remarkable_activerecord 3.1.8 → 3.1.9

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 (48) hide show
  1. data/CHANGELOG +140 -138
  2. data/LICENSE +20 -20
  3. data/README +80 -80
  4. data/lib/remarkable_activerecord.rb +29 -29
  5. data/lib/remarkable_activerecord/base.rb +248 -237
  6. data/lib/remarkable_activerecord/describe.rb +27 -27
  7. data/lib/remarkable_activerecord/human_names.rb +36 -36
  8. data/lib/remarkable_activerecord/matchers/accept_nested_attributes_for_matcher.rb +30 -30
  9. data/lib/remarkable_activerecord/matchers/allow_mass_assignment_of_matcher.rb +59 -59
  10. data/lib/remarkable_activerecord/matchers/allow_values_for_matcher.rb +85 -94
  11. data/lib/remarkable_activerecord/matchers/association_matcher.rb +283 -283
  12. data/lib/remarkable_activerecord/matchers/have_column_matcher.rb +68 -68
  13. data/lib/remarkable_activerecord/matchers/have_default_scope_matcher.rb +38 -38
  14. data/lib/remarkable_activerecord/matchers/have_index_matcher.rb +73 -73
  15. data/lib/remarkable_activerecord/matchers/have_readonly_attributes_matcher.rb +30 -30
  16. data/lib/remarkable_activerecord/matchers/have_scope_matcher.rb +85 -85
  17. data/lib/remarkable_activerecord/matchers/validate_acceptance_of_matcher.rb +50 -50
  18. data/lib/remarkable_activerecord/matchers/validate_associated_matcher.rb +97 -97
  19. data/lib/remarkable_activerecord/matchers/validate_confirmation_of_matcher.rb +44 -44
  20. data/lib/remarkable_activerecord/matchers/validate_exclusion_of_matcher.rb +53 -53
  21. data/lib/remarkable_activerecord/matchers/validate_inclusion_of_matcher.rb +52 -52
  22. data/lib/remarkable_activerecord/matchers/validate_length_of_matcher.rb +150 -150
  23. data/lib/remarkable_activerecord/matchers/validate_numericality_of_matcher.rb +181 -181
  24. data/lib/remarkable_activerecord/matchers/validate_presence_of_matcher.rb +29 -29
  25. data/lib/remarkable_activerecord/matchers/validate_uniqueness_of_matcher.rb +233 -233
  26. data/locale/en.yml +261 -261
  27. data/spec/accept_nested_attributes_for_matcher_spec.rb +1 -1
  28. data/spec/allow_mass_assignment_of_matcher_spec.rb +90 -82
  29. data/spec/allow_values_for_matcher_spec.rb +72 -63
  30. data/spec/association_matcher_spec.rb +612 -612
  31. data/spec/describe_spec.rb +3 -3
  32. data/spec/have_column_matcher_spec.rb +73 -73
  33. data/spec/have_default_scope_matcher_spec.rb +1 -1
  34. data/spec/have_index_matcher_spec.rb +87 -87
  35. data/spec/have_readonly_attributes_matcher_spec.rb +47 -47
  36. data/spec/have_scope_matcher_spec.rb +77 -77
  37. data/spec/model_builder.rb +101 -101
  38. data/spec/rcov.opts +1 -1
  39. data/spec/spec.opts +4 -4
  40. data/spec/spec_helper.rb +27 -27
  41. data/spec/validate_acceptance_of_matcher_spec.rb +68 -68
  42. data/spec/validate_associated_matcher_spec.rb +121 -121
  43. data/spec/validate_confirmation_of_matcher_spec.rb +58 -58
  44. data/spec/validate_length_of_matcher_spec.rb +218 -218
  45. data/spec/validate_numericality_of_matcher_spec.rb +179 -179
  46. data/spec/validate_presence_of_matcher_spec.rb +56 -56
  47. data/spec/validate_uniqueness_of_matcher_spec.rb +164 -164
  48. metadata +5 -5
@@ -1,6 +1,6 @@
1
1
  require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
2
2
 
3
- if RAILS_VERSION == '2.3.2'
3
+ if RAILS_VERSION == '2.3.3'
4
4
  describe 'accept_nested_attributes_for' do
5
5
  include ModelBuilder
6
6
 
@@ -1,84 +1,84 @@
1
- require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
2
-
3
- describe 'allow_mass_assignment_of' do
4
- include ModelBuilder
5
-
6
- def define_and_validate(options={})
7
- @model = define_model :product, :title => :string, :category => :string do
8
- attr_protected :title, :category if options[:protected]
9
-
10
- attr_accessible :title, :category if options[:accessible] == true
11
- attr_accessible *options[:accessible] if options[:accessible].is_a?(Array)
12
- end
13
-
14
- allow_mass_assignment_of(:title, :category)
15
- end
16
-
17
- describe 'messages' do
18
-
19
- it 'should contain a description' do
20
- @matcher = allow_mass_assignment_of(:title, :category)
21
- @matcher.description.should == 'allow mass assignment of title and category'
22
- end
23
-
24
- it 'should set allows? message' do
25
- define_and_validate(:protected => true)
26
- @matcher = allow_mass_assignment_of
27
- @matcher.matches?(@model)
28
- @matcher.failure_message.should == 'Expected Product to allow mass assignment (Product is protecting category and title)'
29
- end
30
-
31
- it 'should set is_protected? message' do
32
- @matcher = define_and_validate(:protected => true)
33
- @matcher.matches?(@model)
34
- @matcher.failure_message.should == 'Expected Product to allow mass assignment of title (Product is protecting title)'
35
- end
36
-
37
- it 'should set is_accessible? message' do
38
- @matcher = define_and_validate(:accessible => [:another])
39
- @matcher.matches?(@model)
40
- @matcher.failure_message.should == 'Expected Product to allow mass assignment of title (Product has not made title accessible)'
41
- end
42
-
43
- end
44
-
45
- describe 'matchers' do
46
- it { should define_and_validate }
47
- it { should define_and_validate(:accessible => true) }
48
-
49
- it { should_not define_and_validate(:protected => true) }
50
- it { should_not define_and_validate(:accessible => [:another]) }
51
-
52
- describe 'with no argument' do
53
- it 'should allow mass assignment if no attribute is accessible or protected' do
54
- define_and_validate
55
- should allow_mass_assignment_of
56
- end
57
-
58
- it 'should allow mass assignment if attributes are accessible' do
59
- define_and_validate(:accessible => true)
60
- should allow_mass_assignment_of
61
- end
62
-
63
- it 'should not allow mass assignment if attributes are protected' do
64
- define_and_validate(:protected => true)
65
- should_not allow_mass_assignment_of
66
- end
67
- end
68
- end
69
-
70
- describe 'macros' do
71
- before(:each){ define_and_validate(:accessible => true) }
72
-
73
- should_allow_mass_assignment_of :title
74
- should_allow_mass_assignment_of :category
75
- should_allow_mass_assignment_of :title, :category
76
-
77
- should_not_allow_mass_assignment_of :another
1
+ require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
2
+
3
+ describe 'allow_mass_assignment_of' do
4
+ include ModelBuilder
5
+
6
+ def define_and_validate(options={})
7
+ @model = define_model :product, :title => :string, :category => :string do
8
+ attr_protected :title, :category if options[:protected]
9
+
10
+ attr_accessible :title, :category if options[:accessible] == true
11
+ attr_accessible *options[:accessible] if options[:accessible].is_a?(Array)
12
+ end
13
+
14
+ allow_mass_assignment_of(:title, :category)
15
+ end
16
+
17
+ describe 'messages' do
18
+
19
+ it 'should contain a description' do
20
+ @matcher = allow_mass_assignment_of(:title, :category)
21
+ @matcher.description.should == 'allow mass assignment of title and category'
22
+ end
23
+
24
+ it 'should set allows? message' do
25
+ define_and_validate(:protected => true)
26
+ @matcher = allow_mass_assignment_of
27
+ @matcher.matches?(@model)
28
+ @matcher.failure_message.should == 'Expected Product to allow mass assignment (Product is protecting category and title)'
29
+ end
30
+
31
+ it 'should set is_protected? message' do
32
+ @matcher = define_and_validate(:protected => true)
33
+ @matcher.matches?(@model)
34
+ @matcher.failure_message.should == 'Expected Product to allow mass assignment of title (Product is protecting title)'
35
+ end
36
+
37
+ it 'should set is_accessible? message' do
38
+ @matcher = define_and_validate(:accessible => [:another])
39
+ @matcher.matches?(@model)
40
+ @matcher.failure_message.should == 'Expected Product to allow mass assignment of title (Product has not made title accessible)'
41
+ end
42
+
43
+ end
44
+
45
+ describe 'matchers' do
46
+ it { should define_and_validate }
47
+ it { should define_and_validate(:accessible => true) }
48
+
49
+ it { should_not define_and_validate(:protected => true) }
50
+ it { should_not define_and_validate(:accessible => [:another]) }
51
+
52
+ describe 'with no argument' do
53
+ it 'should allow mass assignment if no attribute is accessible or protected' do
54
+ define_and_validate
55
+ should allow_mass_assignment_of
56
+ end
57
+
58
+ it 'should allow mass assignment if attributes are accessible' do
59
+ define_and_validate(:accessible => true)
60
+ should allow_mass_assignment_of
61
+ end
62
+
63
+ it 'should not allow mass assignment if attributes are protected' do
64
+ define_and_validate(:protected => true)
65
+ should_not allow_mass_assignment_of
66
+ end
67
+ end
68
+ end
69
+
70
+ describe 'macros' do
71
+ before(:each){ define_and_validate(:accessible => true) }
72
+
73
+ should_allow_mass_assignment_of :title
74
+ should_allow_mass_assignment_of :category
75
+ should_allow_mass_assignment_of :title, :category
76
+
77
+ should_not_allow_mass_assignment_of :another
78
78
  end
79
79
 
80
80
  describe 'failures' do
81
- it "should fail if not all attributes are accessible on should not" do
81
+ it "should fail if some attribute is accessible when it shuold be protected" do
82
82
  define_and_validate(:accessible => true)
83
83
 
84
84
  lambda {
@@ -86,13 +86,21 @@ describe 'allow_mass_assignment_of' do
86
86
  }.should raise_error(Spec::Expectations::ExpectationNotMetError, /Product has made title accessible/)
87
87
  end
88
88
 
89
- it "should fail if accessible when protecting" do
89
+ it "should fail if attributes are accessible when none should" do
90
90
  define_and_validate(:accessible => true)
91
91
 
92
92
  lambda {
93
93
  should_not allow_mass_assignment_of
94
94
  }.should raise_error(Spec::Expectations::ExpectationNotMetError, /Product made category and title accessible/)
95
95
  end
96
- end
97
- end
98
-
96
+
97
+ it "should fail if nothing was declared but expected to be protected" do
98
+ define_and_validate
99
+
100
+ lambda {
101
+ should_not allow_mass_assignment_of(:title)
102
+ }.should raise_error(Spec::Expectations::ExpectationNotMetError, /Did not expect Product to allow mass assignment of title/)
103
+ end
104
+ end
105
+ end
106
+
@@ -1,71 +1,80 @@
1
- require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
2
-
3
- describe 'allow_values_for' do
4
- include ModelBuilder
5
-
6
- # Defines a model, create a validation and returns a raw matcher
7
- def define_and_validate(options={})
8
- @model = define_model :product, :title => :string, :category => :string do
9
- validates_format_of :title, options
10
- end
11
-
12
- allow_values_for(:title)
13
- end
14
-
15
- describe 'messages' do
16
- before(:each){ @matcher = define_and_validate(:with => /X|Y|Z/) }
17
-
18
- it 'should contain a description' do
19
- @matcher = allow_values_for(:title, "X", "Y", "Z")
20
- @matcher.description.should == 'allow "X", "Y", and "Z" as values for title'
21
- end
22
-
23
- it 'should set is_valid? message' do
24
- @matcher.in("A").matches?(@model)
25
- @matcher.failure_message.should == 'Expected Product to be valid when title is set to "A"'
26
- end
27
-
28
- it 'should set allow_nil? message' do
29
- @matcher.allow_nil.matches?(@model)
30
- @matcher.failure_message.should == 'Expected Product to allow nil values for title'
31
- end
32
-
33
- it 'should set allow_blank? message' do
34
- @matcher.allow_blank.matches?(@model)
35
- @matcher.failure_message.should == 'Expected Product to allow blank values for title'
36
- end
37
- end
38
-
39
- describe 'matchers' do
40
- it { should define_and_validate(:with => /X|Y|Z/).in('X', 'Y', 'Z') }
41
- it { should_not define_and_validate(:with => /X|Y|Z/).in('A') }
42
-
43
- it { should define_and_validate(:with => /X|Y|Z/, :message => 'valid').in('X', 'Y', 'Z').message('valid') }
44
-
45
- create_optional_boolean_specs(:allow_nil, self, :with => /X|Y|Z/)
46
- create_optional_boolean_specs(:allow_blank, self, :with => /X|Y|Z/)
47
- end
48
-
49
- describe 'macros' do
50
- before(:each){ define_and_validate(:with => /X|Y|Z/) }
51
-
52
- should_allow_values_for :title, 'X'
53
- should_not_allow_values_for :title, 'A'
54
-
55
- describe 'deprecation' do
56
- it { should validate_format_of(:title, 'X') }
57
- should_not_validate_format_of :title, 'A'
58
- end
1
+ require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
2
+
3
+ describe 'allow_values_for' do
4
+ include ModelBuilder
5
+
6
+ # Defines a model, create a validation and returns a raw matcher
7
+ def define_and_validate(options={})
8
+ @model = define_model :product, :title => :string, :category => :string do
9
+ validates_format_of :title, options
10
+ end
11
+
12
+ allow_values_for(:title)
13
+ end
14
+
15
+ describe 'messages' do
16
+ before(:each){ @matcher = define_and_validate(:with => /X|Y|Z/) }
17
+
18
+ it 'should contain a description' do
19
+ @matcher = allow_values_for(:title, "X", "Y", "Z")
20
+ @matcher.description.should == 'allow "X", "Y", and "Z" as values for title'
21
+ end
22
+
23
+ it 'should set is_valid? message' do
24
+ @matcher.in("A").matches?(@model)
25
+ @matcher.failure_message.should == 'Expected Product to be valid when title is set to "A"'
26
+ end
27
+
28
+ it 'should set allow_nil? message' do
29
+ @matcher.allow_nil.matches?(@model)
30
+ @matcher.failure_message.should == 'Expected Product to allow nil values for title'
31
+ end
32
+
33
+ it 'should set allow_blank? message' do
34
+ @matcher.allow_blank.matches?(@model)
35
+ @matcher.failure_message.should == 'Expected Product to allow blank values for title'
36
+ end
37
+ end
38
+
39
+ describe 'matchers' do
40
+ it { should define_and_validate(:with => /X|Y|Z/).in('X', 'Y', 'Z') }
41
+
42
+ it { should_not define_and_validate(:with => /X|Y|Z/).in('A') }
43
+ it { should_not define_and_validate(:with => /X|Y|Z/, :message => 'invalid').in('A') }
44
+
45
+ create_optional_boolean_specs(:allow_nil, self, :with => /X|Y|Z/)
46
+ create_optional_boolean_specs(:allow_blank, self, :with => /X|Y|Z/)
47
+ end
48
+
49
+ describe 'macros' do
50
+ before(:each){ define_and_validate(:with => /X|Y|Z/) }
51
+
52
+ should_allow_values_for :title, 'X'
53
+ should_not_allow_values_for :title, 'A'
59
54
  end
60
55
 
61
56
  describe 'failures' do
62
- it "should fail if any of the values are valid on invalid cases" do
57
+ before(:each) do
63
58
  define_and_validate(:with => /X|Y|Z/)
59
+ end
64
60
 
61
+ it "should fail if any of the values are valid on invalid cases" do
65
62
  lambda {
66
63
  should_not allow_values_for :title, 'A', 'X', 'B'
67
64
  }.should raise_error(Spec::Expectations::ExpectationNotMetError, /Did not expect Product to be valid/)
68
- end
69
- end
70
- end
71
-
65
+ end
66
+
67
+ it "should also fail if all values are valid" do
68
+ lambda {
69
+ should_not allow_values_for :title, 'X', 'Y', 'Z'
70
+ }.should raise_error(Spec::Expectations::ExpectationNotMetError, /Did not expect Product to be valid/)
71
+ end
72
+
73
+ it "should not fail if all values are invalid" do
74
+ lambda {
75
+ should_not allow_values_for :title, 'A', 'B', 'C'
76
+ }.should_not raise_error
77
+ end
78
+ end
79
+ end
80
+
@@ -1,170 +1,170 @@
1
- require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
2
-
3
- describe 'association_matcher' do
4
- include ModelBuilder
5
-
6
- describe 'belong_to' do
7
-
8
- # Defines a model, create a validation and returns a raw matcher
9
- def define_and_validate(options={})
10
- columns = options.delete(:association_columns) || { :projects_count => :integer }
1
+ require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
2
+
3
+ describe 'association_matcher' do
4
+ include ModelBuilder
5
+
6
+ describe 'belong_to' do
7
+
8
+ # Defines a model, create a validation and returns a raw matcher
9
+ def define_and_validate(options={})
10
+ columns = options.delete(:association_columns) || { :projects_count => :integer }
11
11
  define_model :company, columns
12
12
  define_model :super_company, columns
13
-
14
- columns = options.delete(:model_columns) || { :company_id => :integer, :company_type => :string }
15
- @model = define_model :project, columns do
13
+
14
+ columns = options.delete(:model_columns) || { :company_id => :integer, :company_type => :string }
15
+ @model = define_model :project, columns do
16
16
  belongs_to :company, options
17
17
  belongs_to :unknown
18
- belongs_to :accountable, :polymorphic => true
19
- end
20
-
21
- belong_to :company
22
- end
23
-
24
- describe 'messages' do
25
- it 'should contain a description' do
26
- matcher = define_and_validate
27
- matcher.description.should == 'belong to company'
28
-
29
- matcher.class_name('Company')
30
- matcher.description.should == 'belong to company with class name "Company"'
31
-
32
- matcher.foreign_key('company_id')
33
- matcher.description.should == 'belong to company with class name "Company" and with foreign key "company_id"'
34
-
35
- matcher = belong_to(:company).dependent(:destroy)
36
- matcher.description.should == 'belong to company with dependent :destroy'
37
-
38
- matcher.readonly
39
- matcher.description.should == 'belong to company with dependent :destroy and with readonly records'
40
-
41
- matcher.as(:interface)
42
- matcher.description.should == 'belong to company with dependent :destroy, through the polymorphic interface :interface, and with readonly records'
43
-
44
- matcher.counter_cache('projects_count')
18
+ belongs_to :accountable, :polymorphic => true
19
+ end
20
+
21
+ belong_to :company
22
+ end
23
+
24
+ describe 'messages' do
25
+ it 'should contain a description' do
26
+ matcher = define_and_validate
27
+ matcher.description.should == 'belong to company'
28
+
29
+ matcher.class_name('Company')
30
+ matcher.description.should == 'belong to company with class name "Company"'
31
+
32
+ matcher.foreign_key('company_id')
33
+ matcher.description.should == 'belong to company with class name "Company" and with foreign key "company_id"'
34
+
35
+ matcher = belong_to(:company).dependent(:destroy)
36
+ matcher.description.should == 'belong to company with dependent :destroy'
37
+
38
+ matcher.readonly
39
+ matcher.description.should == 'belong to company with dependent :destroy and with readonly records'
40
+
41
+ matcher.as(:interface)
42
+ matcher.description.should == 'belong to company with dependent :destroy, through the polymorphic interface :interface, and with readonly records'
43
+
44
+ matcher.counter_cache('projects_count')
45
45
  matcher.description.should == 'belong to company with dependent :destroy, through the polymorphic interface :interface, ' <<
46
- 'with readonly records, and with counter cache "projects_count"'
47
- end
48
-
49
- it 'should set association_exists? message' do
50
- define_and_validate
51
- matcher = belong_to('whatever')
52
- matcher.matches?(@model)
53
- matcher.failure_message.should == 'Expected Project records belong to whatever, but the association does not exist'
54
- end
55
-
56
- it 'should set macro_matches? message' do
57
- define_and_validate
58
- matcher = have_one('company')
59
- matcher.matches?(@model)
60
- matcher.failure_message.should == 'Expected Project records have one company, got Project records belong to company'
46
+ 'with readonly records, and with counter cache "projects_count"'
47
+ end
48
+
49
+ it 'should set association_exists? message' do
50
+ define_and_validate
51
+ matcher = belong_to('whatever')
52
+ matcher.matches?(@model)
53
+ matcher.failure_message.should == 'Expected Project records belong to whatever, but the association does not exist'
54
+ end
55
+
56
+ it 'should set macro_matches? message' do
57
+ define_and_validate
58
+ matcher = have_one('company')
59
+ matcher.matches?(@model)
60
+ matcher.failure_message.should == 'Expected Project records have one company, got Project records belong to company'
61
61
  end
62
62
 
63
63
  it 'should set klass_exists? message' do
64
- define_and_validate
65
- matcher = belong_to('unknown')
66
- matcher.matches?(@model)
64
+ define_and_validate
65
+ matcher = belong_to('unknown')
66
+ matcher.matches?(@model)
67
67
  matcher.failure_message.should == 'Expected Project records belong to unknown, but the association class does not exist'
68
- end
69
-
70
- it 'should set foreign_key_exists? message' do
71
- matcher = define_and_validate(:model_columns => {})
72
- matcher.matches?(@model)
73
- matcher.failure_message.should == 'Expected foreign key "company_id" to exist on "projects", but does not'
74
- end
75
-
76
- it 'should set polymorphic_exists? message' do
77
- matcher = define_and_validate(:model_columns => { :company_id => :integer }, :polymorphic => true)
78
- matcher.polymorphic.matches?(@model)
79
- matcher.failure_message.should == 'Expected "projects" to have "company_type" as column, but does not'
80
- end
81
-
82
- it 'should set counter_cache_exists? message' do
83
- matcher = define_and_validate(:association_columns => {}, :counter_cache => true)
84
- matcher.counter_cache.matches?(@model)
85
- matcher.failure_message.should == 'Expected "companies" to have "projects_count" as column, but does not'
86
- end
87
-
88
- it 'should set options_matches? message when polymorphic is given' do
89
- matcher = define_and_validate(:polymorphic => false)
90
- matcher.polymorphic.matches?(@model)
91
- matcher.failure_message.should == 'Expected Project records belong to company with options {:polymorphic=>"true"}, got {:polymorphic=>"false"}'
92
- end
93
-
94
- it 'should set options_matches? message when counter_cache is given' do
95
- matcher = define_and_validate(:counter_cache => true)
96
- matcher.counter_cache(false).matches?(@model)
97
- matcher.failure_message.should == 'Expected Project records belong to company with options {:counter_cache=>"false"}, got {:counter_cache=>"true"}'
98
- end
99
- end
100
-
101
- describe 'matchers' do
102
- describe 'without options' do
103
- before(:each){ define_and_validate }
104
-
68
+ end
69
+
70
+ it 'should set foreign_key_exists? message' do
71
+ matcher = define_and_validate(:model_columns => {})
72
+ matcher.matches?(@model)
73
+ matcher.failure_message.should == 'Expected foreign key "company_id" to exist on "projects", but does not'
74
+ end
75
+
76
+ it 'should set polymorphic_exists? message' do
77
+ matcher = define_and_validate(:model_columns => { :company_id => :integer }, :polymorphic => true)
78
+ matcher.polymorphic.matches?(@model)
79
+ matcher.failure_message.should == 'Expected "projects" to have "company_type" as column, but does not'
80
+ end
81
+
82
+ it 'should set counter_cache_exists? message' do
83
+ matcher = define_and_validate(:association_columns => {}, :counter_cache => true)
84
+ matcher.counter_cache.matches?(@model)
85
+ matcher.failure_message.should == 'Expected "companies" to have "projects_count" as column, but does not'
86
+ end
87
+
88
+ it 'should set options_matches? message when polymorphic is given' do
89
+ matcher = define_and_validate(:polymorphic => false)
90
+ matcher.polymorphic.matches?(@model)
91
+ matcher.failure_message.should == 'Expected Project records belong to company with options {:polymorphic=>"true"}, got {:polymorphic=>"false"}'
92
+ end
93
+
94
+ it 'should set options_matches? message when counter_cache is given' do
95
+ matcher = define_and_validate(:counter_cache => true)
96
+ matcher.counter_cache(false).matches?(@model)
97
+ matcher.failure_message.should == 'Expected Project records belong to company with options {:counter_cache=>"false"}, got {:counter_cache=>"true"}'
98
+ end
99
+ end
100
+
101
+ describe 'matchers' do
102
+ describe 'without options' do
103
+ before(:each){ define_and_validate }
104
+
105
105
  it { should belong_to(:company) }
106
- it { should_not belong_to(:unknown) }
107
- it { should_not belong_to(:project) }
108
- it { should_not have_one(:company) }
109
- it { should_not have_many(:company) }
110
- end
111
-
112
- describe 'with class name option' do
113
- it { should define_and_validate.class_name('Company') }
114
- it { should define_and_validate(:class_name => 'SuperCompany').class_name('SuperCompany') }
115
-
116
- it { should_not define_and_validate.class_name('SuperCompany') }
117
- it { should_not define_and_validate(:class_name => 'Company').class_name('SuperCompany') }
118
- end
119
-
120
- describe 'with foreign_key option' do
121
- it { should define_and_validate.foreign_key(:company_id) }
122
- it { should_not define_and_validate.foreign_key(:association_id) }
123
-
124
- # Checks whether fk exists or not
125
- it { should define_and_validate(:foreign_key => :association_id,
126
- :model_columns => { :association_id => :integer }).foreign_key(:association_id) }
127
-
128
- it { should_not define_and_validate(:foreign_key => :association_id).foreign_key(:association_id) }
129
- it { should_not define_and_validate(:model_columns => { :association_id => :integer }).foreign_key(:association_id) }
130
- end
131
-
132
- describe 'with dependent option' do
133
- it { should define_and_validate(:dependent => :delete).dependent(:delete) }
134
- it { should define_and_validate(:dependent => :destroy).dependent(:destroy) }
135
-
136
- it { should_not define_and_validate(:dependent => :delete).dependent(:destroy) }
137
- it { should_not define_and_validate(:dependent => :destroy).dependent(:delete) }
138
- end
139
-
140
- describe 'with counter_cache option' do
141
- # Checks whether fk exists or not
142
- it { should define_and_validate(:counter_cache => :association_count,
143
- :association_columns => { :association_count => :integer }).counter_cache(:association_count) }
144
-
145
- it { should_not define_and_validate(:counter_cache => :association_count).counter_cache(:association_count) }
146
- it { should_not define_and_validate(:association_columns => { :association_count => :integer }).counter_cache(:association_count) }
147
- end
106
+ it { should_not belong_to(:unknown) }
107
+ it { should_not belong_to(:project) }
108
+ it { should_not have_one(:company) }
109
+ it { should_not have_many(:company) }
110
+ end
111
+
112
+ describe 'with class name option' do
113
+ it { should define_and_validate.class_name('Company') }
114
+ it { should define_and_validate(:class_name => 'SuperCompany').class_name('SuperCompany') }
115
+
116
+ it { should_not define_and_validate.class_name('SuperCompany') }
117
+ it { should_not define_and_validate(:class_name => 'Company').class_name('SuperCompany') }
118
+ end
119
+
120
+ describe 'with foreign_key option' do
121
+ it { should define_and_validate.foreign_key(:company_id) }
122
+ it { should_not define_and_validate.foreign_key(:association_id) }
123
+
124
+ # Checks whether fk exists or not
125
+ it { should define_and_validate(:foreign_key => :association_id,
126
+ :model_columns => { :association_id => :integer }).foreign_key(:association_id) }
127
+
128
+ it { should_not define_and_validate(:foreign_key => :association_id).foreign_key(:association_id) }
129
+ it { should_not define_and_validate(:model_columns => { :association_id => :integer }).foreign_key(:association_id) }
130
+ end
131
+
132
+ describe 'with dependent option' do
133
+ it { should define_and_validate(:dependent => :delete).dependent(:delete) }
134
+ it { should define_and_validate(:dependent => :destroy).dependent(:destroy) }
135
+
136
+ it { should_not define_and_validate(:dependent => :delete).dependent(:destroy) }
137
+ it { should_not define_and_validate(:dependent => :destroy).dependent(:delete) }
138
+ end
139
+
140
+ describe 'with counter_cache option' do
141
+ # Checks whether fk exists or not
142
+ it { should define_and_validate(:counter_cache => :association_count,
143
+ :association_columns => { :association_count => :integer }).counter_cache(:association_count) }
144
+
145
+ it { should_not define_and_validate(:counter_cache => :association_count).counter_cache(:association_count) }
146
+ it { should_not define_and_validate(:association_columns => { :association_count => :integer }).counter_cache(:association_count) }
147
+ end
148
148
 
149
149
  describe "with polymorphic option" do
150
150
  before(:each){ define_and_validate(:model_columns => {:accountable_id => :integer, :accountable_type => :string}) }
151
151
  it { should belong_to(:accountable).polymorphic }
152
152
  end
153
-
154
- create_optional_boolean_specs(:readonly, self)
155
- create_optional_boolean_specs(:validate, self)
156
- create_optional_boolean_specs(:autosave, self) if RAILS_VERSION =~ /^2.3/
157
- create_optional_boolean_specs(:polymorphic, self)
158
- create_optional_boolean_specs(:counter_cache, self)
159
- end
160
-
161
- describe 'macros' do
162
- before(:each){ define_and_validate(:validate => true, :readonly => true) }
163
-
164
- should_belong_to :company
165
- should_belong_to :company, :readonly => true
166
- should_belong_to :company, :validate => true
167
- should_belong_to :company, :class_name => "Company"
153
+
154
+ create_optional_boolean_specs(:readonly, self)
155
+ create_optional_boolean_specs(:validate, self)
156
+ create_optional_boolean_specs(:autosave, self) if RAILS_VERSION =~ /^2.3/
157
+ create_optional_boolean_specs(:polymorphic, self)
158
+ create_optional_boolean_specs(:counter_cache, self)
159
+ end
160
+
161
+ describe 'macros' do
162
+ before(:each){ define_and_validate(:validate => true, :readonly => true) }
163
+
164
+ should_belong_to :company
165
+ should_belong_to :company, :readonly => true
166
+ should_belong_to :company, :validate => true
167
+ should_belong_to :company, :class_name => "Company"
168
168
  should_belong_to :company, :foreign_key => :company_id
169
169
 
170
170
  should_belong_to :company do |m|
@@ -172,153 +172,153 @@ describe 'association_matcher' do
172
172
  m.validate
173
173
  m.class_name = "Company"
174
174
  m.foreign_key = :company_id
175
- end
176
-
177
- should_not_belong_to :unknown
178
- should_not_belong_to :project
179
- should_not_have_one :company
180
- should_not_have_many :companies
181
-
182
- should_not_belong_to :company, :readonly => false
183
- should_not_belong_to :company, :validate => false
184
- should_not_belong_to :company, :class_name => "Anything"
185
- should_not_belong_to :company, :foreign_key => :anything_id
186
- end
187
- end
188
-
189
- describe 'have_and_belong_to_many' do
190
-
191
- # Defines a model, create a validation and returns a raw matcher
192
- def define_and_validate(options={})
175
+ end
176
+
177
+ should_not_belong_to :unknown
178
+ should_not_belong_to :project
179
+ should_not_have_one :company
180
+ should_not_have_many :companies
181
+
182
+ should_not_belong_to :company, :readonly => false
183
+ should_not_belong_to :company, :validate => false
184
+ should_not_belong_to :company, :class_name => "Anything"
185
+ should_not_belong_to :company, :foreign_key => :anything_id
186
+ end
187
+ end
188
+
189
+ describe 'have_and_belong_to_many' do
190
+
191
+ # Defines a model, create a validation and returns a raw matcher
192
+ def define_and_validate(options={})
193
193
  define_model :label
194
- define_model :super_label
195
-
196
- columns = options.delete(:association_columns) || [ :label_id, :project_id ]
197
- create_table(options.delete(:association_table) || :labels_projects) do |table|
198
- columns.each { |name| table.column(name, :integer) }
199
- end
200
-
201
- @model = define_model :project, options.delete(:model_columns) || {} do
202
- has_and_belongs_to_many :labels, options
203
- end
204
-
205
- have_and_belong_to_many :labels
206
- end
207
-
208
- describe 'messages' do
209
- it 'should contain a description' do
210
- matcher = define_and_validate
211
- matcher.description.should == 'have and belong to many labels'
212
-
213
- matcher.class_name('Label')
214
- matcher.description.should == 'have and belong to many labels with class name "Label"'
215
-
216
- matcher.foreign_key('label_id')
217
- matcher.description.should == 'have and belong to many labels with class name "Label" and with foreign key "label_id"'
218
-
219
- matcher = have_and_belong_to_many(:labels).autosave
220
- matcher.description.should == 'have and belong to many labels autosaving associated records'
221
-
222
- matcher.uniq
223
- matcher.description.should == 'have and belong to many labels with unique records and autosaving associated records'
224
- end
225
-
226
- it 'should set association_exists? message' do
227
- define_and_validate
228
- matcher = have_and_belong_to_many('whatever')
229
- matcher.matches?(@model)
230
- matcher.failure_message.should == 'Expected Project records have and belong to many whatever, but the association does not exist'
231
- end
232
-
233
- it 'should set macro_matches? message' do
234
- define_and_validate
235
- matcher = have_many('labels')
236
- matcher.matches?(@model)
237
- matcher.failure_message.should == 'Expected Project records have many labels, got Project records have and belong to many labels'
238
- end
239
-
240
- it 'should set join_table_exists? message' do
241
- matcher = define_and_validate(:association_table => 'another_name')
242
- matcher.matches?(@model)
243
- matcher.failure_message.should == 'Expected join table "labels_projects" to exist, but does not'
244
- end
245
-
246
- it 'should set foreign_key_exists? message' do
247
- matcher = define_and_validate(:association_columns => [])
248
- matcher.matches?(@model)
249
- matcher.failure_message.should == 'Expected foreign key "project_id" to exist on "labels_projects", but does not'
250
- end
251
-
252
- it 'should set options_matches? message' do
253
- matcher = define_and_validate(:uniq => false)
254
- matcher.uniq.matches?(@model)
255
- matcher.failure_message.should == 'Expected Project records have and belong to many labels with options {:uniq=>"true"}, got {:uniq=>"false"}'
256
- end
257
- end
258
-
259
- describe 'matchers' do
260
- describe 'without options' do
261
- before(:each){ define_and_validate }
262
-
263
- it { should have_and_belong_to_many(:labels) }
264
- it { should_not belong_to(:label) }
265
- it { should_not have_one(:label) }
266
- it { should_not have_many(:labels) }
267
- it { should_not have_and_belong_to_many(:companies) }
268
- end
269
-
270
- describe 'with class name option' do
271
- it { should define_and_validate.class_name('Label') }
272
-
273
- it { should define_and_validate(:class_name => 'SuperLabel',
274
- :association_table => 'projects_super_labels').class_name('SuperLabel') }
275
-
276
- it { should_not define_and_validate.class_name('SuperLabel') }
277
- end
278
-
279
- describe 'with foreign_key option' do
280
- it { should define_and_validate.foreign_key(:project_id) }
281
- it { should_not define_and_validate.foreign_key(:association_id) }
282
-
283
- # Checks whether fk exists or not
284
- it { should define_and_validate(:foreign_key => :association_id,
285
- :association_columns => [ :association_id ]).foreign_key(:association_id) }
286
-
287
- it { should_not define_and_validate(:foreign_key => :association_id).foreign_key(:association_id) }
288
- it { should_not define_and_validate(:association_columns => [ :association_id ]).foreign_key(:association_id) }
289
- end
290
-
291
- describe 'with join table option' do
292
- it { should define_and_validate.join_table('labels_projects') }
293
- it { should define_and_validate(:join_table => 'my_table',
194
+ define_model :super_label
195
+
196
+ columns = options.delete(:association_columns) || [ :label_id, :project_id ]
197
+ create_table(options.delete(:association_table) || :labels_projects) do |table|
198
+ columns.each { |name| table.column(name, :integer) }
199
+ end
200
+
201
+ @model = define_model :project, options.delete(:model_columns) || {} do
202
+ has_and_belongs_to_many :labels, options
203
+ end
204
+
205
+ have_and_belong_to_many :labels
206
+ end
207
+
208
+ describe 'messages' do
209
+ it 'should contain a description' do
210
+ matcher = define_and_validate
211
+ matcher.description.should == 'have and belong to many labels'
212
+
213
+ matcher.class_name('Label')
214
+ matcher.description.should == 'have and belong to many labels with class name "Label"'
215
+
216
+ matcher.foreign_key('label_id')
217
+ matcher.description.should == 'have and belong to many labels with class name "Label" and with foreign key "label_id"'
218
+
219
+ matcher = have_and_belong_to_many(:labels).autosave
220
+ matcher.description.should == 'have and belong to many labels autosaving associated records'
221
+
222
+ matcher.uniq
223
+ matcher.description.should == 'have and belong to many labels with unique records and autosaving associated records'
224
+ end
225
+
226
+ it 'should set association_exists? message' do
227
+ define_and_validate
228
+ matcher = have_and_belong_to_many('whatever')
229
+ matcher.matches?(@model)
230
+ matcher.failure_message.should == 'Expected Project records have and belong to many whatever, but the association does not exist'
231
+ end
232
+
233
+ it 'should set macro_matches? message' do
234
+ define_and_validate
235
+ matcher = have_many('labels')
236
+ matcher.matches?(@model)
237
+ matcher.failure_message.should == 'Expected Project records have many labels, got Project records have and belong to many labels'
238
+ end
239
+
240
+ it 'should set join_table_exists? message' do
241
+ matcher = define_and_validate(:association_table => 'another_name')
242
+ matcher.matches?(@model)
243
+ matcher.failure_message.should == 'Expected join table "labels_projects" to exist, but does not'
244
+ end
245
+
246
+ it 'should set foreign_key_exists? message' do
247
+ matcher = define_and_validate(:association_columns => [])
248
+ matcher.matches?(@model)
249
+ matcher.failure_message.should == 'Expected foreign key "project_id" to exist on "labels_projects", but does not'
250
+ end
251
+
252
+ it 'should set options_matches? message' do
253
+ matcher = define_and_validate(:uniq => false)
254
+ matcher.uniq.matches?(@model)
255
+ matcher.failure_message.should == 'Expected Project records have and belong to many labels with options {:uniq=>"true"}, got {:uniq=>"false"}'
256
+ end
257
+ end
258
+
259
+ describe 'matchers' do
260
+ describe 'without options' do
261
+ before(:each){ define_and_validate }
262
+
263
+ it { should have_and_belong_to_many(:labels) }
264
+ it { should_not belong_to(:label) }
265
+ it { should_not have_one(:label) }
266
+ it { should_not have_many(:labels) }
267
+ it { should_not have_and_belong_to_many(:companies) }
268
+ end
269
+
270
+ describe 'with class name option' do
271
+ it { should define_and_validate.class_name('Label') }
272
+
273
+ it { should define_and_validate(:class_name => 'SuperLabel',
274
+ :association_table => 'projects_super_labels').class_name('SuperLabel') }
275
+
276
+ it { should_not define_and_validate.class_name('SuperLabel') }
277
+ end
278
+
279
+ describe 'with foreign_key option' do
280
+ it { should define_and_validate.foreign_key(:project_id) }
281
+ it { should_not define_and_validate.foreign_key(:association_id) }
282
+
283
+ # Checks whether fk exists or not
284
+ it { should define_and_validate(:foreign_key => :association_id,
285
+ :association_columns => [ :association_id ]).foreign_key(:association_id) }
286
+
287
+ it { should_not define_and_validate(:foreign_key => :association_id).foreign_key(:association_id) }
288
+ it { should_not define_and_validate(:association_columns => [ :association_id ]).foreign_key(:association_id) }
289
+ end
290
+
291
+ describe 'with join table option' do
292
+ it { should define_and_validate.join_table('labels_projects') }
293
+ it { should define_and_validate(:join_table => 'my_table',
294
294
  :association_table => 'my_table').join_table('my_table') }
295
295
 
296
- it { should define_and_validate(:join_table => :my_table,
297
- :association_table => :my_table).join_table(:my_table) }
298
-
299
- it { should_not define_and_validate.join_table('projects_labels') }
300
-
301
- it { should_not define_and_validate(:join_table => 'my_table',
302
- :association_table => 'another_table').join_table('my_table') }
303
- it { should_not define_and_validate(:join_table => 'another_table',
304
- :association_table => 'my_table').join_table('my_table') }
305
- it { should_not define_and_validate(:join_table => 'my_table',
306
- :association_table => 'my_table').join_table('another_table') }
307
- end
308
-
309
- create_optional_boolean_specs(:uniq, self)
310
- create_optional_boolean_specs(:readonly, self)
311
- create_optional_boolean_specs(:validate, self)
312
- create_optional_boolean_specs(:autosave, self) if RAILS_VERSION =~ /^2.3/
313
- end
314
-
315
- describe 'macros' do
316
- before(:each){ define_and_validate(:validate => true, :readonly => true) }
317
-
318
- should_have_and_belong_to_many :labels
319
- should_have_and_belong_to_many :labels, :readonly => true
320
- should_have_and_belong_to_many :labels, :validate => true
321
- should_have_and_belong_to_many :labels, :class_name => "Label"
296
+ it { should define_and_validate(:join_table => :my_table,
297
+ :association_table => :my_table).join_table(:my_table) }
298
+
299
+ it { should_not define_and_validate.join_table('projects_labels') }
300
+
301
+ it { should_not define_and_validate(:join_table => 'my_table',
302
+ :association_table => 'another_table').join_table('my_table') }
303
+ it { should_not define_and_validate(:join_table => 'another_table',
304
+ :association_table => 'my_table').join_table('my_table') }
305
+ it { should_not define_and_validate(:join_table => 'my_table',
306
+ :association_table => 'my_table').join_table('another_table') }
307
+ end
308
+
309
+ create_optional_boolean_specs(:uniq, self)
310
+ create_optional_boolean_specs(:readonly, self)
311
+ create_optional_boolean_specs(:validate, self)
312
+ create_optional_boolean_specs(:autosave, self) if RAILS_VERSION =~ /^2.3/
313
+ end
314
+
315
+ describe 'macros' do
316
+ before(:each){ define_and_validate(:validate => true, :readonly => true) }
317
+
318
+ should_have_and_belong_to_many :labels
319
+ should_have_and_belong_to_many :labels, :readonly => true
320
+ should_have_and_belong_to_many :labels, :validate => true
321
+ should_have_and_belong_to_many :labels, :class_name => "Label"
322
322
  should_have_and_belong_to_many :labels, :foreign_key => :project_id
323
323
 
324
324
  should_have_and_belong_to_many :labels do |m|
@@ -326,346 +326,346 @@ describe 'association_matcher' do
326
326
  m.validate
327
327
  m.class_name "Label"
328
328
  m.foreign_key :project_id
329
- end
330
-
331
- should_not_have_and_belong_to_many :companies
332
- should_not_have_one :label
333
- should_not_have_many :labels
334
-
335
- should_not_have_and_belong_to_many :labels, :readonly => false
336
- should_not_have_and_belong_to_many :labels, :validate => false
337
- should_not_have_and_belong_to_many :labels, :class_name => "Anything"
338
- should_not_have_and_belong_to_many :labels, :foreign_key => :anything_id
339
- end
340
- end
341
-
342
- describe 'have_many' do
343
-
344
- # Defines a model, create a validation and returns a raw matcher
345
- def define_and_validate(options={})
346
- columns = options.delete(:association_columns) || { :task_id => :integer, :project_id => :integer, :todo_id => :integer }
329
+ end
330
+
331
+ should_not_have_and_belong_to_many :companies
332
+ should_not_have_one :label
333
+ should_not_have_many :labels
334
+
335
+ should_not_have_and_belong_to_many :labels, :readonly => false
336
+ should_not_have_and_belong_to_many :labels, :validate => false
337
+ should_not_have_and_belong_to_many :labels, :class_name => "Anything"
338
+ should_not_have_and_belong_to_many :labels, :foreign_key => :anything_id
339
+ end
340
+ end
341
+
342
+ describe 'have_many' do
343
+
344
+ # Defines a model, create a validation and returns a raw matcher
345
+ def define_and_validate(options={})
346
+ columns = options.delete(:association_columns) || { :task_id => :integer, :project_id => :integer, :todo_id => :integer }
347
347
  define_model :task, columns
348
- define_model :todo, columns
349
-
350
- define_model :project_task, columns do
351
- belongs_to :task
348
+ define_model :todo, columns
349
+
350
+ define_model :project_task, columns do
351
+ belongs_to :task
352
352
  belongs_to :project
353
- belongs_to :todo
354
- end unless options.delete(:skip_source)
355
-
353
+ belongs_to :todo
354
+ end unless options.delete(:skip_source)
355
+
356
356
  @model = define_model :project, options.delete(:model_columns) || {} do
357
- has_many :project_tasks unless options.delete(:skip_through)
358
- has_many :tasks, options
359
- end
360
-
361
- have_many :tasks
362
- end
363
-
364
- describe 'messages' do
365
- it 'should contain a description' do
366
- matcher = define_and_validate
367
- matcher.description.should == 'have many tasks'
368
-
369
- matcher.class_name('Task')
370
- matcher.description.should == 'have many tasks with class name "Task"'
371
-
372
- matcher.foreign_key('task_id')
373
- matcher.description.should == 'have many tasks with class name "Task" and with foreign key "task_id"'
374
-
375
- matcher = have_many(:tasks).autosave
376
- matcher.description.should == 'have many tasks autosaving associated records'
377
-
378
- matcher.uniq
379
- matcher.description.should == 'have many tasks with unique records and autosaving associated records'
380
- end
381
-
382
- it 'should set association_exists? message' do
383
- define_and_validate
384
- matcher = have_many('whatever')
385
- matcher.matches?(@model)
386
- matcher.failure_message.should == 'Expected Project records have many whatever, but the association does not exist'
387
- end
388
-
389
- it 'should set macro_matches? message' do
390
- define_and_validate
391
- matcher = have_and_belong_to_many('tasks')
392
- matcher.matches?(@model)
393
- matcher.failure_message.should == 'Expected Project records have and belong to many tasks, got Project records have many tasks'
394
- end
395
-
396
- it 'should set foreign_key_exists? message' do
397
- matcher = define_and_validate(:association_columns => {})
398
- matcher.matches?(@model)
399
- matcher.failure_message.should == 'Expected foreign key "project_id" to exist on "tasks", but does not'
400
- end
401
-
402
- it 'should set through_exists? message' do
403
- matcher = define_and_validate(:through => :project_tasks, :skip_through => true)
404
- matcher.through(:project_tasks).matches?(@model)
405
- matcher.failure_message.should == 'Expected Project records have many tasks through :project_tasks, through association does not exist'
406
- end
407
-
408
- it 'should set source_exists? message' do
409
- matcher = define_and_validate(:through => :project_tasks, :skip_source => true)
410
- matcher.through(:project_tasks).matches?(@model)
411
- matcher.failure_message.should == 'Expected Project records have many tasks through :project_tasks, source association does not exist'
412
- end
413
-
414
- it 'should set options_matches? message when dependent is given' do
415
- matcher = define_and_validate(:dependent => :destroy)
416
- matcher.dependent(:nullify).matches?(@model)
417
- matcher.failure_message.should == 'Expected Project records have many tasks with options {:dependent=>"nullify"}, got {:dependent=>"destroy"}'
418
- end
419
-
420
- it 'should set options_matches? message when source is given' do
421
- matcher = define_and_validate(:through => :project_tasks, :source => :todo)
422
- matcher.through(:project_tasks).source(:task).matches?(@model)
357
+ has_many :project_tasks unless options.delete(:skip_through)
358
+ has_many :tasks, options
359
+ end
360
+
361
+ have_many :tasks
362
+ end
363
+
364
+ describe 'messages' do
365
+ it 'should contain a description' do
366
+ matcher = define_and_validate
367
+ matcher.description.should == 'have many tasks'
368
+
369
+ matcher.class_name('Task')
370
+ matcher.description.should == 'have many tasks with class name "Task"'
371
+
372
+ matcher.foreign_key('task_id')
373
+ matcher.description.should == 'have many tasks with class name "Task" and with foreign key "task_id"'
374
+
375
+ matcher = have_many(:tasks).autosave
376
+ matcher.description.should == 'have many tasks autosaving associated records'
377
+
378
+ matcher.uniq
379
+ matcher.description.should == 'have many tasks with unique records and autosaving associated records'
380
+ end
381
+
382
+ it 'should set association_exists? message' do
383
+ define_and_validate
384
+ matcher = have_many('whatever')
385
+ matcher.matches?(@model)
386
+ matcher.failure_message.should == 'Expected Project records have many whatever, but the association does not exist'
387
+ end
388
+
389
+ it 'should set macro_matches? message' do
390
+ define_and_validate
391
+ matcher = have_and_belong_to_many('tasks')
392
+ matcher.matches?(@model)
393
+ matcher.failure_message.should == 'Expected Project records have and belong to many tasks, got Project records have many tasks'
394
+ end
395
+
396
+ it 'should set foreign_key_exists? message' do
397
+ matcher = define_and_validate(:association_columns => {})
398
+ matcher.matches?(@model)
399
+ matcher.failure_message.should == 'Expected foreign key "project_id" to exist on "tasks", but does not'
400
+ end
401
+
402
+ it 'should set through_exists? message' do
403
+ matcher = define_and_validate(:through => :project_tasks, :skip_through => true)
404
+ matcher.through(:project_tasks).matches?(@model)
405
+ matcher.failure_message.should == 'Expected Project records have many tasks through :project_tasks, through association does not exist'
406
+ end
407
+
408
+ it 'should set source_exists? message' do
409
+ matcher = define_and_validate(:through => :project_tasks, :skip_source => true)
410
+ matcher.through(:project_tasks).matches?(@model)
411
+ matcher.failure_message.should == 'Expected Project records have many tasks through :project_tasks, source association does not exist'
412
+ end
413
+
414
+ it 'should set options_matches? message when dependent is given' do
415
+ matcher = define_and_validate(:dependent => :destroy)
416
+ matcher.dependent(:nullify).matches?(@model)
417
+ matcher.failure_message.should == 'Expected Project records have many tasks with options {:dependent=>"nullify"}, got {:dependent=>"destroy"}'
418
+ end
419
+
420
+ it 'should set options_matches? message when source is given' do
421
+ matcher = define_and_validate(:through => :project_tasks, :source => :todo)
422
+ matcher.through(:project_tasks).source(:task).matches?(@model)
423
423
  matcher.failure_message.should match(/:source=>"task"/)
424
- matcher.failure_message.should match(/:source=>"todo"/)
425
- end
426
- end
427
-
428
- describe 'matchers' do
429
- describe 'without options' do
430
- before(:each){ define_and_validate }
431
-
432
- it { should have_many(:tasks) }
433
- it { should_not belong_to(:task) }
434
- it { should_not have_one(:task) }
435
- it { should_not have_and_belong_to_many(:tasks) }
436
- end
437
-
438
- describe 'with class name option' do
439
- before(:each){ define_model :super_task, :project_id => :integer }
440
-
441
- it { should define_and_validate.class_name('Task') }
442
- it { should define_and_validate(:class_name => 'SuperTask').class_name('SuperTask') }
443
-
444
- it { should_not define_and_validate.class_name('SuperTask') }
445
- it { should_not define_and_validate(:class_name => 'SuperTask').class_name('Task') }
446
- end
447
-
448
- describe 'with foreign_key option' do
449
- it { should define_and_validate.foreign_key(:project_id) }
450
- it { should_not define_and_validate.foreign_key(:association_id) }
451
-
452
- # Checks whether fk exists or not
453
- it { should define_and_validate(:foreign_key => :association_id,
454
- :association_columns => { :association_id => :integer }).foreign_key(:association_id) }
455
-
456
- it { should_not define_and_validate(:foreign_key => :association_id).foreign_key(:association_id) }
457
- it { should_not define_and_validate(:association_columns => { :association_id => :integer }).foreign_key(:association_id) }
458
- end
459
-
460
- describe 'with dependent option' do
461
- it { should define_and_validate(:dependent => :delete_all).dependent(:delete_all) }
462
- it { should define_and_validate(:dependent => :destroy).dependent(:destroy) }
463
-
464
- it { should_not define_and_validate(:dependent => :delete_all).dependent(:destroy) }
465
- it { should_not define_and_validate(:dependent => :destroy).dependent(:delete_all) }
466
- end
467
-
468
- describe 'with through option' do
469
- it { should define_and_validate(:through => :project_tasks) }
470
- it { should define_and_validate(:through => :project_tasks).through(:project_tasks) }
471
-
472
- it { should_not define_and_validate(:through => :project_tasks).through(:something) }
473
- it { should_not define_and_validate(:through => :project_tasks, :skip_through => true).through(:project_tasks) }
474
- end
475
-
476
- describe 'with source option' do
424
+ matcher.failure_message.should match(/:source=>"todo"/)
425
+ end
426
+ end
427
+
428
+ describe 'matchers' do
429
+ describe 'without options' do
430
+ before(:each){ define_and_validate }
431
+
432
+ it { should have_many(:tasks) }
433
+ it { should_not belong_to(:task) }
434
+ it { should_not have_one(:task) }
435
+ it { should_not have_and_belong_to_many(:tasks) }
436
+ end
437
+
438
+ describe 'with class name option' do
439
+ before(:each){ define_model :super_task, :project_id => :integer }
440
+
441
+ it { should define_and_validate.class_name('Task') }
442
+ it { should define_and_validate(:class_name => 'SuperTask').class_name('SuperTask') }
443
+
444
+ it { should_not define_and_validate.class_name('SuperTask') }
445
+ it { should_not define_and_validate(:class_name => 'SuperTask').class_name('Task') }
446
+ end
447
+
448
+ describe 'with foreign_key option' do
449
+ it { should define_and_validate.foreign_key(:project_id) }
450
+ it { should_not define_and_validate.foreign_key(:association_id) }
451
+
452
+ # Checks whether fk exists or not
453
+ it { should define_and_validate(:foreign_key => :association_id,
454
+ :association_columns => { :association_id => :integer }).foreign_key(:association_id) }
455
+
456
+ it { should_not define_and_validate(:foreign_key => :association_id).foreign_key(:association_id) }
457
+ it { should_not define_and_validate(:association_columns => { :association_id => :integer }).foreign_key(:association_id) }
458
+ end
459
+
460
+ describe 'with dependent option' do
461
+ it { should define_and_validate(:dependent => :delete_all).dependent(:delete_all) }
462
+ it { should define_and_validate(:dependent => :destroy).dependent(:destroy) }
463
+
464
+ it { should_not define_and_validate(:dependent => :delete_all).dependent(:destroy) }
465
+ it { should_not define_and_validate(:dependent => :destroy).dependent(:delete_all) }
466
+ end
467
+
468
+ describe 'with through option' do
469
+ it { should define_and_validate(:through => :project_tasks) }
470
+ it { should define_and_validate(:through => :project_tasks).through(:project_tasks) }
471
+
472
+ it { should_not define_and_validate(:through => :project_tasks).through(:something) }
473
+ it { should_not define_and_validate(:through => :project_tasks, :skip_through => true).through(:project_tasks) }
474
+ end
475
+
476
+ describe 'with source option' do
477
477
  it { should define_and_validate(:through => :project_tasks, :source => :todo).source(:todo) }
478
- it { should_not define_and_validate(:through => :project_tasks, :source => :todo).source(:task) }
479
- end
480
-
481
- create_optional_boolean_specs(:uniq, self)
482
- create_optional_boolean_specs(:readonly, self)
483
- create_optional_boolean_specs(:validate, self)
484
- create_optional_boolean_specs(:autosave, self) if RAILS_VERSION =~ /^2.3/
485
- end
486
-
487
- describe 'macros' do
488
- before(:each){ define_and_validate(:through => :project_tasks, :readonly => true, :validate => true) }
489
-
490
- should_have_many :tasks
491
- should_have_many :tasks, :readonly => true
492
- should_have_many :tasks, :validate => true
478
+ it { should_not define_and_validate(:through => :project_tasks, :source => :todo).source(:task) }
479
+ end
480
+
481
+ create_optional_boolean_specs(:uniq, self)
482
+ create_optional_boolean_specs(:readonly, self)
483
+ create_optional_boolean_specs(:validate, self)
484
+ create_optional_boolean_specs(:autosave, self) if RAILS_VERSION =~ /^2.3/
485
+ end
486
+
487
+ describe 'macros' do
488
+ before(:each){ define_and_validate(:through => :project_tasks, :readonly => true, :validate => true) }
489
+
490
+ should_have_many :tasks
491
+ should_have_many :tasks, :readonly => true
492
+ should_have_many :tasks, :validate => true
493
493
  should_have_many :tasks, :through => :project_tasks
494
494
 
495
495
  should_have_many :tasks do |m|
496
496
  m.readonly
497
497
  m.validate
498
498
  m.through = :project_tasks
499
- end
500
-
501
- should_not_have_many :tasks, :readonly => false
502
- should_not_have_many :tasks, :validate => false
503
- should_not_have_many :tasks, :through => :another_thing
504
- end
505
- end
506
-
507
- describe 'have_one' do
508
-
509
- # Defines a model, create a validation and returns a raw matcher
510
- def define_and_validate(options={})
511
- columns = options.delete(:association_columns) || { :manager_id => :integer, :project_id => :integer, :boss_id => :integer }
499
+ end
500
+
501
+ should_not_have_many :tasks, :readonly => false
502
+ should_not_have_many :tasks, :validate => false
503
+ should_not_have_many :tasks, :through => :another_thing
504
+ end
505
+ end
506
+
507
+ describe 'have_one' do
508
+
509
+ # Defines a model, create a validation and returns a raw matcher
510
+ def define_and_validate(options={})
511
+ columns = options.delete(:association_columns) || { :manager_id => :integer, :project_id => :integer, :boss_id => :integer }
512
512
  define_model :manager, columns
513
- define_model :boss, columns
514
-
515
- define_model :project_manager, columns do
516
- belongs_to :manager
513
+ define_model :boss, columns
514
+
515
+ define_model :project_manager, columns do
516
+ belongs_to :manager
517
517
  belongs_to :project
518
- belongs_to :boss
519
- end unless options.delete(:skip_source)
520
-
518
+ belongs_to :boss
519
+ end unless options.delete(:skip_source)
520
+
521
521
  @model = define_model :project, options.delete(:model_columns) || {} do
522
- has_many :project_managers unless options.delete(:skip_through)
522
+ has_many :project_managers unless options.delete(:skip_through)
523
523
  has_one :manager, options
524
- has_one :unknown
525
- end
526
-
527
- have_one :manager
528
- end
529
-
530
- describe 'messages' do
531
- it 'should contain a description' do
532
- matcher = define_and_validate
533
- matcher.description.should == 'have one manager'
534
-
535
- matcher.class_name('Manager')
536
- matcher.description.should == 'have one manager with class name "Manager"'
537
-
538
- matcher.foreign_key('manager_id')
539
- matcher.description.should == 'have one manager with class name "Manager" and with foreign key "manager_id"'
540
- end
541
-
542
- it 'should set association_exists? message' do
543
- define_and_validate
544
- matcher = have_one('whatever')
545
- matcher.matches?(@model)
546
- matcher.failure_message.should == 'Expected Project records have one whatever, but the association does not exist'
547
- end
524
+ has_one :unknown
525
+ end
526
+
527
+ have_one :manager
528
+ end
529
+
530
+ describe 'messages' do
531
+ it 'should contain a description' do
532
+ matcher = define_and_validate
533
+ matcher.description.should == 'have one manager'
534
+
535
+ matcher.class_name('Manager')
536
+ matcher.description.should == 'have one manager with class name "Manager"'
537
+
538
+ matcher.foreign_key('manager_id')
539
+ matcher.description.should == 'have one manager with class name "Manager" and with foreign key "manager_id"'
540
+ end
541
+
542
+ it 'should set association_exists? message' do
543
+ define_and_validate
544
+ matcher = have_one('whatever')
545
+ matcher.matches?(@model)
546
+ matcher.failure_message.should == 'Expected Project records have one whatever, but the association does not exist'
547
+ end
548
548
 
549
549
  it 'should set klass_exists? message' do
550
- define_and_validate
551
- matcher = have_one('unknown')
552
- matcher.matches?(@model)
550
+ define_and_validate
551
+ matcher = have_one('unknown')
552
+ matcher.matches?(@model)
553
553
  matcher.failure_message.should == 'Expected Project records have one unknown, but the association class does not exist'
554
554
  end
555
-
556
- it 'should set macro_matches? message' do
557
- define_and_validate
558
- matcher = belong_to('manager')
559
- matcher.matches?(@model)
560
- matcher.failure_message.should == 'Expected Project records belong to manager, got Project records have one manager'
561
- end
562
-
563
- it 'should set foreign_key_exists? message' do
564
- matcher = define_and_validate(:association_columns => {})
565
- matcher.matches?(@model)
566
- matcher.failure_message.should == 'Expected foreign key "project_id" to exist on "managers", but does not'
567
- end
568
-
569
- it 'should set through_exists? message' do
570
- matcher = define_and_validate(:through => :project_managers, :skip_through => true)
571
- matcher.through(:project_managers).matches?(@model)
572
- matcher.failure_message.should == 'Expected Project records have one manager through :project_managers, through association does not exist'
573
- end
574
-
575
- it 'should set source_exists? message' do
576
- matcher = define_and_validate(:through => :project_managers, :skip_source => true)
577
- matcher.through(:project_managers).matches?(@model)
578
- matcher.failure_message.should == 'Expected Project records have one manager through :project_managers, source association does not exist'
579
- end
580
-
581
- it 'should set options_matches? message when dependent is given' do
582
- matcher = define_and_validate(:dependent => :destroy)
583
- matcher.dependent(:nullify).matches?(@model)
584
- matcher.failure_message.should == 'Expected Project records have one manager with options {:dependent=>"nullify"}, got {:dependent=>"destroy"}'
585
- end
586
-
587
- it 'should set options_matches? message when source is given' do
588
- matcher = define_and_validate(:through => :project_managers, :source => :boss)
589
- matcher.through(:project_managers).source(:manager).matches?(@model)
555
+
556
+ it 'should set macro_matches? message' do
557
+ define_and_validate
558
+ matcher = belong_to('manager')
559
+ matcher.matches?(@model)
560
+ matcher.failure_message.should == 'Expected Project records belong to manager, got Project records have one manager'
561
+ end
562
+
563
+ it 'should set foreign_key_exists? message' do
564
+ matcher = define_and_validate(:association_columns => {})
565
+ matcher.matches?(@model)
566
+ matcher.failure_message.should == 'Expected foreign key "project_id" to exist on "managers", but does not'
567
+ end
568
+
569
+ it 'should set through_exists? message' do
570
+ matcher = define_and_validate(:through => :project_managers, :skip_through => true)
571
+ matcher.through(:project_managers).matches?(@model)
572
+ matcher.failure_message.should == 'Expected Project records have one manager through :project_managers, through association does not exist'
573
+ end
574
+
575
+ it 'should set source_exists? message' do
576
+ matcher = define_and_validate(:through => :project_managers, :skip_source => true)
577
+ matcher.through(:project_managers).matches?(@model)
578
+ matcher.failure_message.should == 'Expected Project records have one manager through :project_managers, source association does not exist'
579
+ end
580
+
581
+ it 'should set options_matches? message when dependent is given' do
582
+ matcher = define_and_validate(:dependent => :destroy)
583
+ matcher.dependent(:nullify).matches?(@model)
584
+ matcher.failure_message.should == 'Expected Project records have one manager with options {:dependent=>"nullify"}, got {:dependent=>"destroy"}'
585
+ end
586
+
587
+ it 'should set options_matches? message when source is given' do
588
+ matcher = define_and_validate(:through => :project_managers, :source => :boss)
589
+ matcher.through(:project_managers).source(:manager).matches?(@model)
590
590
  matcher.failure_message.should match(/:source=>"manager"/)
591
- matcher.failure_message.should match(/:source=>"boss"/)
592
- end
593
- end
594
-
595
- describe 'matchers' do
596
- describe 'without options' do
597
- before(:each){ define_and_validate }
598
-
591
+ matcher.failure_message.should match(/:source=>"boss"/)
592
+ end
593
+ end
594
+
595
+ describe 'matchers' do
596
+ describe 'without options' do
597
+ before(:each){ define_and_validate }
598
+
599
599
  it { should have_one(:manager) }
600
- it { should_not have_one(:unknown) }
601
- it { should_not belong_to(:manager) }
602
- it { should_not have_many(:managers) }
603
- it { should_not have_and_belong_to_many(:managers) }
604
- end
605
-
606
- describe 'with class name option' do
607
- before(:each){ define_model :super_manager, :project_id => :integer }
608
-
609
- it { should define_and_validate.class_name('Manager') }
610
- it { should define_and_validate(:class_name => 'SuperManager').class_name('SuperManager') }
611
-
612
- it { should_not define_and_validate.class_name('SuperManager') }
613
- it { should_not define_and_validate(:class_name => 'SuperManager').class_name('Manager') }
614
- end
615
-
616
- describe 'with foreign_key option' do
617
- it { should define_and_validate.foreign_key(:project_id) }
618
- it { should_not define_and_validate.foreign_key(:association_id) }
619
-
620
- # Checks whether fk exists or not
621
- it { should define_and_validate(:foreign_key => :association_id,
622
- :association_columns => { :association_id => :integer }).foreign_key(:association_id) }
623
-
624
- it { should_not define_and_validate(:foreign_key => :association_id).foreign_key(:association_id) }
625
- it { should_not define_and_validate(:association_columns => { :association_id => :integer }).foreign_key(:association_id) }
626
- end
627
-
628
- describe 'with dependent option' do
629
- it { should define_and_validate(:dependent => :delete).dependent(:delete) }
630
- it { should define_and_validate(:dependent => :destroy).dependent(:destroy) }
631
-
632
- it { should_not define_and_validate(:dependent => :delete).dependent(:destroy) }
633
- it { should_not define_and_validate(:dependent => :destroy).dependent(:delete) }
634
- end
635
-
636
- describe 'with through option' do
637
- it { should define_and_validate(:through => :project_managers) }
638
- it { should define_and_validate(:through => :project_managers).through(:project_managers) }
639
-
640
- it { should_not define_and_validate(:through => :project_managers).through(:something) }
641
- it { should_not define_and_validate(:through => :project_managers, :skip_through => true).through(:project_managers) }
642
- end
643
-
644
- describe 'with source option' do
600
+ it { should_not have_one(:unknown) }
601
+ it { should_not belong_to(:manager) }
602
+ it { should_not have_many(:managers) }
603
+ it { should_not have_and_belong_to_many(:managers) }
604
+ end
605
+
606
+ describe 'with class name option' do
607
+ before(:each){ define_model :super_manager, :project_id => :integer }
608
+
609
+ it { should define_and_validate.class_name('Manager') }
610
+ it { should define_and_validate(:class_name => 'SuperManager').class_name('SuperManager') }
611
+
612
+ it { should_not define_and_validate.class_name('SuperManager') }
613
+ it { should_not define_and_validate(:class_name => 'SuperManager').class_name('Manager') }
614
+ end
615
+
616
+ describe 'with foreign_key option' do
617
+ it { should define_and_validate.foreign_key(:project_id) }
618
+ it { should_not define_and_validate.foreign_key(:association_id) }
619
+
620
+ # Checks whether fk exists or not
621
+ it { should define_and_validate(:foreign_key => :association_id,
622
+ :association_columns => { :association_id => :integer }).foreign_key(:association_id) }
623
+
624
+ it { should_not define_and_validate(:foreign_key => :association_id).foreign_key(:association_id) }
625
+ it { should_not define_and_validate(:association_columns => { :association_id => :integer }).foreign_key(:association_id) }
626
+ end
627
+
628
+ describe 'with dependent option' do
629
+ it { should define_and_validate(:dependent => :delete).dependent(:delete) }
630
+ it { should define_and_validate(:dependent => :destroy).dependent(:destroy) }
631
+
632
+ it { should_not define_and_validate(:dependent => :delete).dependent(:destroy) }
633
+ it { should_not define_and_validate(:dependent => :destroy).dependent(:delete) }
634
+ end
635
+
636
+ describe 'with through option' do
637
+ it { should define_and_validate(:through => :project_managers) }
638
+ it { should define_and_validate(:through => :project_managers).through(:project_managers) }
639
+
640
+ it { should_not define_and_validate(:through => :project_managers).through(:something) }
641
+ it { should_not define_and_validate(:through => :project_managers, :skip_through => true).through(:project_managers) }
642
+ end
643
+
644
+ describe 'with source option' do
645
645
  it { should define_and_validate(:through => :project_managers, :source => :boss).source(:boss) }
646
- it { should_not define_and_validate(:through => :project_managers, :source => :boss).source(:manager) }
647
- end
648
-
649
- create_optional_boolean_specs(:validate, self)
650
- create_optional_boolean_specs(:autosave, self) if RAILS_VERSION =~ /^2.3/
651
- end
652
-
653
- describe 'macros' do
654
- before(:each){ define_and_validate(:through => :project_managers, :validate => true) }
655
-
656
- should_have_one :manager
657
- should_have_one :manager, :validate => true
646
+ it { should_not define_and_validate(:through => :project_managers, :source => :boss).source(:manager) }
647
+ end
648
+
649
+ create_optional_boolean_specs(:validate, self)
650
+ create_optional_boolean_specs(:autosave, self) if RAILS_VERSION =~ /^2.3/
651
+ end
652
+
653
+ describe 'macros' do
654
+ before(:each){ define_and_validate(:through => :project_managers, :validate => true) }
655
+
656
+ should_have_one :manager
657
+ should_have_one :manager, :validate => true
658
658
  should_have_one :manager, :through => :project_managers
659
659
 
660
660
  should_have_one :manager do |m|
661
661
  m.validate
662
662
  m.through = :project_managers
663
- end
664
-
665
- should_not_have_one :unknown
666
- should_not_have_one :manager, :validate => false
667
- should_not_have_one :manager, :through => :another_thing
668
- end
669
- end
670
-
671
- end
663
+ end
664
+
665
+ should_not_have_one :unknown
666
+ should_not_have_one :manager, :validate => false
667
+ should_not_have_one :manager, :through => :another_thing
668
+ end
669
+ end
670
+
671
+ end