shoulda-matchers 2.5.0 → 2.6.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (121) hide show
  1. data/.gitignore +8 -7
  2. data/.travis.yml +4 -0
  3. data/Appraisals +8 -0
  4. data/CONTRIBUTING.md +1 -1
  5. data/Gemfile +1 -1
  6. data/Gemfile.lock +77 -66
  7. data/MIT-LICENSE +1 -1
  8. data/NEWS.md +63 -1
  9. data/README.md +189 -33
  10. data/Rakefile +6 -5
  11. data/features/rails_integration.feature +1 -1
  12. data/features/step_definitions/rails_steps.rb +7 -6
  13. data/gemfiles/3.0.gemfile +2 -2
  14. data/gemfiles/3.0.gemfile.lock +14 -5
  15. data/gemfiles/3.1.gemfile +2 -2
  16. data/gemfiles/3.1.gemfile.lock +14 -5
  17. data/gemfiles/3.2.gemfile +2 -2
  18. data/gemfiles/3.2.gemfile.lock +16 -7
  19. data/gemfiles/4.0.0.gemfile +2 -2
  20. data/gemfiles/4.0.0.gemfile.lock +15 -6
  21. data/gemfiles/4.0.1.gemfile +2 -2
  22. data/gemfiles/4.0.1.gemfile.lock +15 -6
  23. data/gemfiles/4.1.gemfile +19 -0
  24. data/gemfiles/4.1.gemfile.lock +176 -0
  25. data/lib/shoulda/matchers.rb +17 -1
  26. data/lib/shoulda/matchers/action_controller.rb +4 -2
  27. data/lib/shoulda/matchers/action_controller/callback_matcher.rb +100 -0
  28. data/lib/shoulda/matchers/action_controller/redirect_to_matcher.rb +1 -1
  29. data/lib/shoulda/matchers/action_controller/render_template_matcher.rb +4 -4
  30. data/lib/shoulda/matchers/action_controller/rescue_from_matcher.rb +1 -1
  31. data/lib/shoulda/matchers/action_controller/route_matcher.rb +12 -12
  32. data/lib/shoulda/matchers/action_controller/route_params.rb +1 -1
  33. data/lib/shoulda/matchers/action_controller/set_the_flash_matcher.rb +2 -1
  34. data/lib/shoulda/matchers/action_controller/strong_parameters_matcher.rb +167 -0
  35. data/lib/shoulda/matchers/active_model.rb +4 -2
  36. data/lib/shoulda/matchers/active_model/allow_value_matcher.rb +23 -5
  37. data/lib/shoulda/matchers/active_model/disallow_value_matcher.rb +0 -4
  38. data/lib/shoulda/matchers/active_model/ensure_inclusion_of_matcher.rb +66 -14
  39. data/lib/shoulda/matchers/active_model/ensure_length_of_matcher.rb +8 -8
  40. data/lib/shoulda/matchers/active_model/errors.rb +40 -0
  41. data/lib/shoulda/matchers/active_model/helpers.rb +6 -6
  42. data/lib/shoulda/matchers/active_model/numericality_matchers/comparison_matcher.rb +33 -14
  43. data/lib/shoulda/matchers/active_model/numericality_matchers/even_number_matcher.rb +26 -0
  44. data/lib/shoulda/matchers/active_model/numericality_matchers/{odd_even_number_matcher.rb → numeric_type_matcher.rb} +9 -20
  45. data/lib/shoulda/matchers/active_model/numericality_matchers/odd_number_matcher.rb +26 -0
  46. data/lib/shoulda/matchers/active_model/numericality_matchers/only_integer_matcher.rb +5 -21
  47. data/lib/shoulda/matchers/active_model/validate_confirmation_of_matcher.rb +1 -1
  48. data/lib/shoulda/matchers/active_model/validate_numericality_of_matcher.rb +71 -22
  49. data/lib/shoulda/matchers/active_model/validate_presence_of_matcher.rb +6 -1
  50. data/lib/shoulda/matchers/active_model/validate_uniqueness_of_matcher.rb +25 -6
  51. data/lib/shoulda/matchers/active_record.rb +1 -0
  52. data/lib/shoulda/matchers/active_record/association_matcher.rb +67 -13
  53. data/lib/shoulda/matchers/active_record/association_matchers/inverse_of_matcher.rb +40 -0
  54. data/lib/shoulda/matchers/active_record/association_matchers/model_reflection.rb +24 -1
  55. data/lib/shoulda/matchers/active_record/association_matchers/model_reflector.rb +1 -1
  56. data/lib/shoulda/matchers/active_record/have_db_column_matcher.rb +1 -1
  57. data/lib/shoulda/matchers/active_record/have_db_index_matcher.rb +1 -1
  58. data/lib/shoulda/matchers/assertion_error.rb +7 -2
  59. data/lib/shoulda/matchers/error.rb +24 -0
  60. data/lib/shoulda/matchers/independent.rb +10 -0
  61. data/lib/shoulda/matchers/independent/delegate_matcher.rb +157 -0
  62. data/lib/shoulda/matchers/independent/delegate_matcher/stubbed_target.rb +34 -0
  63. data/lib/shoulda/matchers/integrations/nunit_test_case_detection.rb +36 -0
  64. data/lib/shoulda/matchers/integrations/rspec.rb +13 -14
  65. data/lib/shoulda/matchers/integrations/test_unit.rb +11 -9
  66. data/lib/shoulda/matchers/version.rb +1 -1
  67. data/lib/shoulda/matchers/warn.rb +7 -0
  68. data/shoulda-matchers.gemspec +2 -1
  69. data/spec/shoulda/matchers/action_controller/callback_matcher_spec.rb +79 -0
  70. data/spec/shoulda/matchers/action_controller/filter_param_matcher_spec.rb +3 -3
  71. data/spec/shoulda/matchers/action_controller/redirect_to_matcher_spec.rb +11 -11
  72. data/spec/shoulda/matchers/action_controller/render_template_matcher_spec.rb +21 -21
  73. data/spec/shoulda/matchers/action_controller/render_with_layout_matcher_spec.rb +10 -10
  74. data/spec/shoulda/matchers/action_controller/rescue_from_matcher_spec.rb +45 -18
  75. data/spec/shoulda/matchers/action_controller/respond_with_matcher_spec.rb +8 -8
  76. data/spec/shoulda/matchers/action_controller/route_matcher_spec.rb +19 -19
  77. data/spec/shoulda/matchers/action_controller/route_params_spec.rb +6 -6
  78. data/spec/shoulda/matchers/action_controller/set_session_matcher_spec.rb +11 -11
  79. data/spec/shoulda/matchers/action_controller/set_the_flash_matcher_spec.rb +44 -44
  80. data/spec/shoulda/matchers/action_controller/strong_parameters_matcher_spec.rb +205 -0
  81. data/spec/shoulda/matchers/active_model/allow_mass_assignment_of_matcher_spec.rb +24 -24
  82. data/spec/shoulda/matchers/active_model/allow_value_matcher_spec.rb +37 -37
  83. data/spec/shoulda/matchers/active_model/disallow_value_matcher_spec.rb +17 -21
  84. data/spec/shoulda/matchers/active_model/ensure_exclusion_of_matcher_spec.rb +24 -24
  85. data/spec/shoulda/matchers/active_model/ensure_inclusion_of_matcher_spec.rb +173 -67
  86. data/spec/shoulda/matchers/active_model/ensure_length_of_matcher_spec.rb +40 -40
  87. data/spec/shoulda/matchers/active_model/exception_message_finder_spec.rb +20 -20
  88. data/spec/shoulda/matchers/active_model/helpers_spec.rb +27 -25
  89. data/spec/shoulda/matchers/active_model/numericality_matchers/comparison_matcher_spec.rb +126 -13
  90. data/spec/shoulda/matchers/active_model/numericality_matchers/even_number_matcher_spec.rb +59 -0
  91. data/spec/shoulda/matchers/active_model/numericality_matchers/odd_number_matcher_spec.rb +59 -0
  92. data/spec/shoulda/matchers/active_model/numericality_matchers/only_integer_matcher_spec.rb +27 -26
  93. data/spec/shoulda/matchers/active_model/validate_absence_of_matcher_spec.rb +15 -15
  94. data/spec/shoulda/matchers/active_model/validate_acceptance_of_matcher_spec.rb +8 -8
  95. data/spec/shoulda/matchers/active_model/validate_confirmation_of_matcher_spec.rb +9 -9
  96. data/spec/shoulda/matchers/active_model/validate_numericality_of_matcher_spec.rb +229 -44
  97. data/spec/shoulda/matchers/active_model/validate_presence_of_matcher_spec.rb +44 -25
  98. data/spec/shoulda/matchers/active_model/validate_uniqueness_of_matcher_spec.rb +110 -62
  99. data/spec/shoulda/matchers/active_model/validation_message_finder_spec.rb +19 -19
  100. data/spec/shoulda/matchers/active_record/accept_nested_attributes_for_matcher_spec.rb +30 -30
  101. data/spec/shoulda/matchers/active_record/association_matcher_spec.rb +378 -192
  102. data/spec/shoulda/matchers/active_record/association_matchers/model_reflection_spec.rb +4 -0
  103. data/spec/shoulda/matchers/active_record/have_db_column_matcher_spec.rb +33 -33
  104. data/spec/shoulda/matchers/active_record/have_db_index_matcher_spec.rb +21 -17
  105. data/spec/shoulda/matchers/active_record/have_readonly_attributes_matcher_spec.rb +8 -8
  106. data/spec/shoulda/matchers/active_record/serialize_matcher_spec.rb +14 -14
  107. data/spec/shoulda/matchers/independent/delegate_matcher/stubbed_target_spec.rb +43 -0
  108. data/spec/shoulda/matchers/independent/delegate_matcher_spec.rb +184 -0
  109. data/spec/spec_helper.rb +4 -0
  110. data/spec/support/activemodel_helpers.rb +2 -2
  111. data/spec/support/capture_helpers.rb +19 -0
  112. data/spec/support/controller_builder.rb +22 -3
  113. data/spec/support/fail_with_message_including_matcher.rb +33 -0
  114. data/spec/support/model_builder.rb +1 -1
  115. data/spec/support/shared_examples/numerical_submatcher.rb +19 -0
  116. data/spec/support/shared_examples/numerical_type_submatcher.rb +17 -0
  117. data/spec/support/test_application.rb +23 -0
  118. metadata +90 -22
  119. checksums.yaml +0 -7
  120. data/spec/shoulda/matchers/active_model/numericality_matchers/odd_even_number_matcher_spec.rb +0 -97
  121. data/spec/support/shared_examples/numerical_submatcher_spec.rb +0 -23
@@ -57,6 +57,10 @@ describe Shoulda::Matchers::ActiveRecord::AssociationMatchers::ModelReflection d
57
57
  describe '#join_table' do
58
58
  context 'when the association was defined with a :join_table option' do
59
59
  it 'returns the value of the option' do
60
+ create_table :foos, id: false do |t|
61
+ t.integer :person_id
62
+ t.integer :country_id
63
+ end
60
64
  define_model(:person, country_id: :integer)
61
65
  country_model = define_model(:country) do
62
66
  has_and_belongs_to_many :people, join_table: 'foos'
@@ -2,99 +2,99 @@ require 'spec_helper'
2
2
 
3
3
  describe Shoulda::Matchers::ActiveRecord::HaveDbColumnMatcher do
4
4
  it 'accepts an existing database column' do
5
- model(:nickname => :string).should have_db_column(:nickname)
5
+ expect(model(nickname: :string)).to have_db_column(:nickname)
6
6
  end
7
7
 
8
8
  it 'rejects a nonexistent database column' do
9
- define_model(:employee).new.should_not have_db_column(:nickname)
9
+ expect(define_model(:employee).new).not_to have_db_column(:nickname)
10
10
  end
11
11
 
12
12
  context '#of_type' do
13
13
  it 'accepts a column of correct type' do
14
- model(:nickname => :string).
15
- should have_db_column(:nickname).of_type(:string)
14
+ expect(model(nickname: :string)).
15
+ to have_db_column(:nickname).of_type(:string)
16
16
  end
17
17
 
18
18
  it 'rejects a nonexistent database column' do
19
- define_model(:superhero).new.
20
- should_not have_db_column(:nickname).of_type(:string)
19
+ expect(define_model(:superhero).new).
20
+ not_to have_db_column(:nickname).of_type(:string)
21
21
  end
22
22
 
23
23
  it 'rejects a column of wrong type' do
24
- model(:nickname => :integer).
25
- should_not have_db_column(:nickname).of_type(:string)
24
+ expect(model(nickname: :integer)).
25
+ not_to have_db_column(:nickname).of_type(:string)
26
26
  end
27
27
  end
28
28
 
29
29
  context 'with precision option' do
30
30
  it 'accepts a column of correct precision' do
31
- with_table(:salary, :decimal, :precision => 5).
32
- should have_db_column(:salary).with_options(:precision => 5)
31
+ expect(with_table(:salary, :decimal, precision: 5)).
32
+ to have_db_column(:salary).with_options(precision: 5)
33
33
  end
34
34
 
35
35
  it 'rejects a column of wrong precision' do
36
- with_table(:salary, :decimal, :precision => 6).
37
- should_not have_db_column(:salary).with_options(:precision => 5)
36
+ expect(with_table(:salary, :decimal, precision: 6)).
37
+ not_to have_db_column(:salary).with_options(precision: 5)
38
38
  end
39
39
  end
40
40
 
41
41
  context 'with limit option' do
42
42
  it 'accepts a column of correct limit' do
43
- with_table(:email, :string, :limit => 255).
44
- should have_db_column(:email).with_options(:limit => 255)
43
+ expect(with_table(:email, :string, limit: 255)).
44
+ to have_db_column(:email).with_options(limit: 255)
45
45
  end
46
46
 
47
47
  it 'rejects a column of wrong limit' do
48
- with_table(:email, :string, :limit => 100).
49
- should_not have_db_column(:email).with_options(:limit => 255)
48
+ expect(with_table(:email, :string, limit: 100)).
49
+ not_to have_db_column(:email).with_options(limit: 255)
50
50
  end
51
51
  end
52
52
 
53
53
  context 'with default option' do
54
54
  it 'accepts a column with correct default' do
55
- with_table(:admin, :boolean, :default => false).
56
- should have_db_column(:admin).with_options(:default => false)
55
+ expect(with_table(:admin, :boolean, default: false)).
56
+ to have_db_column(:admin).with_options(default: false)
57
57
  end
58
58
 
59
59
  it 'rejects a column with wrong default' do
60
- with_table(:admin, :boolean, :default => true).
61
- should_not have_db_column(:admin).with_options(:default => false)
60
+ expect(with_table(:admin, :boolean, default: true)).
61
+ not_to have_db_column(:admin).with_options(default: false)
62
62
  end
63
63
  end
64
64
 
65
65
  context 'with null option' do
66
66
  it 'accepts a column of correct null' do
67
- with_table(:admin, :boolean, :null => false).
68
- should have_db_column(:admin).with_options(:null => false)
67
+ expect(with_table(:admin, :boolean, null: false)).
68
+ to have_db_column(:admin).with_options(null: false)
69
69
  end
70
70
 
71
71
  it 'rejects a column of wrong null' do
72
- with_table(:admin, :boolean, :null => true).
73
- should_not have_db_column(:admin).with_options(:null => false)
72
+ expect(with_table(:admin, :boolean, null: true)).
73
+ not_to have_db_column(:admin).with_options(null: false)
74
74
  end
75
75
  end
76
76
 
77
77
  context 'with scale option' do
78
78
  it 'accepts a column of correct scale' do
79
- with_table(:salary, :decimal, :precision => 10, :scale => 2).
80
- should have_db_column(:salary).with_options(:scale => 2)
79
+ expect(with_table(:salary, :decimal, precision: 10, scale: 2)).
80
+ to have_db_column(:salary).with_options(scale: 2)
81
81
  end
82
82
 
83
83
  it 'rejects a column of wrong scale' do
84
- with_table(:salary, :decimal, :precision => 10, :scale => 4).
85
- should_not have_db_column(:salary).with_options(:scale => 2)
84
+ expect(with_table(:salary, :decimal, precision: 10, scale: 4)).
85
+ not_to have_db_column(:salary).with_options(scale: 2)
86
86
  end
87
87
  end
88
88
 
89
89
  context 'with primary option' do
90
90
  it 'accepts a column that is primary' do
91
- with_table(:custom_id, :integer, :primary => true).
92
- should have_db_column(:id).with_options(:primary => true)
91
+ expect(with_table(:custom_id, :integer, primary: true)).
92
+ to have_db_column(:id).with_options(primary: true)
93
93
  end
94
94
 
95
95
  it 'rejects a column that is not primary' do
96
- with_table(:whatever, :integer, :primary => false).
97
- should_not have_db_column(:whatever).with_options(:primary => true)
96
+ expect(with_table(:whatever, :integer, primary: false)).
97
+ not_to have_db_column(:whatever).with_options(primary: true)
98
98
  end
99
99
  end
100
100
 
@@ -104,7 +104,7 @@ describe Shoulda::Matchers::ActiveRecord::HaveDbColumnMatcher do
104
104
 
105
105
  def with_table(column_name, column_type, options)
106
106
  create_table 'employees' do |table|
107
- table.send(column_type, column_name, options)
107
+ table.__send__(column_type, column_name, options)
108
108
  end
109
109
  define_model_class('Employee').new
110
110
  end
@@ -3,23 +3,23 @@ require 'spec_helper'
3
3
  describe Shoulda::Matchers::ActiveRecord::HaveDbIndexMatcher do
4
4
  context 'have_db_index' do
5
5
  it 'accepts an existing index' do
6
- with_index_on(:age).should have_db_index(:age)
6
+ expect(with_index_on(:age)).to have_db_index(:age)
7
7
  end
8
8
 
9
9
  it 'rejects a nonexistent index' do
10
- define_model(:employee).new.should_not have_db_index(:age)
10
+ expect(define_model(:employee).new).not_to have_db_index(:age)
11
11
  end
12
12
  end
13
13
 
14
14
  context 'have_db_index with unique option' do
15
15
  it 'accepts an index of correct unique' do
16
- with_index_on(:ssn, :unique => true).
17
- should have_db_index(:ssn).unique(true)
16
+ expect(with_index_on(:ssn, unique: true)).
17
+ to have_db_index(:ssn).unique(true)
18
18
  end
19
19
 
20
20
  it 'rejects an index of wrong unique' do
21
- with_index_on(:ssn, :unique => false).
22
- should_not have_db_index(:ssn).unique(true)
21
+ expect(with_index_on(:ssn, unique: false)).
22
+ not_to have_db_index(:ssn).unique(true)
23
23
  end
24
24
  end
25
25
 
@@ -30,8 +30,8 @@ describe Shoulda::Matchers::ActiveRecord::HaveDbIndexMatcher do
30
30
  table.string :geocodable_type
31
31
  end
32
32
  db_connection.add_index :geocodings, [:geocodable_type, :geocodable_id]
33
- define_model_class('Geocoding').new.
34
- should have_db_index([:geocodable_type, :geocodable_id])
33
+ expect(define_model_class('Geocoding').new).
34
+ to have_db_index([:geocodable_type, :geocodable_id])
35
35
  end
36
36
 
37
37
  it 'rejects a nonexistent index' do
@@ -39,34 +39,38 @@ describe Shoulda::Matchers::ActiveRecord::HaveDbIndexMatcher do
39
39
  table.integer :geocodable_id
40
40
  table.string :geocodable_type
41
41
  end
42
- define_model_class('Geocoding').new.
43
- should_not have_db_index([:geocodable_type, :geocodable_id])
42
+ expect(define_model_class('Geocoding').new).
43
+ not_to have_db_index([:geocodable_type, :geocodable_id])
44
44
  end
45
45
  end
46
46
 
47
47
  it 'join columns with and when describing multiple columns' do
48
- have_db_index([:user_id, :post_id]).description.should =~ /on columns user_id and post_id/
48
+ expect(have_db_index([:user_id, :post_id]).description).to match(/on columns user_id and post_id/)
49
49
  end
50
50
 
51
51
  it 'describes a unique index as unique' do
52
- have_db_index(:user_id).unique(true).description.should =~ /a unique index/
52
+ expect(have_db_index(:user_id).unique(true).description).to match(/a unique index/)
53
+ end
54
+
55
+ it 'describes a unique index as unique when no argument is given' do
56
+ expect(have_db_index(:user_id).unique.description).to match(/a unique index/)
53
57
  end
54
58
 
55
59
  it 'describes a non-unique index as non-unique' do
56
- have_db_index(:user_id).unique(false).description.should =~ /a non-unique index/
60
+ expect(have_db_index(:user_id).unique(false).description).to match(/a non-unique index/)
57
61
  end
58
62
 
59
63
  it "does not display an index's uniqueness when it's not important" do
60
- have_db_index(:user_id).description.should_not =~ /unique/
64
+ expect(have_db_index(:user_id).description).not_to match(/unique/)
61
65
  end
62
66
 
63
67
  it 'allows an IndexDefinition to have a truthy value for unique' do
64
68
  index_definition = stub('ActiveRecord::ConnectionAdapters::IndexDefinition',
65
- :unique => 7, :name => :age)
69
+ unique: 7, name: :age)
66
70
  matcher = have_db_index(:age).unique(true)
67
- matcher.stubs(:matched_index => index_definition)
71
+ matcher.stubs(matched_index: index_definition)
68
72
 
69
- with_index_on(:age).should matcher
73
+ expect(with_index_on(:age)).to matcher
70
74
  end
71
75
 
72
76
  def with_index_on(column_name, index_options = {})
@@ -3,38 +3,38 @@ require 'spec_helper'
3
3
  describe Shoulda::Matchers::ActiveRecord::HaveReadonlyAttributeMatcher do
4
4
  context 'a read-only attribute' do
5
5
  it 'accepts' do
6
- with_readonly_attr.should have_readonly_attribute(:attr)
6
+ expect(with_readonly_attr).to have_readonly_attribute(:attr)
7
7
  end
8
8
  end
9
9
 
10
10
  context 'an attribute that is not part of the read-only set' do
11
11
  it 'rejects being read-only' do
12
- model = define_model :example, :attr => :string, :other => :string do
12
+ model = define_model :example, attr: :string, other: :string do
13
13
  attr_readonly :attr
14
14
  end.new
15
15
 
16
- model.should_not have_readonly_attribute(:other)
16
+ expect(model).not_to have_readonly_attribute(:other)
17
17
  end
18
18
  end
19
19
 
20
20
  context 'an attribute on a class with no readonly attributes' do
21
21
  it 'rejects being read-only' do
22
- define_model(:example, :attr => :string).new.
23
- should_not have_readonly_attribute(:attr)
22
+ expect(define_model(:example, attr: :string).new).
23
+ not_to have_readonly_attribute(:attr)
24
24
  end
25
25
 
26
26
  it 'assigns a failure message' do
27
- model = define_model(:example, :attr => :string).new
27
+ model = define_model(:example, attr: :string).new
28
28
  matcher = have_readonly_attribute(:attr)
29
29
 
30
30
  matcher.matches?(model)
31
31
 
32
- matcher.failure_message.should_not be_nil
32
+ expect(matcher.failure_message).not_to be_nil
33
33
  end
34
34
  end
35
35
 
36
36
  def with_readonly_attr
37
- define_model :example, :attr => :string do
37
+ define_model :example, attr: :string do
38
38
  attr_readonly :attr
39
39
  end.new
40
40
  end
@@ -2,12 +2,12 @@ require 'spec_helper'
2
2
 
3
3
  describe Shoulda::Matchers::ActiveRecord::SerializeMatcher do
4
4
  it 'accepts when the attribute is serialized' do
5
- with_serialized_attr.should serialize(:attr)
5
+ expect(with_serialized_attr).to serialize(:attr)
6
6
  end
7
7
 
8
8
  context 'when attribute is not serialized' do
9
9
  it 'rejects' do
10
- unserialized_model.should_not serialize(:attr)
10
+ expect(unserialized_model).not_to serialize(:attr)
11
11
  end
12
12
 
13
13
  it 'assigns a helpful failure message' do
@@ -15,7 +15,7 @@ describe Shoulda::Matchers::ActiveRecord::SerializeMatcher do
15
15
 
16
16
  matcher.matches?(unserialized_model)
17
17
 
18
- matcher.failure_message.should =~ /to serialize the attribute called :attr/
18
+ expect(matcher.failure_message).to match(/to serialize the attribute called :attr/)
19
19
  end
20
20
 
21
21
  it 'assigns a helpful failure message when using #as' do
@@ -23,7 +23,7 @@ describe Shoulda::Matchers::ActiveRecord::SerializeMatcher do
23
23
 
24
24
  matcher.matches?(unserialized_model)
25
25
 
26
- matcher.failure_message.should =~ /with a type of Hash/
26
+ expect(matcher.failure_message).to match(/with a type of Hash/)
27
27
  end
28
28
 
29
29
  it 'assigns a helpful failure message when using #as_instance_of' do
@@ -31,44 +31,44 @@ describe Shoulda::Matchers::ActiveRecord::SerializeMatcher do
31
31
 
32
32
  matcher.matches?(unserialized_model)
33
33
 
34
- matcher.failure_message.should =~ /with an instance of Hash/
34
+ expect(matcher.failure_message).to match(/with an instance of Hash/)
35
35
  end
36
36
 
37
37
  def unserialized_model
38
- @model ||= define_model(:example, :attr => :string).new
38
+ @model ||= define_model(:example, attr: :string).new
39
39
  end
40
40
  end
41
41
 
42
42
  context 'an attribute that is serialized as a specific type' do
43
43
  it 'accepts when the types match' do
44
- with_serialized_attr(Hash).should serialize(:attr).as(Hash)
44
+ expect(with_serialized_attr(Hash)).to serialize(:attr).as(Hash)
45
45
  end
46
46
 
47
47
  it 'rejects when the types do not match' do
48
- with_serialized_attr(Hash).should_not serialize(:attr).as(String)
48
+ expect(with_serialized_attr(Hash)).not_to serialize(:attr).as(String)
49
49
  end
50
50
 
51
51
  it 'rejects when using as_instance_of' do
52
- with_serialized_attr(Hash).should_not serialize(:attr).as_instance_of(Hash)
52
+ expect(with_serialized_attr(Hash)).not_to serialize(:attr).as_instance_of(Hash)
53
53
  end
54
54
  end
55
55
 
56
56
  context 'a serializer that is an instance of a class' do
57
57
  it 'accepts when using #as_instance_of' do
58
58
  define_serializer(:ExampleSerializer)
59
- with_serialized_attr(ExampleSerializer.new).
60
- should serialize(:attr).as_instance_of(ExampleSerializer)
59
+ expect(with_serialized_attr(ExampleSerializer.new)).
60
+ to serialize(:attr).as_instance_of(ExampleSerializer)
61
61
  end
62
62
 
63
63
  it 'rejects when using #as' do
64
64
  define_serializer(:ExampleSerializer)
65
- with_serialized_attr(ExampleSerializer.new).
66
- should_not serialize(:attr).as(ExampleSerializer)
65
+ expect(with_serialized_attr(ExampleSerializer.new)).
66
+ not_to serialize(:attr).as(ExampleSerializer)
67
67
  end
68
68
  end
69
69
 
70
70
  def with_serialized_attr(type = nil)
71
- define_model(:example, :attr => :string) do
71
+ define_model(:example, attr: :string) do
72
72
  if type
73
73
  serialize :attr, type
74
74
  else
@@ -0,0 +1,43 @@
1
+ require 'spec_helper'
2
+
3
+ describe Shoulda::Matchers::Independent::DelegateMatcher::StubbedTarget do
4
+ subject(:target) { described_class.new(:stubbed_method) }
5
+
6
+ describe '#has_received_method?' do
7
+ it 'returns true when the method has been called on the target' do
8
+ target.stubbed_method
9
+
10
+ expect(target).to have_received_method
11
+ end
12
+
13
+ it 'returns false when the method has not been called on the target' do
14
+ expect(target).not_to have_received_method
15
+ end
16
+ end
17
+
18
+ describe '#has_received_arguments?' do
19
+ context 'method is called with specified arguments' do
20
+ it 'returns true' do
21
+ target.stubbed_method(:arg1, :arg2)
22
+
23
+ expect(target).to have_received_arguments(:arg1, :arg2)
24
+ end
25
+ end
26
+
27
+ context 'method is not called with specified arguments' do
28
+ it 'returns false' do
29
+ target.stubbed_method
30
+
31
+ expect(target).not_to have_received_arguments(:arg1)
32
+ end
33
+ end
34
+
35
+ context 'method is called with arguments in incorrect order' do
36
+ it 'returns false' do
37
+ target.stubbed_method(:arg2, :arg1)
38
+
39
+ expect(target).not_to have_received_arguments(:arg1, :arg2)
40
+ end
41
+ end
42
+ end
43
+ end
@@ -0,0 +1,184 @@
1
+ require 'spec_helper'
2
+
3
+ describe Shoulda::Matchers::Independent::DelegateMatcher do
4
+ describe '#description' do
5
+ context 'by default' do
6
+ it 'states that it should delegate method to the right object' do
7
+ matcher = delegate_method(:method_name).to(:target)
8
+
9
+ expect(matcher.description)
10
+ .to eq 'delegate method #method_name to :target'
11
+ end
12
+ end
13
+
14
+ context 'with #as chain' do
15
+ it 'states that it should delegate method to the right object and method' do
16
+ matcher = delegate_method(:method_name).to(:target).as(:alternate)
17
+ message = 'delegate method #method_name to :target as #alternate'
18
+
19
+ expect(matcher.description).to eq message
20
+ end
21
+ end
22
+
23
+ context 'with #with_argument chain' do
24
+ it 'states that it should delegate method to the right object with right argument' do
25
+ matcher = delegate_method(:method_name).to(:target)
26
+ .with_arguments(:foo, bar: [1, 2])
27
+ message = 'delegate method #method_name to :target with arguments: [:foo, {:bar=>[1, 2]}]'
28
+
29
+ expect(matcher.description).to eq message
30
+ end
31
+ end
32
+ end
33
+
34
+ it 'raises an error if no delegation target is defined' do
35
+ expect {
36
+ delegate_method(:name).matches?(Object.new)
37
+ }.to raise_exception described_class::TargetNotDefinedError
38
+ end
39
+
40
+ it 'raises an error if called with #should_not' do
41
+ expect {
42
+ delegate_method(:name).to(:anyone).does_not_match?(Object.new)
43
+ }.to raise_exception described_class::InvalidDelegateMatcher
44
+ end
45
+
46
+ context 'given a method that does not delegate' do
47
+ before do
48
+ define_class(:post_office) do
49
+ def deliver_mail
50
+ :delivered
51
+ end
52
+ end
53
+ end
54
+
55
+ it 'rejects' do
56
+ post_office = PostOffice.new
57
+ matcher = delegate_method(:deliver_mail).to(:mailman)
58
+
59
+ expect(matcher.matches?(post_office)).to be false
60
+ end
61
+
62
+ it 'has a failure message that indicates which method should have been delegated' do
63
+ post_office = PostOffice.new
64
+ message = 'Expected PostOffice#deliver_mail to delegate to PostOffice#mailman'
65
+
66
+ expect {
67
+ expect(post_office).to delegate_method(:deliver_mail).to(:mailman)
68
+ }.to fail_with_message(message)
69
+ end
70
+
71
+ it 'uses the proper syntax for class methods in errors' do
72
+ message = 'Expected PostOffice.deliver_mail to delegate to PostOffice.mailman'
73
+
74
+ expect {
75
+ expect(PostOffice).to delegate_method(:deliver_mail).to(:mailman)
76
+ }.to fail_with_message(message)
77
+ end
78
+ end
79
+
80
+ context 'given a method that delegates properly' do
81
+ it 'accepts' do
82
+ define_class(:mailman)
83
+
84
+ define_class(:post_office) do
85
+ def deliver_mail
86
+ mailman.deliver_mail
87
+ end
88
+
89
+ def mailman
90
+ Mailman.new
91
+ end
92
+ end
93
+
94
+ post_office = PostOffice.new
95
+
96
+ expect(post_office).to delegate_method(:deliver_mail).to(:mailman)
97
+ end
98
+ end
99
+
100
+ context 'given a method that delegates properly with arguments' do
101
+ let(:post_office) { PostOffice.new }
102
+
103
+ before do
104
+ define_class(:mailman)
105
+
106
+ define_class(:post_office) do
107
+ def deliver_mail(*args)
108
+ mailman.deliver_mail('221B Baker St.', hastily: true)
109
+ end
110
+
111
+ def mailman
112
+ Mailman.new
113
+ end
114
+ end
115
+ end
116
+
117
+ context 'when given the correct arguments' do
118
+ it 'accepts' do
119
+ expect(post_office).to delegate_method(:deliver_mail)
120
+ .to(:mailman).with_arguments('221B Baker St.', hastily: true)
121
+ end
122
+ end
123
+
124
+ context 'when not given the correct arguments' do
125
+ it 'rejects' do
126
+ matcher = delegate_method(:deliver_mail).to(:mailman)
127
+ .with_arguments('123 Nowhere Ln.')
128
+
129
+ expect(matcher.matches?(post_office)).to be_false
130
+ end
131
+
132
+ it 'has a failure message that indicates which arguments were expected' do
133
+ message = 'Expected PostOffice#deliver_mail to delegate to PostOffice#mailman with arguments: ["123 Nowhere Ln."]'
134
+
135
+ expect {
136
+ expect(post_office).to delegate_method(:deliver_mail)
137
+ .to(:mailman).with_arguments('123 Nowhere Ln.')
138
+ }.to fail_with_message(message)
139
+ end
140
+ end
141
+ end
142
+
143
+ context 'given a method that delegates properly to a method of a different name' do
144
+ let(:post_office) { PostOffice.new }
145
+
146
+ before do
147
+ define_class(:mailman)
148
+
149
+ define_class(:post_office) do
150
+ def deliver_mail
151
+ mailman.deliver_mail_and_avoid_dogs
152
+ end
153
+
154
+ def mailman
155
+ Mailman.new
156
+ end
157
+ end
158
+ end
159
+
160
+ context 'when given the correct method name' do
161
+ it 'accepts' do
162
+ expect(post_office).to delegate_method(:deliver_mail)
163
+ .to(:mailman).as(:deliver_mail_and_avoid_dogs)
164
+ end
165
+ end
166
+
167
+ context 'when given an incorrect method name' do
168
+ it 'rejects' do
169
+ matcher = delegate_method(:deliver_mail).to(:mailman).as(:watch_tv)
170
+
171
+ expect(matcher.matches?(post_office)).to be_false
172
+ end
173
+
174
+ it 'has a failure message that indicates which method was expected' do
175
+ message = 'Expected PostOffice#deliver_mail to delegate to PostOffice#mailman as #watch_tv'
176
+
177
+ expect {
178
+ expect(post_office).to delegate_method(:deliver_mail)
179
+ .to(:mailman).as(:watch_tv)
180
+ }.to fail_with_message(message)
181
+ end
182
+ end
183
+ end
184
+ end