thoughtbot-shoulda 2.9.1 → 2.9.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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 +43 -24
  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
data/lib/shoulda/rails.rb CHANGED
@@ -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
data/lib/shoulda/rspec.rb CHANGED
@@ -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