activevalidators 1.6.0 → 1.7.0

Sign up to get free protection for your applications and to get access to all the features.
data/README.md CHANGED
@@ -1,4 +1,4 @@
1
- ActiveValidators [![Travis](http://travis-ci.org/cesario/activevalidators.png)](http://travis-ci.org/cesario/activevalidators)
1
+ ActiveValidators [![Travis](https://secure.travis-ci.org/cesario/activevalidators.png)](http://travis-ci.org/cesario/activevalidators)
2
2
  ================
3
3
 
4
4
  Collection of ActiveModel/ActiveRecord validations
@@ -12,6 +12,7 @@ In your Gemfile ( >>= 1.1.0 ):
12
12
 
13
13
  In your models, the gem provides new validators like `email`, or `url`:
14
14
 
15
+ ```ruby
15
16
  class User
16
17
  validates :email_address, :email => true
17
18
  validates :link_url, :url => true
@@ -38,6 +39,7 @@ In your models, the gem provides new validators like `email`, or `url`:
38
39
  end
39
40
 
40
41
  class Account
42
+ validates :any_card, :credit_card => true
41
43
  validates :visa_card, :credit_card => { :type => :visa }
42
44
  validates :credit_card, :credit_card => { :type => :any }
43
45
  end
@@ -45,7 +47,7 @@ In your models, the gem provides new validators like `email`, or `url`:
45
47
  class Order
46
48
  validates :tracking_num, :tracking_number => { :carrier => :ups }
47
49
  end
48
-
50
+ ```
49
51
 
50
52
  Exhaustive list of supported validators and their implementation:
51
53
 
@@ -3,7 +3,8 @@ module ActiveModel
3
3
 
4
4
  class CreditCardValidator < EachValidator
5
5
  def validate_each(record, attribute, value)
6
- record.errors.add(attribute) unless Luhn.valid?(options[:type], sanitize_card(value))
6
+ type = options.fetch(:type, :any)
7
+ record.errors.add(attribute) if value.blank? || !Luhn.valid?(type, sanitize_card(value))
7
8
  end
8
9
 
9
10
  def sanitize_card(value)
@@ -23,6 +24,10 @@ module ActiveModel
23
24
  self.luhn_valid?(number) and !(number !~ /^5[1-5].{14}/)
24
25
  end
25
26
 
27
+ class << self
28
+ alias :master_card? :mastercard?
29
+ end
30
+
26
31
  def self.visa?(number)
27
32
  self.luhn_valid?(number) and !(number !~ /^4.{15}/)
28
33
  end
@@ -31,6 +36,15 @@ module ActiveModel
31
36
  self.luhn_valid?(number) and !(number !~ /^3[47].{13}/)
32
37
  end
33
38
 
39
+ [:diners_club, :en_route, :discover, :jcb, :carte_blanche, :switch,
40
+ :solo, :laser].each do |card_type|
41
+ class_eval <<-VALIDATOR, __FILE__, __LINE__ + 1
42
+ def self.#{card_type}?(number)
43
+ self.luhn_valid?(number)
44
+ end
45
+ VALIDATOR
46
+ end
47
+
34
48
  def self.luhn_valid?(s)
35
49
  return false unless s && s.is_a?(String)
36
50
  return false if s.empty?
@@ -49,7 +63,6 @@ module ActiveModel
49
63
  end
50
64
  } % 10 == 0
51
65
  end
52
-
53
66
  end
54
67
  end
55
68
 
@@ -2,7 +2,7 @@ module ActiveModel
2
2
  module Validations
3
3
  class IpValidator < EachValidator
4
4
  def validate_each(record, attribute, value)
5
- record.errors.add(attribute) unless regex.match(value)
5
+ record.errors.add(attribute) if value.blank? || !regex.match(value)
6
6
  end
7
7
 
8
8
  def check_validity!
@@ -4,9 +4,7 @@ module ActiveModel
4
4
  def validate_each(record, attribute, value)
5
5
  @value = value
6
6
  @formats = PhoneValidator.known_formats[options[:country]] || PhoneValidator.known_formats[:us]
7
- unless matches_any?
8
- record.errors.add(attribute)
9
- end
7
+ record.errors.add(attribute) if value.blank? || !matches_any?
10
8
  end
11
9
 
12
10
  def self.known_formats
@@ -6,7 +6,7 @@ module ActiveModel
6
6
  country = options[:country] || :us
7
7
  @formats = PostalCodeValidator.known_formats[country]
8
8
  raise "No known postal code formats for country #{country}" unless @formats
9
- record.errors.add(attribute) unless matches_any?
9
+ record.errors.add(attribute) if value.blank? || !matches_any?
10
10
  end
11
11
 
12
12
  def self.known_formats
@@ -6,7 +6,7 @@ module ActiveModel
6
6
  raise "Carrier option required" unless carrier
7
7
  method = "valid_#{carrier.to_s}?"
8
8
  raise "Tracking number validation not supported for carrier #{carrier}" unless self.respond_to?(method)
9
- record.errors.add(attribute) unless self.send(method, value)
9
+ record.errors.add(attribute) if value.blank? || !self.send(method, value)
10
10
  end
11
11
 
12
12
  # UPS:
@@ -1,8 +1,13 @@
1
1
  module ActiveModel
2
2
  module Validations
3
3
  class UrlValidator < EachValidator
4
+ class << self
5
+ attr_accessor :url_regex
6
+ end
7
+ # Damn complex regex found on GWave https://wave.google.com/wave/?pli=1#restored:wave:googlewave.com!w%252BsFbGJUukA
8
+ self.url_regex = /^(?#Protocol)(?:(?:ht|f)tp(?:s?)\:\/\/|~\/|\/)?(?#Username:Password)(?:\w+:\w+@)?(?#Subdomains)(?:(?:[-\w]+\.)+(?#TopLevel Domains)(?:com|org|net|gov|mil|biz|info|mobi|name|aero|jobs|museum|travel|[a-z]{2}))(?#Port)(?::[\d]{1,5})?(?#Directories)(?:(?:(?:\/(?:[-\w~!$+|.,=]|%[a-f\d]{2})+)+|\/)+|\?|#)?(?#Query)(?:(?:\?(?:[-\w~!$+|.,*:]|%[a-f\d{2}])+=?(?:[-\w~!$+|.,*:=]|%[a-f\d]{2})*)(?:&(?:[-\w~!$+|.,*:]|%[a-f\d{2}])+=?(?:[-\w~!$+|.,*:=]|%[a-f\d]{2})*)*)*(?#Anchor)(?:#(?:[-\w~!$+|.,*:=]|%[a-f\d]{2})*)?$/
4
9
  def validate_each(record, attribute, value)
5
- unless value =~ /^https?:\/\/(?i)[a-z0-9]+([-.]{1}[a-z0-9]+)*.[a-z]{2,5}(([0-9]{1,5})?\/.*)?$/
10
+ unless value =~ self.class.url_regex
6
11
  record.errors.add(attribute)
7
12
  end
8
13
  end
@@ -1,4 +1,4 @@
1
1
  # encoding: utf-8
2
2
  module ActiveValidators
3
- VERSION = '1.6.0'
3
+ VERSION = '1.7.0'
4
4
  end
@@ -1,26 +1,18 @@
1
- require 'active_support'
2
1
  require 'active_model'
3
- require 'active_record'
4
- require 'active_support/all'
5
- require 'active_model/validations'
6
2
 
7
3
  module ActiveModel
8
4
  module Validations
9
- extend ActiveSupport::Autoload
10
-
11
5
  def self.activevalidators
12
- ['Email','Url','RespondTo','Phone','Slug','Ip','CreditCard','Date','Password','Twitter','PostalCode',
13
- 'TrackingNumber']
6
+ %w(email url respond_to phone slug ip credit_card date password twitter postal_code tracking_number)
14
7
  end
15
8
 
16
- #Eager autoload the library's validators into AR::Validations
17
9
  activevalidators.each do |validator_name|
18
- autoload validator_name+'Validator'
10
+ require "active_model/validations/#{validator_name}_validator"
19
11
  end
20
12
 
21
13
  #Defines methods like validates_credit_card
22
14
  module HelperMethods
23
- ActiveModel::Validations.activevalidators.map(&:underscore).each do |validator|
15
+ ActiveModel::Validations.activevalidators.each do |validator|
24
16
  define_method('validates_'+validator) do |*fields|
25
17
  options ||= (fields.delete fields.find { |f| f.kind_of? Hash}) || true
26
18
  args = fields.push({ validator => options })
@@ -29,26 +29,43 @@ describe "Credit Card Validation" do
29
29
  }
30
30
 
31
31
  VALID_CARDS.each_pair do |card, number|
32
- it "accepts #{card} valid cards" do
33
- subject = build_card_record :card => number
34
- subject.valid?.must_equal true
35
- subject.errors.size.must_equal 0
32
+ describe "it accepts #{card} cards" do
33
+ it "using a specific card type" do
34
+ subject = build_card_record({:card => number}, {:type => card})
35
+ assert card_is_valid?(subject)
36
+ end
37
+ it "using :credit_card => { :type => :any }" do
38
+ subject = build_card_record({:card => number}, {:type => :any})
39
+ assert card_is_valid?(subject)
40
+ end
41
+ it "using :credit_card => true" do
42
+ subject = build_card_record({:card => number}, true)
43
+ assert card_is_valid?(subject)
44
+ end
36
45
  end
37
46
  end
38
47
 
39
48
  describe "for invalid cards" do
40
49
  it "rejects invalid cards and generates an error message of type invalid" do
41
50
  subject = build_card_record :card => '99999'
42
- subject.valid?.must_equal false
43
- subject.errors.size.must_equal 1
44
-
45
- subject.errors[:card].include?(subject.errors.generate_message(:card, :invalid)).must_equal true
51
+ assert card_is_invalid?(subject)
46
52
  end
47
53
  end
48
54
 
49
- def build_card_record(attrs = {})
55
+ def build_card_record(attrs = {}, validator = {:type => :any})
50
56
  TestRecord.reset_callbacks(:validate)
51
- TestRecord.validates :card, :credit_card => { :type => :any }
57
+ TestRecord.validates :card, :credit_card => validator
52
58
  TestRecord.new attrs
53
59
  end
60
+
61
+ def card_is_valid?(subject)
62
+ subject.valid?.must_equal true
63
+ subject.errors.size.must_equal 0
64
+ end
65
+
66
+ def card_is_invalid?(subject)
67
+ subject.valid?.must_equal false
68
+ subject.errors.size.must_equal 1
69
+ subject.errors[:card].include?(subject.errors.generate_message(:card, :invalid)).must_equal true
70
+ end
54
71
  end
@@ -7,18 +7,33 @@ describe "Url Validation" do
7
7
  TestRecord.new
8
8
  end
9
9
 
10
- it "accepts valid urls" do
11
- subject = build_url_record
12
- subject.url = 'http://www.verrot.fr'
13
- subject.valid?.must_equal true
14
- subject.errors.size.must_equal 0
15
- end
10
+ describe "valid urls" do
11
+ it "accepts urls without port number" do
12
+ subject = build_url_record
13
+ subject.url = 'http://www.verrot.fr'
14
+ subject.valid?.must_equal true
15
+ subject.errors.size.must_equal 0
16
+ end
17
+
18
+ it "accepts urls with port number" do
19
+ subject = build_url_record
20
+ subject.url = 'http://www.verrot.fr:1234'
21
+ subject.valid?.must_equal true
22
+ subject.errors.size.must_equal 0
23
+ end
16
24
 
17
- it "accepts valid SSL urls" do
18
- subject = build_url_record
19
- subject.url = 'https://www.verrot.fr'
20
- subject.valid?.must_equal true
21
- subject.errors.size.must_equal 0
25
+ it "accepts urls with basic auth" do
26
+ subject = build_url_record
27
+ subject.url = 'http://foo:bar@www.verrot.fr'
28
+ subject.valid?.must_equal true
29
+ subject.errors.size.must_equal 0
30
+ end
31
+ it "accepts valid SSL urls" do
32
+ subject = build_url_record
33
+ subject.url = 'https://www.verrot.fr'
34
+ subject.valid?.must_equal true
35
+ subject.errors.size.must_equal 0
36
+ end
22
37
  end
23
38
 
24
39
  describe "for invalid urls" do
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: activevalidators
3
3
  version: !ruby/object:Gem::Version
4
- hash: 15
4
+ hash: 11
5
5
  prerelease:
6
6
  segments:
7
7
  - 1
8
- - 6
8
+ - 7
9
9
  - 0
10
- version: 1.6.0
10
+ version: 1.7.0
11
11
  platform: ruby
12
12
  authors:
13
13
  - Franck Verrot
@@ -20,7 +20,7 @@ autorequire:
20
20
  bindir: bin
21
21
  cert_chain: []
22
22
 
23
- date: 2011-09-09 00:00:00 Z
23
+ date: 2011-09-27 00:00:00 Z
24
24
  dependencies:
25
25
  - !ruby/object:Gem::Dependency
26
26
  name: bundler