jakewendt-rails_extension 2.0.22
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/LICENSE +20 -0
- data/README.rdoc +42 -0
- data/generators/rails_extension/USAGE +0 -0
- data/generators/rails_extension/rails_extension_generator.rb +72 -0
- data/lib/jakewendt-rails_extension.rb +1 -0
- data/lib/rails_extension.rb +18 -0
- data/lib/rails_extension/action_controller_extension.rb +8 -0
- data/lib/rails_extension/action_controller_extension/accessible_via_format.rb +2 -0
- data/lib/rails_extension/action_controller_extension/accessible_via_protocol.rb +403 -0
- data/lib/rails_extension/action_controller_extension/accessible_via_user.rb +606 -0
- data/lib/rails_extension/action_controller_extension/routing.rb +23 -0
- data/lib/rails_extension/action_controller_extension/test_case.rb +19 -0
- data/lib/rails_extension/active_record_extension.rb +5 -0
- data/lib/rails_extension/active_record_extension/base.rb +82 -0
- data/lib/rails_extension/active_record_extension/error.rb +18 -0
- data/lib/rails_extension/active_record_extension/errors.rb +20 -0
- data/lib/rails_extension/active_support_extension.rb +29 -0
- data/lib/rails_extension/active_support_extension/associations.rb +209 -0
- data/lib/rails_extension/active_support_extension/attributes.rb +235 -0
- data/lib/rails_extension/active_support_extension/pending.rb +67 -0
- data/lib/rails_extension/active_support_extension/test_case.rb +211 -0
- data/rails/init.rb +1 -0
- metadata +146 -0
@@ -0,0 +1,23 @@
|
|
1
|
+
module RailsExtension::ActionControllerExtension::Routing
|
2
|
+
|
3
|
+
def self.included(base)
|
4
|
+
base.extend ClassMethods
|
5
|
+
end
|
6
|
+
|
7
|
+
module ClassMethods
|
8
|
+
|
9
|
+
# def assert_route
|
10
|
+
# end
|
11
|
+
|
12
|
+
def assert_no_route(verb,action,args={})
|
13
|
+
test "#{brand}no route to #{verb} #{action} #{args}" do
|
14
|
+
assert_raise(ActionController::RoutingError){
|
15
|
+
send(verb,action,args)
|
16
|
+
}
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
end # module ClassMethods
|
21
|
+
end # module RailsExtension::ActionControllerExtension::Routing
|
22
|
+
ActionController::TestCase.send(:include,
|
23
|
+
RailsExtension::ActionControllerExtension::Routing)
|
@@ -0,0 +1,19 @@
|
|
1
|
+
module RailsExtension::ActionControllerExtension::TestCase
|
2
|
+
|
3
|
+
def turn_https_on
|
4
|
+
@request.env['HTTPS'] = 'on'
|
5
|
+
# @request.env['HTTP_X_FORWARDED_PROTO'] == 'https'
|
6
|
+
end
|
7
|
+
|
8
|
+
def turn_https_off
|
9
|
+
@request.env['HTTPS'] = nil
|
10
|
+
end
|
11
|
+
|
12
|
+
def assert_layout(layout)
|
13
|
+
layout = "layouts/#{layout}" unless layout.match(/^layouts/)
|
14
|
+
assert_equal layout, @response.layout
|
15
|
+
end
|
16
|
+
|
17
|
+
end # module RailsExtension::ActionControllerExtension::TestCase
|
18
|
+
ActionController::TestCase.send(:include,
|
19
|
+
RailsExtension::ActionControllerExtension::TestCase)
|
@@ -0,0 +1,82 @@
|
|
1
|
+
module RailsExtension::ActiveRecordExtension::Base
|
2
|
+
def self.included(base)
|
3
|
+
base.extend(ClassMethods)
|
4
|
+
end
|
5
|
+
|
6
|
+
module ClassMethods
|
7
|
+
|
8
|
+
def random
|
9
|
+
count = count()
|
10
|
+
if count > 0
|
11
|
+
first(:offset => rand(count))
|
12
|
+
else
|
13
|
+
nil
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
def validates_absence_of(*attr_names)
|
18
|
+
configuration = { :on => :save,
|
19
|
+
:message => "is present and must be absent." }
|
20
|
+
configuration.update(attr_names.extract_options!)
|
21
|
+
|
22
|
+
send(validation_method(configuration[:on]), configuration) do |record|
|
23
|
+
attr_names.each do |attr_name|
|
24
|
+
unless record.send(attr_name).blank?
|
25
|
+
record.errors.add(attr_name,
|
26
|
+
ActiveRecord::Error.new(record,attr_name,:present,
|
27
|
+
{ :message => configuration[:message] }))
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
def validates_past_date_for(*attr_names)
|
34
|
+
configuration = { :on => :save,
|
35
|
+
:message => "is in the future and must be in the past." }
|
36
|
+
configuration.update(attr_names.extract_options!)
|
37
|
+
|
38
|
+
send(validation_method(configuration[:on]), configuration) do |record|
|
39
|
+
attr_names.each do |attr_name|
|
40
|
+
date = record.send(attr_name)
|
41
|
+
if !date.blank? && Time.now < date
|
42
|
+
record.errors.add(attr_name,
|
43
|
+
ActiveRecord::Error.new(record,attr_name,:not_past_date,
|
44
|
+
{ :message => configuration[:message] }))
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
# This doesn't work as one would expect if the column
|
51
|
+
# is a DateTime instead of just a Date.
|
52
|
+
# For some reason, *_before_type_cast actually
|
53
|
+
# returns a parsed DateTime?
|
54
|
+
def validates_complete_date_for(*attr_names)
|
55
|
+
configuration = { :on => :save,
|
56
|
+
:message => "is not a complete date." }
|
57
|
+
configuration.update(attr_names.extract_options!)
|
58
|
+
|
59
|
+
send(validation_method(configuration[:on]), configuration) do |record|
|
60
|
+
attr_names.each do |attr_name|
|
61
|
+
|
62
|
+
value = record.send("#{attr_name}_before_type_cast")
|
63
|
+
unless( configuration[:allow_nil] && value.blank? ) ||
|
64
|
+
( !value.is_a?(String) )
|
65
|
+
date_hash = Date._parse(value)
|
66
|
+
unless date_hash.has_key?(:year) &&
|
67
|
+
date_hash.has_key?(:mon) &&
|
68
|
+
date_hash.has_key?(:mday)
|
69
|
+
record.errors.add(attr_name,
|
70
|
+
ActiveRecord::Error.new(record,attr_name,:not_complete_date,
|
71
|
+
{ :message => configuration[:message] }))
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
end
|
79
|
+
|
80
|
+
end
|
81
|
+
ActiveRecord::Base.send(:include,
|
82
|
+
RailsExtension::ActiveRecordExtension::Base)
|
@@ -0,0 +1,18 @@
|
|
1
|
+
module RailsExtension::ActiveRecordExtension::Error
|
2
|
+
|
3
|
+
def self.included(base)
|
4
|
+
base.alias_method_chain( :generate_full_message, :attribute_strip ) unless
|
5
|
+
base.method_defined?(:generate_full_message_without_attribute_strip)
|
6
|
+
end
|
7
|
+
|
8
|
+
def generate_full_message_with_attribute_strip(options = {}, &block)
|
9
|
+
m = generate_full_message_without_attribute_strip(options, &block)
|
10
|
+
unless( ( i = m.index('<|X|') ).nil? )
|
11
|
+
m = m[i+4..-1]
|
12
|
+
end
|
13
|
+
m
|
14
|
+
end
|
15
|
+
|
16
|
+
end
|
17
|
+
ActiveRecord::Error.send(:include,
|
18
|
+
RailsExtension::ActiveRecordExtension::Error)
|
@@ -0,0 +1,20 @@
|
|
1
|
+
module RailsExtension::ActiveRecordExtension::Errors
|
2
|
+
def self.included(base)
|
3
|
+
base.extend(ClassMethods)
|
4
|
+
base.send(:include,InstanceMethods)
|
5
|
+
end
|
6
|
+
module InstanceMethods
|
7
|
+
def on_attr_and_type(attribute,type)
|
8
|
+
attribute = attribute.to_s
|
9
|
+
return nil unless @errors.has_key?(attribute)
|
10
|
+
@errors[attribute].collect(&:type).include?(type)
|
11
|
+
end
|
12
|
+
end
|
13
|
+
module ClassMethods
|
14
|
+
def delete(key)
|
15
|
+
@errors.delete(key.to_s)
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end # RailsExtension::ActiveRecordExtension::Errors
|
19
|
+
ActiveRecord::Errors.send(:include,
|
20
|
+
RailsExtension::ActiveRecordExtension::Errors)
|
@@ -0,0 +1,29 @@
|
|
1
|
+
require 'active_support'
|
2
|
+
require 'active_support/test_case'
|
3
|
+
$LOAD_PATH.unshift(File.dirname(__FILE__))
|
4
|
+
require 'active_support_extension/test_case'
|
5
|
+
require 'active_support_extension/associations'
|
6
|
+
require 'active_support_extension/attributes'
|
7
|
+
require 'active_support_extension/pending'
|
8
|
+
|
9
|
+
|
10
|
+
Rails.backtrace_cleaner.add_silencer {|line|
|
11
|
+
# line =~ /\/test\/.*\.\.\/declarative\.rb:/
|
12
|
+
# Due to my modification, every error is accompanied by
|
13
|
+
# 3 additional and unnecessary lines like ...
|
14
|
+
# /test/functional/../declarative.rb:21:in `_test_should_change_locale_to_es_without_verbosity'
|
15
|
+
#/test/functional/../declarative.rb:21:in `send'
|
16
|
+
#/test/functional/../declarative.rb:21:in `_test_should_change_locale_to_es_with_verbosity']:
|
17
|
+
#
|
18
|
+
# in rvm/jruby the error is passing through
|
19
|
+
# test/declarative.rb:21:in `_test_should_NOT_create_new_user_if_invitation_update_fails_with_verbosity']:
|
20
|
+
|
21
|
+
# /Users/jakewendt/github_repo/jakewendt/ucb_ccls_clic/vendor/plugins/ucb_ccls_engine/rails/../test/helpers/declarative.rb:21:in `_test_AWiHTTP_should_get_show_with_admin_login_with_verbosity'
|
22
|
+
|
23
|
+
# This doesn't seem to work at all in the plugin engine.
|
24
|
+
# line =~ /test.*\/declarative\.rb:/
|
25
|
+
# line =~ /simply_testable\/declarative\.rb:/
|
26
|
+
|
27
|
+
# Return true or false. Need to collect if adding multiple conditions.
|
28
|
+
line =~ /rails_extension\/active_support_extension\/test_case\.rb:/
|
29
|
+
} if defined? Rails
|
@@ -0,0 +1,209 @@
|
|
1
|
+
module RailsExtension::ActiveSupportExtension::Associations
|
2
|
+
|
3
|
+
def self.included(base)
|
4
|
+
base.extend ClassMethods
|
5
|
+
# base.send(:include,InstanceMethods)
|
6
|
+
base.class_eval do
|
7
|
+
class << self
|
8
|
+
alias_methods = {
|
9
|
+
:should_have_many => :should_have_many_,
|
10
|
+
:should_have_many_associations => :should_have_many_,
|
11
|
+
:should_require_valid_associations => :requires_valid_associations,
|
12
|
+
:should_require_valid_association => :requires_valid_associations,
|
13
|
+
:requires_valid_association => :requires_valid_associations,
|
14
|
+
:requires_valid => :requires_valid_associations
|
15
|
+
}
|
16
|
+
alias_methods.each do |alias_name,method_name|
|
17
|
+
alias_method( "assert_#{alias_name}",
|
18
|
+
"assert_#{method_name}" ) unless
|
19
|
+
self.method_defined?("assert_#{alias_name}")
|
20
|
+
end # alias_methods.each
|
21
|
+
end # class << self
|
22
|
+
end # base.class_eval
|
23
|
+
end # def self.included
|
24
|
+
|
25
|
+
module ClassMethods
|
26
|
+
|
27
|
+
def assert_should_initially_belong_to(*associations)
|
28
|
+
options = associations.extract_options!
|
29
|
+
model = options[:model] || st_model_name
|
30
|
+
associations.each do |assoc|
|
31
|
+
class_name = ( assoc = assoc.to_s ).camelize
|
32
|
+
title = "#{brand}should initially belong to #{assoc}"
|
33
|
+
if !options[:class_name].blank?
|
34
|
+
title << " ( #{options[:class_name]} )"
|
35
|
+
class_name = options[:class_name].to_s
|
36
|
+
end
|
37
|
+
test title do
|
38
|
+
object = create_object
|
39
|
+
assert_not_nil object.send(assoc)
|
40
|
+
if object.send(assoc).respond_to?(
|
41
|
+
"#{model.underscore.pluralize}_count")
|
42
|
+
assert_equal 1, object.reload.send(assoc).send(
|
43
|
+
"#{model.underscore.pluralize}_count")
|
44
|
+
end
|
45
|
+
if !options[:class_name].blank?
|
46
|
+
assert object.send(assoc).is_a?(class_name.constantize)
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
def assert_should_belong_to(*associations)
|
53
|
+
options = associations.extract_options!
|
54
|
+
model = options[:model] || st_model_name
|
55
|
+
associations.each do |assoc|
|
56
|
+
class_name = ( assoc = assoc.to_s ).camelize
|
57
|
+
title = "#{brand}should belong to #{assoc}"
|
58
|
+
# if !options[:as].blank?
|
59
|
+
# title << " as #{options[:as]}"
|
60
|
+
# as = options[:as]
|
61
|
+
# end
|
62
|
+
if !options[:class_name].blank?
|
63
|
+
title << " ( #{options[:class_name]} )"
|
64
|
+
class_name = options[:class_name].to_s
|
65
|
+
end
|
66
|
+
test title do
|
67
|
+
object = create_object
|
68
|
+
assert_nil object.send(assoc)
|
69
|
+
object.send("#{assoc}=",send("create_#{class_name.underscore}"))
|
70
|
+
assert_not_nil object.send(assoc)
|
71
|
+
assert object.send(assoc).is_a?(class_name.constantize
|
72
|
+
) unless options[:polymorphic]
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
def assert_should_have_one(*associations)
|
78
|
+
options = associations.extract_options!
|
79
|
+
model = options[:model] || st_model_name
|
80
|
+
# foreign_key = if !options[:foreign_key].blank?
|
81
|
+
# options[:foreign_key].to_sym
|
82
|
+
# else
|
83
|
+
# "#{model.underscore}_id".to_sym
|
84
|
+
# end
|
85
|
+
associations.each do |assoc|
|
86
|
+
assoc = assoc.to_s
|
87
|
+
test "#{brand}should have one #{assoc}" do
|
88
|
+
object = create_object
|
89
|
+
assert_nil object.reload.send(assoc)
|
90
|
+
# send("create_#{assoc}", foreign_key => object.id)
|
91
|
+
send("create_#{assoc}", model.underscore => object )
|
92
|
+
assert_not_nil object.reload.send(assoc)
|
93
|
+
object.send(assoc).destroy
|
94
|
+
assert_nil object.reload.send(assoc)
|
95
|
+
end
|
96
|
+
end
|
97
|
+
end
|
98
|
+
|
99
|
+
def assert_should_have_many_(*associations)
|
100
|
+
options = associations.extract_options!
|
101
|
+
model = options[:model] || st_model_name
|
102
|
+
# foreign_key = if !options[:foreign_key].blank?
|
103
|
+
# options[:foreign_key].to_sym
|
104
|
+
# else
|
105
|
+
# "#{model.underscore}_id".to_sym
|
106
|
+
# end
|
107
|
+
associations.each do |assoc|
|
108
|
+
class_name = ( assoc = assoc.to_s ).camelize
|
109
|
+
title = "#{brand}should have many #{assoc}"
|
110
|
+
if !options[:class_name].blank?
|
111
|
+
title << " ( #{options[:class_name]} )"
|
112
|
+
class_name = options[:class_name].to_s
|
113
|
+
end
|
114
|
+
if !options[:as].blank?
|
115
|
+
title << " ( as #{options[:as]} )"
|
116
|
+
end
|
117
|
+
test title do
|
118
|
+
object = create_object
|
119
|
+
assert_equal 0, object.send(assoc).length
|
120
|
+
command = ["create_#{class_name.singularize.underscore}"]
|
121
|
+
if !options[:foreign_key].blank?
|
122
|
+
command.push( options[:foreign_key].to_sym => object.id )
|
123
|
+
elsif !options[:as].blank?
|
124
|
+
command.push( options[:as].to_sym => object )
|
125
|
+
else
|
126
|
+
command.push( model.underscore => object )
|
127
|
+
end
|
128
|
+
# send("create_#{class_name.singularize.underscore}", foreign_key => object.id)
|
129
|
+
# send("create_#{class_name.singularize.underscore}", model.underscore => object )
|
130
|
+
send *command
|
131
|
+
assert_equal 1, object.reload.send(assoc).length
|
132
|
+
if object.respond_to?("#{assoc}_count")
|
133
|
+
assert_equal 1, object.reload.send("#{assoc}_count")
|
134
|
+
end
|
135
|
+
# send("create_#{class_name.singularize.underscore}", foreign_key => object.id)
|
136
|
+
# send("create_#{class_name.singularize.underscore}", model.underscore => object )
|
137
|
+
send *command
|
138
|
+
assert_equal 2, object.reload.send(assoc).length
|
139
|
+
if object.respond_to?("#{assoc}_count")
|
140
|
+
assert_equal 2, object.reload.send("#{assoc}_count")
|
141
|
+
end
|
142
|
+
end
|
143
|
+
end
|
144
|
+
end
|
145
|
+
|
146
|
+
def assert_should_habtm(*associations)
|
147
|
+
options = associations.extract_options!
|
148
|
+
model = options[:model] || st_model_name
|
149
|
+
associations.each do |assoc|
|
150
|
+
assoc = assoc.to_s
|
151
|
+
test "#{brand}should habtm #{assoc}" do
|
152
|
+
object = create_object
|
153
|
+
assert_equal 0, object.send(assoc).length
|
154
|
+
object.send(assoc) << send("create_#{assoc.singularize}")
|
155
|
+
assert_equal 1, object.reload.send(assoc).length
|
156
|
+
if object.respond_to?("#{assoc}_count")
|
157
|
+
assert_equal 1, object.reload.send("#{assoc}_count")
|
158
|
+
end
|
159
|
+
object.send(assoc) << send("create_#{assoc.singularize}")
|
160
|
+
assert_equal 2, object.reload.send(assoc).length
|
161
|
+
if object.respond_to?("#{assoc}_count")
|
162
|
+
assert_equal 2, object.reload.send("#{assoc}_count")
|
163
|
+
end
|
164
|
+
end
|
165
|
+
end
|
166
|
+
end
|
167
|
+
|
168
|
+
def assert_requires_valid_associations(*associations)
|
169
|
+
# options = associations.extract_options!
|
170
|
+
# model = options[:model] || st_model_name
|
171
|
+
#
|
172
|
+
# associations.each do |assoc|
|
173
|
+
# as = assoc = assoc.to_s
|
174
|
+
# as = options[:as] if !options[:as].blank?
|
175
|
+
#
|
176
|
+
# test "#{brand}should require foreign key #{as}_id" do
|
177
|
+
# assert_difference("#{model}.count",0) do
|
178
|
+
# object = create_object("#{as}_id".to_sym => nil)
|
179
|
+
# assert object.errors.on("#{as}_id".to_sym)
|
180
|
+
# end
|
181
|
+
# end
|
182
|
+
#
|
183
|
+
# # test "#{brand}should require valid foreign key #{as}_id" do
|
184
|
+
# # assert_difference("#{model}.count",0) do
|
185
|
+
# # object = create_object("#{as}_id".to_sym => 0)
|
186
|
+
# # assert object.errors.on("#{as}_id".to_sym)
|
187
|
+
# # end
|
188
|
+
# # end
|
189
|
+
#
|
190
|
+
# title = "#{brand}should require valid association #{assoc}"
|
191
|
+
# title << " as #{options[:as]}" if !options[:as].blank?
|
192
|
+
# test title do
|
193
|
+
# assert_difference("#{model}.count",0) {
|
194
|
+
# object = create_object(
|
195
|
+
# assoc.to_sym => Factory.build(assoc.to_sym))
|
196
|
+
# # as.to_sym => Factory.build(assoc.to_sym))
|
197
|
+
# assert object.errors.on("#{as}_id".to_sym)
|
198
|
+
# }
|
199
|
+
# end
|
200
|
+
#
|
201
|
+
# end
|
202
|
+
|
203
|
+
end
|
204
|
+
|
205
|
+
end # ClassMethods
|
206
|
+
|
207
|
+
end # module RailsExtension::Associations
|
208
|
+
ActiveSupport::TestCase.send(:include,
|
209
|
+
RailsExtension::ActiveSupportExtension::Associations)
|
@@ -0,0 +1,235 @@
|
|
1
|
+
module RailsExtension::ActiveSupportExtension::Attributes
|
2
|
+
|
3
|
+
def self.included(base)
|
4
|
+
base.extend ClassMethods
|
5
|
+
# base.send(:include,InstanceMethods)
|
6
|
+
base.class_eval do
|
7
|
+
class << self
|
8
|
+
alias_methods = {
|
9
|
+
:require_unique_attributes => :require_unique_attribute,
|
10
|
+
:require_unique => :require_unique_attribute,
|
11
|
+
:require_attributes_not_nil => :require_attribute_not_nil,
|
12
|
+
:require_not_nil => :require_attribute_not_nil,
|
13
|
+
:require_attributes => :require_attribute,
|
14
|
+
:require => :require_attribute,
|
15
|
+
:not_require_attributes => :not_require_attribute,
|
16
|
+
:not_require => :not_require_attribute,
|
17
|
+
:require_attributes_length => :require_attribute_length,
|
18
|
+
:require_length => :require_attribute_length,
|
19
|
+
:protect_attributes => :protect_attribute,
|
20
|
+
:protect => :protect_attribute,
|
21
|
+
:not_protect_attributes => :not_protect_attribute,
|
22
|
+
:not_protect => :not_protect_attribute
|
23
|
+
}
|
24
|
+
alias_methods.each do |alias_name,method_name|
|
25
|
+
alias_method( "assert_should_#{alias_name}",
|
26
|
+
"assert_should_#{method_name}" ) unless
|
27
|
+
self.method_defined?("assert_should_#{alias_name}")
|
28
|
+
end # alias_methods.each
|
29
|
+
end # class << self
|
30
|
+
end # base.class_eval
|
31
|
+
end # def self.included
|
32
|
+
|
33
|
+
module ClassMethods
|
34
|
+
|
35
|
+
def assert_should_require_unique_attribute(*attributes)
|
36
|
+
options = attributes.extract_options!
|
37
|
+
model = options[:model] || st_model_name
|
38
|
+
|
39
|
+
attributes.each do |attr|
|
40
|
+
attr = attr.to_s
|
41
|
+
title = "#{brand}should require unique #{attr}"
|
42
|
+
scope = options[:scope]
|
43
|
+
unless scope.blank?
|
44
|
+
title << " scope "
|
45
|
+
title << (( scope.is_a?(Array) )?scope.join(','):scope.to_s)
|
46
|
+
end
|
47
|
+
test title do
|
48
|
+
o = create_object
|
49
|
+
assert_no_difference "#{model}.count" do
|
50
|
+
attrs = { attr.to_sym => o.send(attr) }
|
51
|
+
if( scope.is_a?(String) || scope.is_a?(Symbol) )
|
52
|
+
attrs[scope.to_sym] = o.send(scope.to_sym)
|
53
|
+
elsif scope.is_a?(Array)
|
54
|
+
scope.each do |s|
|
55
|
+
attrs[s.to_sym] = o.send(s.to_sym)
|
56
|
+
end
|
57
|
+
end
|
58
|
+
object = create_object(attrs)
|
59
|
+
assert object.errors.on_attr_and_type(attr.to_sym, :taken)
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
def assert_should_require_attribute_not_nil(*attributes)
|
66
|
+
options = attributes.extract_options!
|
67
|
+
model = options[:model] || st_model_name
|
68
|
+
|
69
|
+
attributes.each do |attr|
|
70
|
+
attr = attr.to_s
|
71
|
+
test "#{brand}should require #{attr} not nil" do
|
72
|
+
assert_no_difference "#{model}.count" do
|
73
|
+
object = create_object(attr.to_sym => nil)
|
74
|
+
assert object.errors.on(attr.to_sym)
|
75
|
+
end
|
76
|
+
end
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
def assert_should_require_attribute(*attributes)
|
81
|
+
options = attributes.extract_options!
|
82
|
+
model = options[:model] || st_model_name
|
83
|
+
|
84
|
+
attributes.each do |attr|
|
85
|
+
attr = attr.to_s
|
86
|
+
test "#{brand}should require #{attr}" do
|
87
|
+
assert_no_difference "#{model}.count" do
|
88
|
+
object = create_object(attr.to_sym => nil)
|
89
|
+
assert object.errors.on_attr_and_type(attr.to_sym, :blank) ||
|
90
|
+
object.errors.on_attr_and_type(attr.to_sym, :too_short)
|
91
|
+
end
|
92
|
+
end
|
93
|
+
end
|
94
|
+
end
|
95
|
+
|
96
|
+
def assert_should_not_require_attribute(*attributes)
|
97
|
+
options = attributes.extract_options!
|
98
|
+
model = options[:model] || st_model_name
|
99
|
+
|
100
|
+
attributes.each do |attr|
|
101
|
+
attr = attr.to_s
|
102
|
+
test "#{brand}should not require #{attr}" do
|
103
|
+
assert_difference( "#{model}.count", 1 ) do
|
104
|
+
object = create_object(attr.to_sym => nil)
|
105
|
+
assert !object.errors.on(attr.to_sym)
|
106
|
+
if attr =~ /^(.*)_id$/
|
107
|
+
assert !object.errors.on($1.to_sym)
|
108
|
+
end
|
109
|
+
end
|
110
|
+
end
|
111
|
+
end
|
112
|
+
end
|
113
|
+
|
114
|
+
def assert_should_require_attribute_length(*attributes)
|
115
|
+
options = attributes.extract_options!
|
116
|
+
model = options[:model] || st_model_name
|
117
|
+
|
118
|
+
if( ( options.keys & [:in,:within] ).length >= 1 )
|
119
|
+
range = options[:in]||options[:within]
|
120
|
+
options[:minimum] = range.min
|
121
|
+
options[:maximum] = range.max
|
122
|
+
end
|
123
|
+
|
124
|
+
attributes.each do |attr|
|
125
|
+
attr = attr.to_s
|
126
|
+
if options.keys.include?(:is)
|
127
|
+
length = options[:is]
|
128
|
+
test "#{brand}should require exact length of #{length} for #{attr}" do
|
129
|
+
assert_no_difference "#{model}.count" do
|
130
|
+
value = 'x'*(length-1)
|
131
|
+
object = create_object(attr.to_sym => value)
|
132
|
+
assert_equal length-1, object.send(attr.to_sym).length
|
133
|
+
assert_equal object.send(attr.to_sym), value
|
134
|
+
assert object.errors.on_attr_and_type(attr.to_sym, :wrong_length)
|
135
|
+
end
|
136
|
+
assert_no_difference "#{model}.count" do
|
137
|
+
value = 'x'*(length+1)
|
138
|
+
object = create_object(attr.to_sym => value)
|
139
|
+
assert_equal length+1, object.send(attr.to_sym).length
|
140
|
+
assert_equal object.send(attr.to_sym), value
|
141
|
+
assert object.errors.on_attr_and_type(attr.to_sym, :wrong_length)
|
142
|
+
end
|
143
|
+
end
|
144
|
+
end
|
145
|
+
|
146
|
+
if options.keys.include?(:minimum)
|
147
|
+
min = options[:minimum]
|
148
|
+
test "#{brand}should require min length of #{min} for #{attr}" do
|
149
|
+
# because the model may have other requirements
|
150
|
+
# just check to ensure that we don't get a :too_short error
|
151
|
+
# assert_difference "#{model}.count" do
|
152
|
+
value = 'x'*(min)
|
153
|
+
object = create_object(attr.to_sym => value)
|
154
|
+
assert_equal min, object.send(attr.to_sym).length
|
155
|
+
assert_equal object.send(attr.to_sym), value
|
156
|
+
assert !object.errors.on_attr_and_type(attr.to_sym, :too_short)
|
157
|
+
# end
|
158
|
+
assert_no_difference "#{model}.count" do
|
159
|
+
value = 'x'*(min-1)
|
160
|
+
object = create_object(attr.to_sym => value)
|
161
|
+
assert_equal min-1, object.send(attr.to_sym).length
|
162
|
+
assert_equal object.send(attr.to_sym), value
|
163
|
+
assert object.errors.on_attr_and_type(attr.to_sym, :too_short)
|
164
|
+
end
|
165
|
+
end
|
166
|
+
end
|
167
|
+
|
168
|
+
if options.keys.include?(:maximum)
|
169
|
+
max = options[:maximum]
|
170
|
+
test "#{brand}should require max length of #{max} for #{attr}" do
|
171
|
+
# because the model may have other requirements
|
172
|
+
# just check to ensure that we don't get a :too_long error
|
173
|
+
# assert_difference "#{model}.count" do
|
174
|
+
value = 'x'*(max)
|
175
|
+
object = create_object(attr.to_sym => value)
|
176
|
+
assert_equal max, object.send(attr.to_sym).length
|
177
|
+
assert_equal object.send(attr.to_sym), value
|
178
|
+
assert !object.errors.on_attr_and_type(attr.to_sym, :too_long)
|
179
|
+
# end
|
180
|
+
assert_no_difference "#{model}.count" do
|
181
|
+
value = 'x'*(max+1)
|
182
|
+
object = create_object(attr.to_sym => value)
|
183
|
+
assert_equal max+1, object.send(attr.to_sym).length
|
184
|
+
assert_equal object.send(attr.to_sym), value
|
185
|
+
assert object.errors.on_attr_and_type(attr.to_sym, :too_long)
|
186
|
+
end
|
187
|
+
end
|
188
|
+
end
|
189
|
+
|
190
|
+
end
|
191
|
+
end
|
192
|
+
|
193
|
+
def assert_should_protect_attribute(*attributes)
|
194
|
+
options = attributes.extract_options!
|
195
|
+
model_name = options[:model] || st_model_name
|
196
|
+
model = model_name.constantize
|
197
|
+
|
198
|
+
attributes.each do |attr|
|
199
|
+
attr = attr.to_s
|
200
|
+
test "#{brand}should protect attribute #{attr}" do
|
201
|
+
assert model.accessible_attributes||model.protected_attributes,
|
202
|
+
"Both accessible and protected attributes are empty"
|
203
|
+
assert !(model.accessible_attributes||[]).include?(attr),
|
204
|
+
"#{attr} is included in accessible attributes"
|
205
|
+
if !model.protected_attributes.nil?
|
206
|
+
assert model.protected_attributes.include?(attr),
|
207
|
+
"#{attr} is not included in protected attributes"
|
208
|
+
end
|
209
|
+
end
|
210
|
+
end
|
211
|
+
end
|
212
|
+
|
213
|
+
def assert_should_not_protect_attribute(*attributes)
|
214
|
+
options = attributes.extract_options!
|
215
|
+
model_name = options[:model] || st_model_name
|
216
|
+
model = model_name.constantize
|
217
|
+
|
218
|
+
attributes.each do |attr|
|
219
|
+
attr = attr.to_s
|
220
|
+
test "#{brand}should not protect attribute #{attr}" do
|
221
|
+
assert !(model.protected_attributes||[]).include?(attr),
|
222
|
+
"#{attr} is included in protected attributes"
|
223
|
+
if !model.accessible_attributes.nil?
|
224
|
+
assert model.accessible_attributes.include?(attr),
|
225
|
+
"#{attr} is not included in accessible attributes"
|
226
|
+
end
|
227
|
+
end
|
228
|
+
end
|
229
|
+
end
|
230
|
+
|
231
|
+
end
|
232
|
+
|
233
|
+
end # module RailsExtension::Attributes
|
234
|
+
ActiveSupport::TestCase.send(:include,
|
235
|
+
RailsExtension::ActiveSupportExtension::Attributes)
|