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.
Files changed (121) hide show
  1. data/History.txt +5 -5
  2. data/Manifest.txt +53 -35
  3. data/PostInstall.txt +1 -6
  4. data/README.rdoc +109 -15
  5. data/Rakefile +29 -29
  6. data/lib/remarkable/active_record/README.markdown +378 -0
  7. data/lib/remarkable/active_record/active_record.rb +12 -11
  8. data/lib/remarkable/active_record/helpers.rb +215 -5
  9. data/lib/remarkable/active_record/macros/associations/association_matcher.rb +242 -0
  10. data/lib/remarkable/active_record/macros/callbacks/callback_matcher.rb +46 -0
  11. data/lib/remarkable/active_record/macros/database/column_matcher.rb +122 -0
  12. data/lib/remarkable/active_record/macros/database/index_matcher.rb +103 -0
  13. data/lib/remarkable/active_record/macros/validations/allow_mass_assignment_of_matcher.rb +52 -0
  14. data/lib/remarkable/active_record/macros/validations/ensure_value_in_list_matcher.rb +83 -0
  15. data/lib/remarkable/active_record/macros/validations/ensure_value_in_range_matcher.rb +172 -0
  16. data/lib/remarkable/active_record/macros/validations/have_class_methods_matcher.rb +54 -0
  17. data/lib/remarkable/active_record/macros/validations/have_instance_methods_matcher.rb +54 -0
  18. data/lib/remarkable/active_record/macros/validations/have_named_scope_matcher.rb +94 -0
  19. data/lib/remarkable/active_record/macros/validations/have_readonly_attributes_matcher.rb +48 -0
  20. data/lib/remarkable/active_record/macros/validations/protect_attributes_matcher.rb +51 -0
  21. data/lib/remarkable/active_record/macros/validations/validate_acceptance_of_matcher.rb +79 -0
  22. data/lib/remarkable/active_record/macros/validations/validate_associated_matcher.rb +177 -0
  23. data/lib/remarkable/active_record/macros/validations/validate_confirmation_of_matcher.rb +74 -0
  24. data/lib/remarkable/active_record/macros/validations/validate_exclusion_of_matcher.rb +38 -0
  25. data/lib/remarkable/active_record/macros/validations/validate_format_of_matcher.rb +33 -0
  26. data/lib/remarkable/active_record/macros/validations/validate_inclusion_of_matcher.rb +45 -0
  27. data/lib/remarkable/active_record/macros/validations/validate_length_of_matcher.rb +248 -0
  28. data/lib/remarkable/active_record/macros/validations/validate_numericality_of_matcher.rb +206 -0
  29. data/lib/remarkable/active_record/macros/validations/validate_presence_of_matcher.rb +72 -0
  30. data/lib/remarkable/active_record/macros/validations/validate_uniqueness_of_matcher.rb +222 -0
  31. data/lib/remarkable/active_record/macros.rb +52 -0
  32. data/lib/remarkable/assertions.rb +29 -0
  33. data/lib/remarkable/controller/README.markdown +147 -0
  34. data/lib/remarkable/controller/controller.rb +11 -6
  35. data/lib/remarkable/controller/helpers.rb +4 -38
  36. data/lib/remarkable/controller/macros/assign_matcher.rb +85 -0
  37. data/lib/remarkable/controller/macros/filter_params_matcher.rb +63 -0
  38. data/lib/remarkable/controller/macros/metadata_matcher.rb +63 -0
  39. data/lib/remarkable/controller/macros/render_with_layout_matcher.rb +75 -0
  40. data/lib/remarkable/controller/macros/respond_with_content_type_matcher.rb +60 -0
  41. data/lib/remarkable/controller/macros/respond_with_matcher.rb +62 -0
  42. data/lib/remarkable/controller/macros/return_from_session_matcher.rb +58 -0
  43. data/lib/remarkable/controller/macros/route_matcher.rb +75 -0
  44. data/lib/remarkable/controller/macros/set_the_flash_to_matcher.rb +60 -0
  45. data/lib/remarkable/controller/macros.rb +78 -0
  46. data/lib/remarkable/dsl.rb +239 -0
  47. data/lib/remarkable/example/example_methods.rb +27 -7
  48. data/lib/remarkable/helpers.rb +28 -0
  49. data/lib/remarkable/matcher_base.rb +64 -0
  50. data/lib/remarkable/private_helpers.rb +10 -115
  51. data/lib/remarkable/rails.rb +27 -0
  52. data/lib/remarkable.rb +13 -5
  53. data/remarkable.gemspec +43 -0
  54. data/spec/controllers/posts_controller_spec.rb +58 -4
  55. data/spec/controllers/users_controller_spec.rb +1 -0
  56. data/spec/fixtures/fleas.yml +10 -0
  57. data/spec/fixtures/users.yml +7 -0
  58. data/spec/models/address_spec.rb +44 -0
  59. data/spec/models/dog_spec.rb +64 -3
  60. data/spec/models/flea_spec.rb +30 -0
  61. data/spec/models/post_spec.rb +36 -2
  62. data/spec/models/product_spec.rb +73 -8
  63. data/spec/models/tag_spec.rb +2 -2
  64. data/spec/models/tagging_spec.rb +24 -0
  65. data/spec/models/user_spec.rb +206 -21
  66. data/spec/other/custom_macros_spec.rb +27 -0
  67. data/spec/other/my_own_matcher_spec.rb +11 -0
  68. data/spec/other/private_helpers_spec.rb +31 -0
  69. data/spec/rails_root/app/controllers/posts_controller.rb +2 -0
  70. data/spec/rails_root/app/models/address.rb +2 -2
  71. data/spec/rails_root/app/models/flea.rb +4 -0
  72. data/spec/rails_root/app/models/pets/dog.rb +12 -0
  73. data/spec/rails_root/app/models/product.rb +7 -5
  74. data/spec/rails_root/app/models/tagging.rb +2 -0
  75. data/spec/rails_root/app/models/user.rb +20 -5
  76. data/spec/rails_root/app/views/layouts/posts.rhtml +8 -6
  77. data/spec/rails_root/config/database.yml +1 -2
  78. data/spec/rails_root/config/environment.rb +3 -1
  79. data/spec/rails_root/config/environments/{sqlite3.rb → test.rb} +0 -0
  80. data/spec/rails_root/config/locales/en.yml +8 -0
  81. data/spec/rails_root/db/migrate/001_create_users.rb +2 -2
  82. data/spec/rails_root/db/migrate/005_create_dogs.rb +1 -0
  83. data/spec/rails_root/db/migrate/011_add_fleas_color.rb +10 -0
  84. data/spec/rails_root/db/migrate/012_add_fleas_address.rb +10 -0
  85. data/spec/rails_root/spec/remarkable_macros/.keep +0 -0
  86. data/spec/rails_root/vendor/plugins/my_plugin/remarkable_macros/.keep +0 -0
  87. data/spec/spec_helper.rb +0 -2
  88. metadata +63 -43
  89. data/lib/remarkable/active_record/macros/associations/belong_to.rb +0 -81
  90. data/lib/remarkable/active_record/macros/associations/have_and_belong_to_many.rb +0 -77
  91. data/lib/remarkable/active_record/macros/associations/have_many.rb +0 -160
  92. data/lib/remarkable/active_record/macros/associations/have_one.rb +0 -133
  93. data/lib/remarkable/active_record/macros/database/have_db_column.rb +0 -81
  94. data/lib/remarkable/active_record/macros/database/have_db_columns.rb +0 -73
  95. data/lib/remarkable/active_record/macros/database/have_indices.rb +0 -75
  96. data/lib/remarkable/active_record/macros/validations/allow_values_for.rb +0 -103
  97. data/lib/remarkable/active_record/macros/validations/ensure_length_at_least.rb +0 -97
  98. data/lib/remarkable/active_record/macros/validations/ensure_length_in_range.rb +0 -134
  99. data/lib/remarkable/active_record/macros/validations/ensure_length_is.rb +0 -106
  100. data/lib/remarkable/active_record/macros/validations/ensure_value_in_range.rb +0 -117
  101. data/lib/remarkable/active_record/macros/validations/have_class_methods.rb +0 -74
  102. data/lib/remarkable/active_record/macros/validations/have_instance_methods.rb +0 -74
  103. data/lib/remarkable/active_record/macros/validations/have_named_scope.rb +0 -148
  104. data/lib/remarkable/active_record/macros/validations/have_readonly_attributes.rb +0 -81
  105. data/lib/remarkable/active_record/macros/validations/only_allow_numeric_values_for.rb +0 -89
  106. data/lib/remarkable/active_record/macros/validations/protect_attributes.rb +0 -89
  107. data/lib/remarkable/active_record/macros/validations/require_acceptance_of.rb +0 -94
  108. data/lib/remarkable/active_record/macros/validations/require_attributes.rb +0 -94
  109. data/lib/remarkable/active_record/macros/validations/require_unique_attributes.rb +0 -146
  110. data/lib/remarkable/controller/macros/assign_to.rb +0 -110
  111. data/lib/remarkable/controller/macros/filter_params.rb +0 -52
  112. data/lib/remarkable/controller/macros/redirect_to.rb +0 -24
  113. data/lib/remarkable/controller/macros/render_a_form.rb +0 -23
  114. data/lib/remarkable/controller/macros/render_template.rb +0 -18
  115. data/lib/remarkable/controller/macros/render_with_layout.rb +0 -61
  116. data/lib/remarkable/controller/macros/respond_with.rb +0 -86
  117. data/lib/remarkable/controller/macros/respond_with_content_type.rb +0 -45
  118. data/lib/remarkable/controller/macros/return_from_session.rb +0 -45
  119. data/lib/remarkable/controller/macros/route.rb +0 -91
  120. data/lib/remarkable/controller/macros/set_the_flash_to.rb +0 -58
  121. 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", '*')].each do |file|
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 Matchers
9
- include Remarkable::Controller::Helpers
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
- SPECIAL_INSTANCE_VARIABLES = %w{
7
- _cookies
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