Skip to content

Commit

Permalink
support for validates_length_of
Browse files Browse the repository at this point in the history
  • Loading branch information
fhwang committed Mar 4, 2012
1 parent a6e4e86 commit d5cb2f6
Show file tree
Hide file tree
Showing 8 changed files with 68 additions and 16 deletions.
7 changes: 7 additions & 0 deletions README.markdown
Expand Up @@ -117,6 +117,13 @@ validates_inclusion_of
SampleModels will set the attribute to one of the specified values.


validates_length_of
-------------------

SampleModels will set the attribute to a string within the specified
length constraints.


validates_uniqueness_of
-----------------------

Expand Down
25 changes: 25 additions & 0 deletions lib/sample_models/attribute_sequence.rb
Expand Up @@ -27,6 +27,8 @@ def self.source(pass, model, column, force_email_format)
EmailSource.new
elsif v = validations.detect(&:inclusion?)
InclusionSource.new(v)
elsif v = validations.detect(&:length?)
LengthSource.new(v)
else
SimpleSource.new(column)
end
Expand Down Expand Up @@ -65,6 +67,29 @@ def value
@validation.config[:in].first
end
end

class LengthSource < AbstractSource
def initialize(validation)
super()
@validation = validation
end

def value
minimum = @validation.config[:minimum]
minimum ||= (
@validation.config[:within] && @validation.config[:within].begin
)
minimum ||= (
@validation.config[:in] && @validation.config[:in].begin
)
minimum ||= 1
value = 'a' * minimum
@number.times do
value = value.succ
end
value
end
end

class RequiredBelongsToSource < AbstractSource
def initialize(assoc)
Expand Down
2 changes: 1 addition & 1 deletion lib/sample_models/initializer.rb
Expand Up @@ -17,7 +17,7 @@ def intercept_validation_definition(validation, recipient)
def intercept_validation_definitions
validations_to_intercept = [
:validates_email_format_of, :validates_inclusion_of,
:validates_presence_of, :validates_uniqueness_of
:validates_length_of, :validates_presence_of, :validates_uniqueness_of
]
optional_interceptions = [:validates_email_format_of]
validations_to_intercept.each do |validation|
Expand Down
23 changes: 9 additions & 14 deletions lib/sample_models/model.rb
Expand Up @@ -88,21 +88,16 @@ class Validation
def initialize(type, config = {})
@type, @config = type, config
end

def email_format?
@type == :validates_email_format_of
end

def inclusion?
@type == :validates_inclusion_of
end

def presence?
@type == :validates_presence_of
end

def uniqueness?
@type == :validates_uniqueness_of
def method_missing(meth, *args, &block)
type_predicates = %w(
email_format? inclusion? length? presence? uniqueness?
)
if type_predicates.include?(meth.to_s)
@type == "validates_#{meth.to_s.chop}_of".to_sym
else
super
end
end
end
end
Expand Down
5 changes: 5 additions & 0 deletions test/setup/models.rb
Expand Up @@ -99,6 +99,11 @@ class User < ActiveRecord::Base
class User2 < ActiveRecord::Base
validates_presence_of :login
validates_uniqueness_of :login
validates_length_of :token1, :minimum => 40
validates_length_of :token2, :maximum => 4
validates_uniqueness_of :token2
validates_length_of :token3, :within => (20..40)
validates_length_of :token4, :in => (20..40)
end

class UserWithPassword < ActiveRecord::Base
Expand Down
4 changes: 4 additions & 0 deletions test/setup/schema.rb
Expand Up @@ -89,6 +89,10 @@
create_table 'user2s', :force => true do |user2|
user2.string 'login'
user2.string 'email'
user2.string 'token1'
user2.string 'token2'
user2.string 'token3'
user2.string 'token4'
end

create_table 'user_with_passwords', :force => true do |user|
Expand Down
5 changes: 4 additions & 1 deletion test/unit/sample_test.rb
Expand Up @@ -90,7 +90,10 @@ def test_required_accessor
def test_string_which_is_required_to_be_present_and_unique
# Ensuring that it doesn't get tripped up by a pre-existing record
User2.destroy_all
User2.create!(:login => 'login 1')
User2.create!(
:login => 'login 1', :token1 => 'a' * 40, :token2 => 'a' * 4,
:token3 => 'a' * 20, :token4 => 'a' * 20
)
User2.sample
end

Expand Down
13 changes: 13 additions & 0 deletions test/unit/validations_test.rb
Expand Up @@ -27,5 +27,18 @@ def test_cant_override_validations
end
end
end

def test_validates_length_of
token2s = []
50.times do
user2 = User2.sample
assert(user2.token1.length >= 40)
assert(user2.token2.length <= 4)
token2s << user2.token2
assert(user2.token3.length >= 20 && user2.token3.length <= 40)
assert(user2.token4.length >= 20 && user2.token4.length <= 40)
end
assert_equal(token2s.size, token2s.uniq.size)
end
end

0 comments on commit d5cb2f6

Please sign in to comment.