remarkable_activerecord 3.0.4 → 3.0.5
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.
- data/README +7 -3
- data/lib/remarkable_activerecord/base.rb +2 -16
- data/lib/remarkable_activerecord/matchers/association_matcher.rb +61 -47
- data/locale/en.yml +40 -64
- data/spec/association_matcher_spec.rb +85 -85
- metadata +3 -3
data/README
CHANGED
@@ -4,13 +4,17 @@ Remarkable ActiveRecord is a collection of matchers to ActiveRecord. Why use
|
|
4
4
|
Remarkable?
|
5
5
|
|
6
6
|
* The only one with matchers for all ActiveRecord validations, with support to
|
7
|
-
all options;
|
7
|
+
all options (except :on and the option :with in validates_format_of);
|
8
8
|
|
9
9
|
* Matchers for all ActiveRecord associations. The only one which supports all
|
10
10
|
these options:
|
11
11
|
|
12
|
-
:through, :
|
13
|
-
:readonly, :validate, :autosave, :counter_cache, :polymorphic
|
12
|
+
:through, :source, :source_type, :class_name, :foreign_key, :dependent,
|
13
|
+
:join_table, :uniq, :readonly, :validate, :autosave, :counter_cache, :polymorphic
|
14
|
+
|
15
|
+
Plus SQL options:
|
16
|
+
|
17
|
+
:select, :conditions, :include, :group, :having, :order, :limit, :offset
|
14
18
|
|
15
19
|
Besides in Remarkable 3.0 matchers became much smarter. Whenever :join_table
|
16
20
|
or :through is given as option, it checks if the given table exists. Whenever
|
@@ -60,14 +60,7 @@ module Remarkable
|
|
60
60
|
# to be used as default.
|
61
61
|
#
|
62
62
|
def allow_nil?(message_key=:message) #:nodoc:
|
63
|
-
|
64
|
-
|
65
|
-
unless valid
|
66
|
-
default = Remarkable.t "remarkable.active_record.allow_nil", default_i18n_options.except(:scope).merge(options)
|
67
|
-
return false, options.merge(:default => default)
|
68
|
-
end
|
69
|
-
|
70
|
-
true
|
63
|
+
assert_good_or_bad_if_key(:allow_nil, nil, message_key)
|
71
64
|
end
|
72
65
|
|
73
66
|
# Default allow_blank? validation. It accepts the message_key which is
|
@@ -77,14 +70,7 @@ module Remarkable
|
|
77
70
|
# to be used as default.
|
78
71
|
#
|
79
72
|
def allow_blank?(message_key=:message) #:nodoc:
|
80
|
-
|
81
|
-
|
82
|
-
unless valid
|
83
|
-
default = Remarkable.t "remarkable.active_record.allow_blank", default_i18n_options.except(:scope).merge(options)
|
84
|
-
return false, options.merge(:default => default)
|
85
|
-
end
|
86
|
-
|
87
|
-
true
|
73
|
+
assert_good_or_bad_if_key(:allow_blank, '', message_key)
|
88
74
|
end
|
89
75
|
|
90
76
|
# Shortcut for assert_good_value.
|
@@ -4,15 +4,13 @@ module Remarkable
|
|
4
4
|
class AssociationMatcher < Remarkable::ActiveRecord::Base #:nodoc:
|
5
5
|
arguments :macro, :collection => :associations, :as => :association
|
6
6
|
|
7
|
-
optionals :through, :class_name, :foreign_key, :dependent, :join_table, :as
|
7
|
+
optionals :through, :source, :source_type, :class_name, :foreign_key, :dependent, :join_table, :as
|
8
|
+
optionals :select, :conditions, :include, :group, :having, :order, :limit, :offset, :finder_sql, :counter_sql
|
8
9
|
optionals :uniq, :readonly, :validate, :autosave, :polymorphic, :counter_cache, :default => true
|
9
10
|
|
10
|
-
|
11
|
-
ASSOCIATION_OPTIONS = self.matcher_optionals
|
12
|
-
|
13
|
-
collection_assertions :association_exists?, :macro_matches?, :through_exists?,
|
11
|
+
collection_assertions :association_exists?, :macro_matches?, :through_exists?, :source_exists?,
|
14
12
|
:join_table_exists?, :foreign_key_exists?, :polymorphic_exists?,
|
15
|
-
:counter_cache_exists?
|
13
|
+
:counter_cache_exists?, :options_match?
|
16
14
|
|
17
15
|
protected
|
18
16
|
|
@@ -25,16 +23,22 @@ module Remarkable
|
|
25
23
|
end
|
26
24
|
|
27
25
|
def through_exists?
|
28
|
-
return true unless @options.key?(:through)
|
29
|
-
|
26
|
+
return true unless @options.key?(:through)
|
27
|
+
reflection.through_reflection rescue false
|
28
|
+
end
|
29
|
+
|
30
|
+
def source_exists?
|
31
|
+
return true unless @options.key?(:through)
|
32
|
+
reflection.source_reflection rescue false
|
30
33
|
end
|
31
34
|
|
32
35
|
def join_table_exists?
|
33
|
-
return true unless
|
34
|
-
::ActiveRecord::Base.connection.tables.include?(
|
36
|
+
return true unless reflection.macro == :has_and_belongs_to_many
|
37
|
+
::ActiveRecord::Base.connection.tables.include?(reflection.options[:join_table])
|
35
38
|
end
|
36
39
|
|
37
|
-
def foreign_key_exists?
|
40
|
+
def foreign_key_exists?
|
41
|
+
return true unless foreign_key_table
|
38
42
|
table_has_column?(foreign_key_table, reflection_foreign_key)
|
39
43
|
end
|
40
44
|
|
@@ -47,18 +51,18 @@ module Remarkable
|
|
47
51
|
return true unless @options[:counter_cache]
|
48
52
|
table_has_column?(reflection.klass.table_name, reflection.counter_cache_column.to_s)
|
49
53
|
end
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
54
|
+
|
55
|
+
def options_match?
|
56
|
+
actual_options = {}
|
57
|
+
|
58
|
+
@options.keys.each do |key|
|
59
|
+
method = :"reflection_#{key}"
|
60
|
+
|
61
|
+
@options[key] = @options[key].to_s
|
62
|
+
actual_options[key] = (respond_to?(method, true) ? send(method) : reflection.options[key]).to_s
|
63
|
+
end
|
64
|
+
|
65
|
+
return @options == actual_options, :actual => actual_options.inspect
|
62
66
|
end
|
63
67
|
|
64
68
|
private
|
@@ -76,27 +80,25 @@ module Remarkable
|
|
76
80
|
reflection.primary_key_name.to_s
|
77
81
|
end
|
78
82
|
|
79
|
-
def reflection_join_table
|
80
|
-
(reflection.options[:join_table] || reflection.options[:through]).to_s
|
81
|
-
end
|
82
|
-
|
83
|
-
def has_join_table?
|
84
|
-
reflection.options.key?(:through) || reflection.macro == :has_and_belongs_to_many
|
85
|
-
end
|
86
|
-
|
87
83
|
def table_has_column?(table_name, column)
|
88
84
|
::ActiveRecord::Base.connection.columns(table_name, 'Remarkable column retrieval').any?{|c| c.name == column }
|
89
85
|
end
|
90
86
|
|
87
|
+
# In through we don't check the foreign_key, because it's spread
|
88
|
+
# accross the through and the source reflection which should be tested
|
89
|
+
# with their own macros.
|
90
|
+
#
|
91
91
|
# In cases a join table exists (has_and_belongs_to_many and through
|
92
92
|
# associations), we check the foreign key in the join table.
|
93
93
|
#
|
94
94
|
# On belongs to, the foreign_key is in the subject class table and in
|
95
95
|
# other cases it's on the reflection class table.
|
96
96
|
#
|
97
|
-
def foreign_key_table
|
98
|
-
if
|
99
|
-
|
97
|
+
def foreign_key_table
|
98
|
+
if reflection.options.key?(:through)
|
99
|
+
nil
|
100
|
+
elsif reflection.macro == :has_and_belongs_to_many
|
101
|
+
reflection.options[:join_table]
|
100
102
|
elsif reflection.macro == :belongs_to
|
101
103
|
subject_class.table_name
|
102
104
|
else
|
@@ -105,7 +107,7 @@ module Remarkable
|
|
105
107
|
end
|
106
108
|
|
107
109
|
def interpolation_options
|
108
|
-
options = { :macro => Remarkable.t(@macro, :scope => matcher_i18n_scope, :default => @macro.to_s) }
|
110
|
+
options = { :macro => Remarkable.t(@macro, :scope => matcher_i18n_scope, :default => @macro.to_s), :options => @options.inspect }
|
109
111
|
|
110
112
|
if @subject && reflection
|
111
113
|
options.merge!(
|
@@ -114,14 +116,10 @@ module Remarkable
|
|
114
116
|
:reflection_table => reflection.klass.table_name.inspect,
|
115
117
|
:foreign_key_table => foreign_key_table.inspect,
|
116
118
|
:polymorphic_column => reflection_foreign_key.sub(/_id$/, '_type').inspect,
|
117
|
-
:counter_cache_column => reflection.counter_cache_column.to_s.inspect
|
119
|
+
:counter_cache_column => reflection.counter_cache_column.to_s.inspect,
|
120
|
+
:join_table => reflection.options[:join_table].inspect,
|
121
|
+
:foreign_key => reflection_foreign_key.inspect
|
118
122
|
) rescue nil # rescue to allow specs to run properly
|
119
|
-
|
120
|
-
ASSOCIATION_OPTIONS.each do |option|
|
121
|
-
value_to_compare = respond_to?(:"reflection_#{option}", true) ? send(:"reflection_#{option}") : reflection.options[option].to_s
|
122
|
-
options[:"actual_#{option}"] = value_to_compare.inspect
|
123
|
-
end
|
124
|
-
|
125
123
|
end
|
126
124
|
|
127
125
|
options
|
@@ -143,6 +141,9 @@ module Remarkable
|
|
143
141
|
# It also checks if the column actually exists in the table.
|
144
142
|
# * <tt>:polymorphic</tt> - if the association should be polymorphic or not.
|
145
143
|
# When true it also checks for the association_type column in the subject table.
|
144
|
+
#
|
145
|
+
# Plus all supported sql conditions options: :select, :conditions, :order,
|
146
|
+
# :limit, :offset, :include, :group, :having.
|
146
147
|
#
|
147
148
|
# == Examples
|
148
149
|
#
|
@@ -164,7 +165,10 @@ module Remarkable
|
|
164
165
|
# * <tt>:uniq</tt> - checks wether uniq is true or false.
|
165
166
|
# * <tt>:readonly</tt> - checks wether readonly is true or false.
|
166
167
|
# * <tt>:validate</tt> - checks wether validate is true or false.
|
167
|
-
# * <tt>:autosave</tt> - checks wether autosave is true or false.
|
168
|
+
# * <tt>:autosave</tt> - checks wether autosave is true or false.
|
169
|
+
#
|
170
|
+
# Plus all supported sql conditions options: :select, :conditions, :order,
|
171
|
+
# :limit, :offset, :include, :group, :having.
|
168
172
|
#
|
169
173
|
# == Examples
|
170
174
|
#
|
@@ -183,14 +187,19 @@ module Remarkable
|
|
183
187
|
#
|
184
188
|
# * <tt>:class_name</tt> - the expected associted class name.
|
185
189
|
# * <tt>:through</tt> - the expected join model which to perform the query.
|
186
|
-
# It also checks if the through table exists.
|
190
|
+
# It also checks if the through table exists.
|
191
|
+
# * <tt>:source</tt> - the source of the through association.
|
192
|
+
# * <tt>:source_type</tt> - the source type of the through association.
|
187
193
|
# * <tt>:foreign_key</tt> - the expected foreign key in the associated table.
|
188
194
|
# When used with :through, it will check for the foreign key in the join table.
|
189
195
|
# * <tt>:dependent</tt> - the expected dependent value for the association.
|
190
196
|
# * <tt>:uniq</tt> - checks wether uniq is true or false.
|
191
197
|
# * <tt>:readonly</tt> - checks wether readonly is true or false.
|
192
198
|
# * <tt>:validate</tt> - checks wether validate is true or false.
|
193
|
-
# * <tt>:autosave</tt> - checks wether autosave is true or false.
|
199
|
+
# * <tt>:autosave</tt> - checks wether autosave is true or false.
|
200
|
+
#
|
201
|
+
# Plus all supported sql conditions options: :select, :conditions, :order,
|
202
|
+
# :limit, :offset, :include, :group, :having.
|
194
203
|
#
|
195
204
|
# == Examples
|
196
205
|
#
|
@@ -214,12 +223,17 @@ module Remarkable
|
|
214
223
|
#
|
215
224
|
# * <tt>:class_name</tt> - the expected associted class name.
|
216
225
|
# * <tt>:through</tt> - the expected join model which to perform the query.
|
217
|
-
# It also checks if the through table exists.
|
226
|
+
# It also checks if the through table exists.
|
227
|
+
# * <tt>:source</tt> - the source of the through association.
|
228
|
+
# * <tt>:source_type</tt> - the source type of the through association.
|
218
229
|
# * <tt>:foreign_key</tt> - the expected foreign key in the associated table.
|
219
230
|
# When used with :through, it will check for the foreign key in the join table.
|
220
231
|
# * <tt>:dependent</tt> - the expected dependent value for the association.
|
221
232
|
# * <tt>:validate</tt> - checks wether validate is true or false.
|
222
|
-
# * <tt>:autosave</tt> - checks wether autosave is true or false.
|
233
|
+
# * <tt>:autosave</tt> - checks wether autosave is true or false.
|
234
|
+
#
|
235
|
+
# Plus all supported sql conditions options: :select, :conditions, :order,
|
236
|
+
# :limit, :offset, :include, :group, :having.
|
223
237
|
#
|
224
238
|
# == Examples
|
225
239
|
#
|
data/locale/en.yml
CHANGED
@@ -1,20 +1,21 @@
|
|
1
1
|
en:
|
2
2
|
remarkable:
|
3
|
-
active_record:
|
4
|
-
|
5
|
-
|
3
|
+
active_record:
|
4
|
+
expectations:
|
5
|
+
allow_nil: "{{subject_name}} to {{not}}allow nil values for {{attribute}}"
|
6
|
+
allow_blank: "{{subject_name}} to {{not}}allow blank values for {{attribute}}"
|
7
|
+
optionals:
|
8
|
+
allow_nil:
|
9
|
+
positive: "allowing nil values"
|
10
|
+
negative: "not allowing nil values"
|
11
|
+
allow_blank:
|
12
|
+
positive: "allowing blank values"
|
13
|
+
negative: "not allowing blank values"
|
6
14
|
|
7
15
|
allow_values_for:
|
8
16
|
description: "allow {{in}} as values for {{attributes}}"
|
9
17
|
expectations:
|
10
18
|
is_valid: "{{subject_name}} to be valid when {{attribute}} is set to {{value}}"
|
11
|
-
optionals:
|
12
|
-
allow_nil:
|
13
|
-
positive: "allowing nil values"
|
14
|
-
negative: "not allowing nil values"
|
15
|
-
allow_blank:
|
16
|
-
positive: "allowing blank values"
|
17
|
-
negative: "not allowing blank values"
|
18
19
|
|
19
20
|
allow_mass_assignment_of:
|
20
21
|
description: "allow mass assignment of {{attributes}}"
|
@@ -31,26 +32,20 @@ en:
|
|
31
32
|
expectations:
|
32
33
|
association_exists: "{{subject_name}} records {{macro}} {{association}}, got no association"
|
33
34
|
macro_matches: "{{subject_name}} records {{macro}} {{association}}, got {{subject_name}} records {{actual_macro}} {{association}}"
|
34
|
-
through_exists: "{{subject_name}} records {{macro}} {{association}} through {{through}}, through association does not exist"
|
35
|
-
|
36
|
-
|
35
|
+
through_exists: "{{subject_name}} records {{macro}} {{association}} through {{through}}, through association does not exist"
|
36
|
+
source_exists: "{{subject_name}} records {{macro}} {{association}} through {{through}}, source association does not exist"
|
37
|
+
join_table_exists: "join table {{join_table}} to exist, but does not"
|
38
|
+
foreign_key_exists: "foreign key {{foreign_key}} to exist on {{foreign_key_table}}, but does not"
|
37
39
|
polymorphic_exists: "{{subject_table}} to have {{polymorphic_column}} as column, but does not"
|
38
|
-
counter_cache_exists: "{{reflection_table}} to have {{counter_cache_column}} as column, but does not"
|
39
|
-
|
40
|
-
class_name_matches: "{{association}} association with class name {{class_name}}, got {{actual_class_name}}"
|
41
|
-
foreign_key_matches: "{{association}} association with foreign key {{foreign_key}}, got {{actual_foreign_key}}"
|
42
|
-
dependent_matches: "{{association}} association with dependent {{dependent}}, got {{actual_dependent}}"
|
43
|
-
join_table_matches: "{{association}} association with join table {{join_table}}, got {{actual_join_table}}"
|
44
|
-
uniq_matches: "{{association}} association with uniq equals to {{uniq}}, got {{actual_uniq}}"
|
45
|
-
readonly_matches: "{{association}} association with readonly equals to {{readonly}}, got {{actual_readonly}}"
|
46
|
-
validate_matches: "{{association}} association with validate equals to {{validate}}, got {{actual_validate}}"
|
47
|
-
autosave_matches: "{{association}} association with autosave equals to {{autosave}}, got {{actual_autosave}}"
|
48
|
-
polymorphic_matches: "{{association}} association with polymorphic equals to {{polymorphic}}, got {{actual_polymorphic}}"
|
49
|
-
as_matches: "{{association}} association with polymorphic interface {{as}}, got {{actual_as}}"
|
50
|
-
counter_cache_matches: "{{association}} association with counter cache {{counter_cache}}, got {{actual_counter_cache}}"
|
40
|
+
counter_cache_exists: "{{reflection_table}} to have {{counter_cache_column}} as column, but does not"
|
41
|
+
options_match: "{{subject_name}} records {{macro}} {{association}} with options {{options}}, got {{actual}}"
|
51
42
|
optionals:
|
52
43
|
through:
|
53
|
-
positive: "through {{value}}"
|
44
|
+
positive: "through {{value}}"
|
45
|
+
source:
|
46
|
+
positive: "with source {{inspect}}"
|
47
|
+
source_type:
|
48
|
+
positive: "with source type {{inspect}}"
|
54
49
|
class_name:
|
55
50
|
positive: "with class name {{inspect}}"
|
56
51
|
foreign_key:
|
@@ -75,7 +70,23 @@ en:
|
|
75
70
|
positive: "through the polymorphic interface {{inspect}}"
|
76
71
|
counter_cache:
|
77
72
|
positive: "with counter cache {{inspect}}"
|
78
|
-
negative: "without counter cache"
|
73
|
+
negative: "without counter cache"
|
74
|
+
select:
|
75
|
+
positive: "selecting {{inspect}}"
|
76
|
+
conditions:
|
77
|
+
positive: "with conditions {{inspect}}"
|
78
|
+
include:
|
79
|
+
positive: "including {{inspect}}"
|
80
|
+
group:
|
81
|
+
positive: "grouping by {{inspect}}"
|
82
|
+
having:
|
83
|
+
positive: "having {{inspect}}"
|
84
|
+
order:
|
85
|
+
positive: "with order {{inspect}}"
|
86
|
+
limit:
|
87
|
+
positive: "with limit {{inspect}}"
|
88
|
+
offset:
|
89
|
+
positive: "with offset {{inspect}}"
|
79
90
|
|
80
91
|
have_column:
|
81
92
|
description: "have column(s) named {{columns}}"
|
@@ -126,9 +137,6 @@ en:
|
|
126
137
|
optionals:
|
127
138
|
accept:
|
128
139
|
positive: "with value {{inspect}}"
|
129
|
-
allow_nil:
|
130
|
-
positive: "allowing nil values"
|
131
|
-
negative: "not allowing nil values"
|
132
140
|
|
133
141
|
validate_associated:
|
134
142
|
description: "require associated {{associations}} to be valid"
|
@@ -146,26 +154,12 @@ en:
|
|
146
154
|
expectations:
|
147
155
|
is_valid: "{{subject_name}} to be valid when {{attribute}} is set to {{value}}"
|
148
156
|
is_invalid: "{{subject_name}} to be invalid when {{attribute}} is set to {{value}}"
|
149
|
-
optionals:
|
150
|
-
allow_nil:
|
151
|
-
positive: "allowing nil values"
|
152
|
-
negative: "not allowing nil values"
|
153
|
-
allow_blank:
|
154
|
-
positive: "allowing blank values"
|
155
|
-
negative: "not allowing blank values"
|
156
157
|
|
157
158
|
validate_inclusion_of:
|
158
159
|
description: "ensure inclusion of {{attributes}} in {{in}}"
|
159
160
|
expectations:
|
160
161
|
is_valid: "{{subject_name}} to be valid when {{attribute}} is set to {{value}}"
|
161
162
|
is_invalid: "{{subject_name}} to be invalid when {{attribute}} is set to {{value}}"
|
162
|
-
optionals:
|
163
|
-
allow_nil:
|
164
|
-
positive: "allowing nil values"
|
165
|
-
negative: "not allowing nil values"
|
166
|
-
allow_blank:
|
167
|
-
positive: "allowing blank values"
|
168
|
-
negative: "not allowing blank values"
|
169
163
|
|
170
164
|
validate_length_of:
|
171
165
|
description: "ensure length of {{attributes}}"
|
@@ -183,12 +177,6 @@ en:
|
|
183
177
|
positive: "is minimum {{inspect}} characters"
|
184
178
|
is:
|
185
179
|
positive: "is equal to {{inspect}} characters"
|
186
|
-
allow_nil:
|
187
|
-
positive: "allowing nil values"
|
188
|
-
negative: "not allowing nil values"
|
189
|
-
allow_blank:
|
190
|
-
positive: "allowing blank values"
|
191
|
-
negative: "not allowing blank values"
|
192
180
|
|
193
181
|
validate_numericality_of:
|
194
182
|
description: "ensure numericality of {{attributes}}"
|
@@ -217,12 +205,6 @@ en:
|
|
217
205
|
positive: "is less than or equal to {{inspect}}"
|
218
206
|
greater_than_or_equal_to:
|
219
207
|
positive: "is greater than or equal to {{inspect}}"
|
220
|
-
allow_nil:
|
221
|
-
positive: "allowing nil values"
|
222
|
-
negative: "not allowing nil values"
|
223
|
-
allow_blank:
|
224
|
-
positive: "allowing blank values"
|
225
|
-
negative: "not allowing blank values"
|
226
208
|
|
227
209
|
validate_presence_of:
|
228
210
|
description: "require {{attributes}} to be set"
|
@@ -242,10 +224,4 @@ en:
|
|
242
224
|
case_sensitive:
|
243
225
|
positive: "case sensitive"
|
244
226
|
negative: "case insensitive"
|
245
|
-
|
246
|
-
positive: "allowing nil values"
|
247
|
-
negative: "not allowing nil values"
|
248
|
-
allow_blank:
|
249
|
-
positive: "allowing blank values"
|
250
|
-
negative: "not allowing blank values"
|
251
|
-
|
227
|
+
|
@@ -75,36 +75,16 @@ describe 'association_matcher' do
|
|
75
75
|
matcher.failure_message.should == 'Expected "companies" to have "projects_count" as column, but does not'
|
76
76
|
end
|
77
77
|
|
78
|
-
it 'should set
|
79
|
-
matcher = define_and_validate(:validate => false)
|
80
|
-
matcher.validate.matches?(@model)
|
81
|
-
matcher.failure_message.should == 'Expected company association with validate equals to true, got "false"'
|
82
|
-
end
|
83
|
-
|
84
|
-
it 'should set readonly_matches? message' do
|
85
|
-
matcher = define_and_validate(:readonly => false)
|
86
|
-
matcher.readonly.matches?(@model)
|
87
|
-
matcher.failure_message.should == 'Expected company association with readonly equals to true, got "false"'
|
88
|
-
end
|
89
|
-
|
90
|
-
if RAILS_VERSION =~ /^2.3/
|
91
|
-
it 'should set autosave_matches? message' do
|
92
|
-
matcher = define_and_validate(:autosave => false)
|
93
|
-
matcher.autosave.matches?(@model)
|
94
|
-
matcher.failure_message.should == 'Expected company association with autosave equals to true, got "false"'
|
95
|
-
end
|
96
|
-
end
|
97
|
-
|
98
|
-
it 'should set polymorphic_matches? message' do
|
78
|
+
it 'should set options_matches? message when polymorphic is given' do
|
99
79
|
matcher = define_and_validate(:polymorphic => false)
|
100
80
|
matcher.polymorphic.matches?(@model)
|
101
|
-
matcher.failure_message.should == 'Expected
|
81
|
+
matcher.failure_message.should == 'Expected Project records belong to company with options {:polymorphic=>"true"}, got {:polymorphic=>"false"}'
|
102
82
|
end
|
103
83
|
|
104
|
-
it 'should set
|
84
|
+
it 'should set options_matches? message when counter_cache is given' do
|
105
85
|
matcher = define_and_validate(:counter_cache => true)
|
106
86
|
matcher.counter_cache(false).matches?(@model)
|
107
|
-
matcher.failure_message.should == 'Expected company
|
87
|
+
matcher.failure_message.should == 'Expected Project records belong to company with options {:counter_cache=>"false"}, got {:counter_cache=>"true"}'
|
108
88
|
end
|
109
89
|
end
|
110
90
|
|
@@ -244,31 +224,11 @@ describe 'association_matcher' do
|
|
244
224
|
matcher.failure_message.should == 'Expected foreign key "project_id" to exist on "labels_projects", but does not'
|
245
225
|
end
|
246
226
|
|
247
|
-
it 'should set
|
248
|
-
matcher = define_and_validate(:validate => false)
|
249
|
-
matcher.validate.matches?(@model)
|
250
|
-
matcher.failure_message.should == 'Expected labels association with validate equals to true, got "false"'
|
251
|
-
end
|
252
|
-
|
253
|
-
it 'should set readonly_matches? message' do
|
254
|
-
matcher = define_and_validate(:readonly => false)
|
255
|
-
matcher.readonly.matches?(@model)
|
256
|
-
matcher.failure_message.should == 'Expected labels association with readonly equals to true, got "false"'
|
257
|
-
end
|
258
|
-
|
259
|
-
if RAILS_VERSION =~ /^2.3/
|
260
|
-
it 'should set autosave_matches? message' do
|
261
|
-
matcher = define_and_validate(:autosave => false)
|
262
|
-
matcher.autosave.matches?(@model)
|
263
|
-
matcher.failure_message.should == 'Expected labels association with autosave equals to true, got "false"'
|
264
|
-
end
|
265
|
-
end
|
266
|
-
|
267
|
-
it 'should set uniq_matches? message' do
|
227
|
+
it 'should set options_matches? message' do
|
268
228
|
matcher = define_and_validate(:uniq => false)
|
269
229
|
matcher.uniq.matches?(@model)
|
270
|
-
matcher.failure_message.should == 'Expected
|
271
|
-
end
|
230
|
+
matcher.failure_message.should == 'Expected Project records have and belong to many labels with options {:uniq=>"true"}, got {:uniq=>"false"}'
|
231
|
+
end
|
272
232
|
end
|
273
233
|
|
274
234
|
describe 'matchers' do
|
@@ -348,17 +308,19 @@ describe 'association_matcher' do
|
|
348
308
|
|
349
309
|
# Defines a model, create a validation and returns a raw matcher
|
350
310
|
def define_and_validate(options={})
|
351
|
-
columns = options.delete(:association_columns) || { :task_id => :integer, :project_id => :integer }
|
352
|
-
define_model :task, columns
|
311
|
+
columns = options.delete(:association_columns) || { :task_id => :integer, :project_id => :integer, :todo_id => :integer }
|
312
|
+
define_model :task, columns
|
313
|
+
define_model :todo, columns
|
353
314
|
|
354
315
|
define_model :project_task, columns do
|
355
316
|
belongs_to :task
|
356
|
-
belongs_to :project
|
357
|
-
|
317
|
+
belongs_to :project
|
318
|
+
belongs_to :todo
|
319
|
+
end unless options.delete(:skip_source)
|
358
320
|
|
359
|
-
@model = define_model :project, options.delete(:model_columns) || {} do
|
321
|
+
@model = define_model :project, options.delete(:model_columns) || {} do
|
322
|
+
has_many :project_tasks unless options.delete(:skip_through)
|
360
323
|
has_many :tasks, options
|
361
|
-
has_many :project_tasks
|
362
324
|
end
|
363
325
|
|
364
326
|
have_many :tasks
|
@@ -403,15 +365,28 @@ describe 'association_matcher' do
|
|
403
365
|
end
|
404
366
|
|
405
367
|
it 'should set through_exists? message' do
|
406
|
-
matcher = define_and_validate(:through =>
|
407
|
-
matcher.through(:
|
408
|
-
matcher.failure_message.should == 'Expected Project records have many tasks through :
|
409
|
-
end
|
410
|
-
|
411
|
-
it 'should set
|
412
|
-
matcher = define_and_validate(:through =>
|
368
|
+
matcher = define_and_validate(:through => :project_tasks, :skip_through => true)
|
369
|
+
matcher.through(:project_tasks).matches?(@model)
|
370
|
+
matcher.failure_message.should == 'Expected Project records have many tasks through :project_tasks, through association does not exist'
|
371
|
+
end
|
372
|
+
|
373
|
+
it 'should set source_exists? message' do
|
374
|
+
matcher = define_and_validate(:through => :project_tasks, :skip_source => true)
|
413
375
|
matcher.through(:project_tasks).matches?(@model)
|
414
|
-
matcher.failure_message.should == 'Expected
|
376
|
+
matcher.failure_message.should == 'Expected Project records have many tasks through :project_tasks, source association does not exist'
|
377
|
+
end
|
378
|
+
|
379
|
+
it 'should set options_matches? message when dependent is given' do
|
380
|
+
matcher = define_and_validate(:dependent => :destroy)
|
381
|
+
matcher.dependent(:nullify).matches?(@model)
|
382
|
+
matcher.failure_message.should == 'Expected Project records have many tasks with options {:dependent=>"nullify"}, got {:dependent=>"destroy"}'
|
383
|
+
end
|
384
|
+
|
385
|
+
it 'should set options_matches? message when source is given' do
|
386
|
+
matcher = define_and_validate(:through => :project_tasks, :source => :todo)
|
387
|
+
matcher.through(:project_tasks).source(:task).matches?(@model)
|
388
|
+
matcher.failure_message.should match(/:source=>"task"/)
|
389
|
+
matcher.failure_message.should match(/:source=>"todo"/)
|
415
390
|
end
|
416
391
|
end
|
417
392
|
|
@@ -456,11 +431,16 @@ describe 'association_matcher' do
|
|
456
431
|
end
|
457
432
|
|
458
433
|
describe 'with through option' do
|
459
|
-
it { should define_and_validate(:through =>
|
460
|
-
it { should define_and_validate(:through =>
|
434
|
+
it { should define_and_validate(:through => :project_tasks) }
|
435
|
+
it { should define_and_validate(:through => :project_tasks).through(:project_tasks) }
|
461
436
|
|
462
|
-
it { should_not define_and_validate(:through =>
|
463
|
-
it { should_not define_and_validate(:through =>
|
437
|
+
it { should_not define_and_validate(:through => :project_tasks).through(:something) }
|
438
|
+
it { should_not define_and_validate(:through => :project_tasks, :skip_through => true).through(:project_tasks) }
|
439
|
+
end
|
440
|
+
|
441
|
+
describe 'with source option' do
|
442
|
+
it { should define_and_validate(:through => :project_tasks, :source => :todo).source(:todo) }
|
443
|
+
it { should_not define_and_validate(:through => :project_tasks, :source => :todo).source(:task) }
|
464
444
|
end
|
465
445
|
|
466
446
|
create_optional_boolean_specs(:uniq, self)
|
@@ -470,7 +450,7 @@ describe 'association_matcher' do
|
|
470
450
|
end
|
471
451
|
|
472
452
|
describe 'macros' do
|
473
|
-
before(:each){ define_and_validate(:through =>
|
453
|
+
before(:each){ define_and_validate(:through => :project_tasks, :readonly => true, :validate => true) }
|
474
454
|
|
475
455
|
should_have_many :tasks
|
476
456
|
should_have_many :tasks, :readonly => true
|
@@ -487,17 +467,19 @@ describe 'association_matcher' do
|
|
487
467
|
|
488
468
|
# Defines a model, create a validation and returns a raw matcher
|
489
469
|
def define_and_validate(options={})
|
490
|
-
columns = options.delete(:association_columns) || { :manager_id => :integer, :project_id => :integer }
|
491
|
-
define_model :manager, columns
|
470
|
+
columns = options.delete(:association_columns) || { :manager_id => :integer, :project_id => :integer, :boss_id => :integer }
|
471
|
+
define_model :manager, columns
|
472
|
+
define_model :boss, columns
|
492
473
|
|
493
474
|
define_model :project_manager, columns do
|
494
475
|
belongs_to :manager
|
495
|
-
belongs_to :project
|
496
|
-
|
476
|
+
belongs_to :project
|
477
|
+
belongs_to :boss
|
478
|
+
end unless options.delete(:skip_source)
|
497
479
|
|
498
|
-
@model = define_model :project, options.delete(:model_columns) || {} do
|
480
|
+
@model = define_model :project, options.delete(:model_columns) || {} do
|
481
|
+
has_many :project_managers unless options.delete(:skip_through)
|
499
482
|
has_one :manager, options
|
500
|
-
has_many :project_managers
|
501
483
|
end
|
502
484
|
|
503
485
|
have_one :manager
|
@@ -536,15 +518,28 @@ describe 'association_matcher' do
|
|
536
518
|
end
|
537
519
|
|
538
520
|
it 'should set through_exists? message' do
|
539
|
-
matcher = define_and_validate(:through =>
|
540
|
-
matcher.through(:
|
541
|
-
matcher.failure_message.should == 'Expected Project records have one manager through :
|
542
|
-
end
|
543
|
-
|
544
|
-
it 'should set
|
545
|
-
matcher = define_and_validate(:through =>
|
521
|
+
matcher = define_and_validate(:through => :project_managers, :skip_through => true)
|
522
|
+
matcher.through(:project_managers).matches?(@model)
|
523
|
+
matcher.failure_message.should == 'Expected Project records have one manager through :project_managers, through association does not exist'
|
524
|
+
end
|
525
|
+
|
526
|
+
it 'should set source_exists? message' do
|
527
|
+
matcher = define_and_validate(:through => :project_managers, :skip_source => true)
|
546
528
|
matcher.through(:project_managers).matches?(@model)
|
547
|
-
matcher.failure_message.should == 'Expected
|
529
|
+
matcher.failure_message.should == 'Expected Project records have one manager through :project_managers, source association does not exist'
|
530
|
+
end
|
531
|
+
|
532
|
+
it 'should set options_matches? message when dependent is given' do
|
533
|
+
matcher = define_and_validate(:dependent => :destroy)
|
534
|
+
matcher.dependent(:nullify).matches?(@model)
|
535
|
+
matcher.failure_message.should == 'Expected Project records have one manager with options {:dependent=>"nullify"}, got {:dependent=>"destroy"}'
|
536
|
+
end
|
537
|
+
|
538
|
+
it 'should set options_matches? message when source is given' do
|
539
|
+
matcher = define_and_validate(:through => :project_managers, :source => :boss)
|
540
|
+
matcher.through(:project_managers).source(:manager).matches?(@model)
|
541
|
+
matcher.failure_message.should match(/:source=>"manager"/)
|
542
|
+
matcher.failure_message.should match(/:source=>"boss"/)
|
548
543
|
end
|
549
544
|
end
|
550
545
|
|
@@ -589,11 +584,16 @@ describe 'association_matcher' do
|
|
589
584
|
end
|
590
585
|
|
591
586
|
describe 'with through option' do
|
592
|
-
it { should define_and_validate(:through =>
|
593
|
-
it { should define_and_validate(:through =>
|
587
|
+
it { should define_and_validate(:through => :project_managers) }
|
588
|
+
it { should define_and_validate(:through => :project_managers).through(:project_managers) }
|
594
589
|
|
595
|
-
it { should_not define_and_validate(:through =>
|
596
|
-
it { should_not define_and_validate(:through =>
|
590
|
+
it { should_not define_and_validate(:through => :project_managers).through(:something) }
|
591
|
+
it { should_not define_and_validate(:through => :project_managers, :skip_through => true).through(:project_managers) }
|
592
|
+
end
|
593
|
+
|
594
|
+
describe 'with source option' do
|
595
|
+
it { should define_and_validate(:through => :project_managers, :source => :boss).source(:boss) }
|
596
|
+
it { should_not define_and_validate(:through => :project_managers, :source => :boss).source(:manager) }
|
597
597
|
end
|
598
598
|
|
599
599
|
create_optional_boolean_specs(:validate, self)
|
@@ -601,7 +601,7 @@ describe 'association_matcher' do
|
|
601
601
|
end
|
602
602
|
|
603
603
|
describe 'macros' do
|
604
|
-
before(:each){ define_and_validate(:through =>
|
604
|
+
before(:each){ define_and_validate(:through => :project_managers, :validate => true) }
|
605
605
|
|
606
606
|
should_have_one :manager
|
607
607
|
should_have_one :manager, :validate => true
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: remarkable_activerecord
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 3.0.
|
4
|
+
version: 3.0.5
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Carlos Brando
|
@@ -11,7 +11,7 @@ autorequire:
|
|
11
11
|
bindir: bin
|
12
12
|
cert_chain: []
|
13
13
|
|
14
|
-
date: 2009-04-
|
14
|
+
date: 2009-04-20 00:00:00 +02:00
|
15
15
|
default_executable:
|
16
16
|
dependencies:
|
17
17
|
- !ruby/object:Gem::Dependency
|
@@ -22,7 +22,7 @@ dependencies:
|
|
22
22
|
requirements:
|
23
23
|
- - ">="
|
24
24
|
- !ruby/object:Gem::Version
|
25
|
-
version: 3.0.
|
25
|
+
version: 3.0.5
|
26
26
|
version:
|
27
27
|
description: "Remarkable ActiveRecord: collection of matchers and macros with I18n for ActiveRecord"
|
28
28
|
email:
|