4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
|
# File 'lib/rspec_rails_matchers/validations/length_of.rb', line 4
def validate_length_of(attribute, options = {})
if range = (options.delete(:in) || options.delete(:within))
raise ArgumentError, ":in and :within must be a Range" unless range.is_a?(Range)
options[:minimum], options[:maximum] = range.begin, range.end
options[:maximum] -= 1 if range.exclude_end?
end
if (ActiveModel::Validations::LengthValidator::CHECKS.keys & options.keys).empty?
raise ArgumentError, 'Range unspecified. Specify the :within, :maximum, :minimum, or :is option.'
end
delete_keys = [:tokenizer, :too_long, :too_short, :wrong_length, :message, :if, :unless]
options.delete_if { |k| delete_keys.include? k }
actual_options = {}
Rspec::Matchers::Matcher.new :validate_length_of, attribute do |_attr_|
match do |model|
if validator = model.class.validators.find(Proc.new {false}) { |v| v.to_s.demodulize =~ /^LengthValidator/ &&
v.attributes.include?(_attr_) }
options_unfrozen = validator.options.dup
options_unfrozen.delete_if { |k| delete_keys.include? k }
actual_options = options_unfrozen
options_unfrozen.deep_include?(options) && options_unfrozen.keys.sort == options.keys.sort
end
end
failure_message_for_should do |model|
RspecRailsMatchers::Message.error(
:expected => [ "%s to validate uniqueness of %s, %s", model, _attr_, options ],
:actual => [ "%s to validate uniqueness of %s, %s", model, _attr_, actual_options]
)
end
end
end
|