shoulda 2.9.1 → 2.9.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (54) hide show
  1. data/README.rdoc +27 -5
  2. data/Rakefile +2 -2
  3. data/lib/shoulda.rb +1 -1
  4. data/lib/shoulda/{controller.rb → action_controller.rb} +6 -8
  5. data/lib/shoulda/{controller → action_controller}/helpers.rb +1 -16
  6. data/lib/shoulda/action_controller/macros.rb +277 -0
  7. data/lib/shoulda/action_controller/matchers.rb +37 -0
  8. data/lib/shoulda/action_controller/matchers/assign_to_matcher.rb +109 -0
  9. data/lib/shoulda/action_controller/matchers/filter_param_matcher.rb +57 -0
  10. data/lib/shoulda/action_controller/matchers/render_with_layout_matcher.rb +81 -0
  11. data/lib/shoulda/action_controller/matchers/respond_with_content_type_matcher.rb +70 -0
  12. data/lib/shoulda/action_controller/matchers/respond_with_matcher.rb +81 -0
  13. data/lib/shoulda/action_controller/matchers/route_matcher.rb +93 -0
  14. data/lib/shoulda/action_controller/matchers/set_session_matcher.rb +83 -0
  15. data/lib/shoulda/action_controller/matchers/set_the_flash_matcher.rb +85 -0
  16. data/lib/shoulda/action_view.rb +10 -0
  17. data/lib/shoulda/action_view/macros.rb +56 -0
  18. data/lib/shoulda/active_record/macros.rb +8 -13
  19. data/lib/shoulda/active_record/matchers/validate_uniqueness_of_matcher.rb +1 -1
  20. data/lib/shoulda/rails.rb +4 -3
  21. data/lib/shoulda/rspec.rb +7 -5
  22. data/test/functional/posts_controller_test.rb +28 -22
  23. data/test/functional/users_controller_test.rb +0 -19
  24. data/test/matchers/{allow_mass_assignment_of_matcher_test.rb → active_record/allow_mass_assignment_of_matcher_test.rb} +1 -1
  25. data/test/matchers/{allow_value_matcher_test.rb → active_record/allow_value_matcher_test.rb} +1 -1
  26. data/test/matchers/{association_matcher_test.rb → active_record/association_matcher_test.rb} +1 -1
  27. data/test/matchers/{ensure_inclusion_of_matcher_test.rb → active_record/ensure_inclusion_of_matcher_test.rb} +1 -1
  28. data/test/matchers/{ensure_length_of_matcher_test.rb → active_record/ensure_length_of_matcher_test.rb} +1 -1
  29. data/test/matchers/{have_db_column_matcher_test.rb → active_record/have_db_column_matcher_test.rb} +1 -1
  30. data/test/matchers/{have_index_matcher_test.rb → active_record/have_index_matcher_test.rb} +1 -1
  31. data/test/matchers/{have_named_scope_matcher_test.rb → active_record/have_named_scope_matcher_test.rb} +1 -1
  32. data/test/matchers/{have_readonly_attributes_matcher_test.rb → active_record/have_readonly_attributes_matcher_test.rb} +1 -1
  33. data/test/matchers/{validate_acceptance_of_matcher_test.rb → active_record/validate_acceptance_of_matcher_test.rb} +1 -1
  34. data/test/matchers/{validate_numericality_of_matcher_test.rb → active_record/validate_numericality_of_matcher_test.rb} +1 -1
  35. data/test/matchers/{validate_presence_of_matcher_test.rb → active_record/validate_presence_of_matcher_test.rb} +1 -1
  36. data/test/matchers/{validate_uniqueness_of_matcher_test.rb → active_record/validate_uniqueness_of_matcher_test.rb} +8 -2
  37. data/test/matchers/controller/assign_to_matcher_test.rb +35 -0
  38. data/test/matchers/controller/filter_param_matcher_test.rb +32 -0
  39. data/test/matchers/controller/render_with_layout_matcher_test.rb +33 -0
  40. data/test/matchers/controller/respond_with_content_type_matcher_test.rb +27 -0
  41. data/test/matchers/controller/respond_with_matcher_test.rb +106 -0
  42. data/test/matchers/controller/route_matcher_test.rb +58 -0
  43. data/test/matchers/controller/set_session_matcher_test.rb +27 -0
  44. data/test/matchers/controller/set_the_flash_matcher.rb +41 -0
  45. data/test/model_builder.rb +47 -2
  46. data/test/rails_root/app/models/user.rb +2 -1
  47. data/test/rails_root/config/environment.rb +1 -1
  48. data/test/rspec_test.rb +207 -0
  49. data/test/unit/user_test.rb +10 -1
  50. metadata +38 -22
  51. data/lib/shoulda/controller/formats/html.rb +0 -199
  52. data/lib/shoulda/controller/formats/xml.rb +0 -168
  53. data/lib/shoulda/controller/macros.rb +0 -336
  54. data/lib/shoulda/controller/resource_options.rb +0 -233
@@ -0,0 +1,83 @@
1
+ module Shoulda # :nodoc:
2
+ module ActionController # :nodoc:
3
+ module Matchers
4
+
5
+ # Ensures that a session key was set to the expected value.
6
+ #
7
+ # Example:
8
+ #
9
+ # it { should set_session(:message) }
10
+ # it { should set_session(:user_id).to(@user.id) }
11
+ # it { should_not set_session(:user_id) }
12
+ def set_session(key)
13
+ SetSessionMatcher.new(key)
14
+ end
15
+
16
+ class SetSessionMatcher # :nodoc:
17
+
18
+ def initialize(key)
19
+ @key = key.to_s
20
+ end
21
+
22
+ def to(value)
23
+ @value = value
24
+ self
25
+ end
26
+
27
+ def matches?(controller)
28
+ @controller = controller
29
+ assigned_value? && assigned_correct_value?
30
+ end
31
+
32
+ def failure_message
33
+ "Expected #{expectation}, but #{result}"
34
+ end
35
+
36
+ def negative_failure_message
37
+ "Didn't expect #{expectation}, but #{result}"
38
+ end
39
+
40
+ def description
41
+ description = "set session variable #{@key.inspect}"
42
+ description << " to #{@value.inspect}" if @value
43
+ description
44
+ end
45
+
46
+ private
47
+
48
+ def assigned_value?
49
+ !assigned_value.blank?
50
+ end
51
+
52
+ def assigned_correct_value?
53
+ return true if @value.nil?
54
+ assigned_value == @value
55
+ end
56
+
57
+ def assigned_value
58
+ session[@key]
59
+ end
60
+
61
+ def session
62
+ @controller.response.session.data
63
+ end
64
+
65
+ def expectation
66
+ expectation = "session variable #{@key} to be set"
67
+ expectation << " to #{@value.inspect}" if @value
68
+ expectation
69
+ end
70
+
71
+ def result
72
+ if session.empty?
73
+ "no session variables were set"
74
+ else
75
+ "the session was #{session.inspect}"
76
+ end
77
+ end
78
+
79
+ end
80
+
81
+ end
82
+ end
83
+ end
@@ -0,0 +1,85 @@
1
+ module Shoulda # :nodoc:
2
+ module ActionController # :nodoc:
3
+ module Matchers
4
+
5
+ # Ensures that the flash contains the given value. Can be a String, a
6
+ # Regexp, or nil (indicating that the flash should not be set).
7
+ #
8
+ # Example:
9
+ #
10
+ # it { should set_the_flash }
11
+ # it { should set_the_flash.to("Thank you for placing this order.") }
12
+ # it { should set_the_flash.to(/created/i) }
13
+ # it { should_not set_the_flash }
14
+ def set_the_flash
15
+ SetTheFlashMatcher.new
16
+ end
17
+
18
+ class SetTheFlashMatcher # :nodoc:
19
+
20
+ def to(value)
21
+ @value = value
22
+ self
23
+ end
24
+
25
+ def matches?(controller)
26
+ @controller = controller
27
+ sets_the_flash? && string_value_matches? && regexp_value_matches?
28
+ end
29
+
30
+ attr_reader :failure_message, :negative_failure_message
31
+
32
+ def description
33
+ description = "set the flash"
34
+ description << " to #{@value.inspect}" unless @value.nil?
35
+ description
36
+ end
37
+
38
+ def failure_message
39
+ "Expected #{expectation}"
40
+ end
41
+
42
+ def negative_failure_message
43
+ "Did not expect #{expectation}"
44
+ end
45
+
46
+ private
47
+
48
+ def sets_the_flash?
49
+ !flash.blank?
50
+ end
51
+
52
+ def string_value_matches?
53
+ return true unless String === @value
54
+ flash.values.any? {|value| value == @value }
55
+ end
56
+
57
+ def regexp_value_matches?
58
+ return true unless Regexp === @value
59
+ flash.values.any? {|value| value =~ @value }
60
+ end
61
+
62
+ def flash
63
+ @controller.response.session['flash']
64
+ end
65
+
66
+ def expectation
67
+ expectation = "the flash to be set"
68
+ expectation << " to #{@value.inspect}" unless @value.nil?
69
+ expectation << ", but #{flash_description}"
70
+ expectation
71
+ end
72
+
73
+ def flash_description
74
+ if flash.blank?
75
+ "no flash was set"
76
+ else
77
+ "was #{flash.inspect}"
78
+ end
79
+ end
80
+
81
+ end
82
+
83
+ end
84
+ end
85
+ end
@@ -0,0 +1,10 @@
1
+ require 'shoulda'
2
+ require 'shoulda/action_view/macros'
3
+
4
+ module Test # :nodoc: all
5
+ module Unit
6
+ class TestCase
7
+ extend Shoulda::ActionView::Macros
8
+ end
9
+ end
10
+ end
@@ -0,0 +1,56 @@
1
+ module Shoulda # :nodoc:
2
+ module ActionView # :nodoc:
3
+ # = Macro test helpers for your view
4
+ #
5
+ # By using the macro helpers you can quickly and easily create concise and
6
+ # easy to read test suites.
7
+ #
8
+ # This code segment:
9
+ # context "on GET to :new" do
10
+ # setup do
11
+ # get :new
12
+ # end
13
+ #
14
+ # should_render_a_form
15
+ # should_render_page_with_metadata :title => /index/
16
+ #
17
+ # should "do something else really cool" do
18
+ # assert_select '#really_cool'
19
+ # end
20
+ # end
21
+ #
22
+ # Would produce 3 tests for the +show+ action
23
+ module Macros
24
+
25
+ # Macro that creates a test asserting that the rendered view contains a <form> element.
26
+ def should_render_a_form
27
+ should "display a form" do
28
+ assert_select "form", true, "The template doesn't contain a <form> element"
29
+ end
30
+ end
31
+
32
+ # Macro that creates a test asserting that the rendered view contains the selected metatags.
33
+ # Values can be string or Regexps.
34
+ # Example:
35
+ #
36
+ # should_render_page_with_metadata :description => "Description of this page", :keywords => /post/
37
+ #
38
+ # You can also use this method to test the rendered views title.
39
+ #
40
+ # Example:
41
+ # should_render_page_with_metadata :title => /index/
42
+ def should_render_page_with_metadata(options)
43
+ options.each do |key, value|
44
+ should "have metatag #{key}" do
45
+ if key.to_sym == :title
46
+ assert_select "title", value
47
+ else
48
+ assert_select "meta[name=?][content#{"*" if value.is_a?(Regexp)}=?]", key, value
49
+ end
50
+ end
51
+ end
52
+ end
53
+ end
54
+ end
55
+ end
56
+
@@ -23,14 +23,6 @@ module Shoulda # :nodoc:
23
23
  include Helpers
24
24
  include Matchers
25
25
 
26
- # <b>DEPRECATED:</b> Use <tt>fixtures :all</tt> instead
27
- #
28
- # Loads all fixture files (<tt>test/fixtures/*.yml</tt>)
29
- def load_all_fixtures
30
- warn "[DEPRECATION] load_all_fixtures is deprecated. Use `fixtures :all` instead."
31
- fixtures :all
32
- end
33
-
34
26
  # Ensures that the model cannot be saved if one of the attributes listed is not present.
35
27
  #
36
28
  # If an instance variable has been created in the setup named after the
@@ -304,13 +296,16 @@ module Shoulda # :nodoc:
304
296
  # should_ensure_value_in_range :age, (0..100)
305
297
  #
306
298
  def should_ensure_value_in_range(attribute, range, opts = {})
307
- message = get_options!([opts], :message)
308
- message ||= default_error_message(:inclusion)
309
-
299
+ message, low_message, high_message = get_options!([opts],
300
+ :message,
301
+ :low_message,
302
+ :high_message)
310
303
  klass = model_class
311
304
  matcher = ensure_inclusion_of(attribute).
312
305
  in_range(range).
313
- with_message(message)
306
+ with_message(message).
307
+ with_low_message(low_message).
308
+ with_high_message(high_message)
314
309
  should matcher.description do
315
310
  assert_accepts matcher, get_instance_of(klass)
316
311
  end
@@ -341,7 +336,7 @@ module Shoulda # :nodoc:
341
336
  end
342
337
  end
343
338
 
344
- # Deprecated. See should_validate_uniqueness_of
339
+ # Deprecated. See should_validate_numericality_of
345
340
  def should_only_allow_numeric_values_for(*attributes)
346
341
  warn "[DEPRECATION] should_only_allow_numeric_values_for is " <<
347
342
  "deprecated. Use should_validate_numericality_of instead."
@@ -77,9 +77,9 @@ module Shoulda # :nodoc:
77
77
 
78
78
  def find_existing
79
79
  if @existing = @subject.class.find(:first)
80
- @failure_message = "Can't find first #{class_name}"
81
80
  true
82
81
  else
82
+ @failure_message = "Can't find first #{class_name}"
83
83
  false
84
84
  end
85
85
  end
@@ -2,9 +2,10 @@ require 'rubygems'
2
2
  require 'active_support'
3
3
  require 'shoulda'
4
4
 
5
- require 'shoulda/active_record' if defined? ActiveRecord::Base
6
- require 'shoulda/controller' if defined? ActionController::Base
7
- require 'shoulda/action_mailer' if defined? ActionMailer::Base
5
+ require 'shoulda/active_record' if defined? ActiveRecord::Base
6
+ require 'shoulda/action_controller' if defined? ActionController::Base
7
+ require 'shoulda/action_view' if defined? ActionView::Base
8
+ require 'shoulda/action_mailer' if defined? ActionMailer::Base
8
9
 
9
10
  if defined?(RAILS_ROOT)
10
11
  # load in the 3rd party macros from vendorized plugins and gems
@@ -1,9 +1,11 @@
1
1
  require 'shoulda/active_record/matchers'
2
+ require 'shoulda/action_controller/matchers'
3
+ require 'active_support/test_case'
2
4
 
3
- module Spec
4
- module Rails
5
- module Matchers
6
- include Shoulda::ActiveRecord::Matchers
7
- end
5
+ # :enddoc:
6
+ module ActiveSupport
7
+ class TestCase
8
+ include Shoulda::ActiveRecord::Matchers
9
+ include Shoulda::ActionController::Matchers
8
10
  end
9
11
  end
@@ -33,44 +33,27 @@ class PostsControllerTest < Test::Unit::TestCase
33
33
  should_route :get, '/users/5/posts/new', :action => :new, :user_id => 5
34
34
  should_route :put, '/users/5/posts/1', :action => :update, :id => 1, :user_id => 5
35
35
 
36
- context "The public" do
37
- setup do
38
- @request.session[:logged_in] = false
39
- end
40
-
41
- should_be_restful do |resource|
42
- resource.parent = :user
43
-
44
- resource.denied.actions = [:index, :show, :edit, :new, :create, :update, :destroy]
45
- resource.denied.flash = /what/i
46
- resource.denied.redirect = '"/"'
47
- end
48
- end
49
-
50
36
  context "Logged in" do
51
37
  setup do
52
38
  @request.session[:logged_in] = true
53
39
  end
54
40
 
55
- should_be_restful do |resource|
56
- resource.parent = :user
57
-
58
- resource.create.params = { :title => "first post", :body => 'blah blah blah'}
59
- resource.update.params = { :title => "changed" }
60
- end
61
-
62
41
  context "viewing posts for a user" do
63
42
  setup do
64
43
  get :index, :user_id => users(:first)
65
44
  end
66
45
  should_respond_with :success
67
46
  should_assign_to :user, :class => User, :equals => 'users(:first)'
47
+ should_assign_to(:user) { users(:first) }
68
48
  should_fail do
69
49
  should_assign_to :user, :class => Post
70
50
  end
71
51
  should_fail do
72
52
  should_assign_to :user, :equals => 'posts(:first)'
73
53
  end
54
+ should_fail do
55
+ should_assign_to(:user) { posts(:first) }
56
+ end
74
57
  should_assign_to :posts
75
58
  should_not_assign_to :foo, :bar
76
59
  should_render_page_with_metadata :description => /Posts/, :title => /index/
@@ -87,7 +70,12 @@ class PostsControllerTest < Test::Unit::TestCase
87
70
  should_respond_with_content_type :rss
88
71
  should_respond_with_content_type /rss/
89
72
  should_return_from_session :special, "'$2 off your next purchase'"
90
- should_return_from_session :special_user_id, '@user.id'
73
+ should_set_session :special, "'$2 off your next purchase'"
74
+ should_set_session :special_user_id, '@user.id'
75
+ should_set_session(:special_user_id) { @user.id }
76
+ should_fail do
77
+ should_set_session(:special_user_id) { 'value' }
78
+ end
91
79
  should_assign_to :user, :posts
92
80
  should_not_assign_to :foo, :bar
93
81
  end
@@ -103,6 +91,24 @@ class PostsControllerTest < Test::Unit::TestCase
103
91
  setup { get :new, :user_id => users(:first) }
104
92
  should_render_without_layout
105
93
  end
94
+
95
+ context "on POST to #create" do
96
+ setup do
97
+ post :create, :user_id => users(:first),
98
+ :post => { :title => "first post",
99
+ :body => 'blah blah blah' }
100
+ end
101
+
102
+ should_redirect_to 'user_post_url(@post.user, @post)'
103
+ should_redirect_to('the created post') { user_post_url(users(:first),
104
+ assigns(:post)) }
105
+ should_fail do
106
+ should_redirect_to 'user_posts_url(@post.user)'
107
+ end
108
+ should_fail do
109
+ should_redirect_to('elsewhere') { user_posts_url(users(:first)) }
110
+ end
111
+ end
106
112
  end
107
113
 
108
114
  end
@@ -16,23 +16,4 @@ class UsersControllerTest < Test::Unit::TestCase
16
16
 
17
17
  should_filter_params :ssn
18
18
 
19
- should_be_restful do |resource|
20
- resource.identifier = :id
21
- resource.klass = User
22
- resource.object = :user
23
- resource.parent = []
24
- resource.actions = [:index, :show, :new, :edit, :update, :create, :destroy]
25
- resource.formats = [:html, :xml]
26
-
27
- resource.create.params = { :name => "bob", :email => 'bob@bob.com', :age => 13, :ssn => "123456789"}
28
- resource.update.params = { :name => "sue" }
29
-
30
- resource.create.redirect = "user_url(@user)"
31
- resource.update.redirect = "user_url(@user)"
32
- resource.destroy.redirect = "users_url"
33
-
34
- resource.create.flash = /created/i
35
- resource.update.flash = /updated/i
36
- resource.destroy.flash = /removed/i
37
- end
38
19
  end
@@ -1,4 +1,4 @@
1
- require File.join(File.dirname(__FILE__), '..', 'test_helper')
1
+ require File.join(File.dirname(__FILE__), '..', '..', 'test_helper')
2
2
 
3
3
  class AllowMassAssignmentOfMatcherTest < Test::Unit::TestCase # :nodoc:
4
4
 
@@ -1,4 +1,4 @@
1
- require File.join(File.dirname(__FILE__), '..', 'test_helper')
1
+ require File.join(File.dirname(__FILE__), '..', '..', 'test_helper')
2
2
 
3
3
  class AllowValueMatcherTest < Test::Unit::TestCase # :nodoc:
4
4