not-naughty 0.6.0 → 0.6.1

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/CHANGELOG.rdoc CHANGED
@@ -1,3 +1,8 @@
1
+ === 0.6.1 (2008-10-10)
2
+ * builder/validation cleanups
3
+ * added gemspecs for github
4
+ * added support for predefined format expressions [resolves:#19814]
5
+
1
6
  === 0.6 (2008-10-08)
2
7
  * fixed Rakefile
3
8
  * removed whitespaces
data/Rakefile CHANGED
@@ -9,7 +9,7 @@ include FileUtils
9
9
  # Configuration
10
10
  ##############################################################################
11
11
  NAME = "not-naughty"
12
- VERS = "0.6.0"
12
+ VERS = "0.6.1"
13
13
  CLEAN.include %w[ pkg doc coverage ]
14
14
  RDOC_OPTS = [
15
15
  "--quiet",
@@ -39,7 +39,7 @@ task :doc_rforge => [:doc]
39
39
 
40
40
  desc "Update docs and upload to rubyforge.org"
41
41
  task :doc_rforge do
42
- sh %{scp -r doc/rdoc/* boof@rubyforge.org:/var/www/gforge-projects/not-naughty}
42
+ sh %{scp -r doc/* boof@rubyforge.org:/var/www/gforge-projects/not-naughty}
43
43
  end
44
44
 
45
45
  ##############################################################################
@@ -40,26 +40,25 @@ module NotNaughty
40
40
 
41
41
  class ValidationDelegator < SimpleDelegator #:nodoc:all
42
42
  def initialize(receiver, *params)
43
- @_sd_obj_opts = params.extract_options!
44
- @_sd_obj_params = params
43
+ @_sd_obj_opts = params.extract_options!
44
+ @_sd_obj_attributes = params
45
45
 
46
46
  super receiver
47
47
  end
48
48
  def method_missing(method_sym, *params) #:nodoc:
49
- method_sym, params = unless @_sd_obj_params.empty?
50
- opts = @_sd_obj_opts.update params.extract_options!
51
- [:"validates_#{method_sym}_of", @_sd_obj_params + [opts]]
49
+ valid = @_sd_obj_opts.merge params.extract_options!
50
+ valid = Marshal.load Marshal.dump(valid)
51
+
52
+ method_sym, params = unless @_sd_obj_attributes.empty?
53
+ [:"validates_#{ method_sym }_of", @_sd_obj_attributes + [valid]]
52
54
  else
53
- opts = @_sd_obj_opts.update params.extract_options!
54
- [:"validates_#{method_sym}", params + [opts]]
55
+ [:"validates_#{ method_sym }", params + [valid]]
55
56
  end
56
57
 
57
58
  if @_sd_obj.respond_to? method_sym
58
- @_sd_obj.send(method_sym, *params)
59
- return true
59
+ @_sd_obj.send(method_sym, *params); true
60
60
  else
61
- raise NoMethodError,
62
- "unable to evaluate ´#{method_sym}(*#{params.inspect})'"
61
+ raise NoMethodError, "unable to evaluate ´#{method_sym}(#{ params.map {|p|p.inspect} * ','})'"
63
62
  end
64
63
  end
65
64
  end
@@ -20,22 +20,30 @@ module NotNaughty
20
20
  # obj.errors.on(:to_s).any? # => true
21
21
  class ConfirmationValidation < Validation
22
22
 
23
- def initialize(opts, attributes) #:nodoc:
24
- __message = opts[:message] || '#{"%s".humanize} could not be confirmed.'
23
+ def initialize(valid, attributes) #:nodoc:
24
+ valid[:message] ||= '%s could not be confirmed.'
25
25
 
26
- if opts[:allow_blank] or opts[:allow_nil]
27
- __allow = if opts[:allow_blank] then :blank? else :nil? end
28
- super opts, attributes do |o, a, v|
29
- o.errors.add a, __message unless
30
- v.send __allow or o.send(:"#{a}_confirmation").eql? v
31
- end
26
+ if valid[:allow_blank] || valid[:allow_nil]
27
+ valid[:allow] = valid[:allow_blank] ? :blank? : :nil?
28
+ super valid, attributes, &confirmation_block_with_exception(valid)
32
29
  else
33
- super opts, attributes do |o, a, v|
34
- o.errors.add a, __message unless
35
- o.send(:"#{a}_confirmation").eql? v
36
- end
30
+ super valid, attributes, &confirmation_block(valid)
37
31
  end
38
32
  end
39
33
 
34
+ protected
35
+ def confirmation_block_with_exception(valid)
36
+ proc do |obj, attr, value|
37
+ value.send valid[:allow] or
38
+ obj.send(:"#{ attr }_confirmation") == value or
39
+ obj.errors.add attr, valid[:message]
40
+ end
41
+ end
42
+ def confirmation_block(valid)
43
+ proc do |obj, attr, value|
44
+ obj.send(:"#{ attr }_confirmation") == value or
45
+ obj.errors.add attr, valid[:message]
46
+ end
47
+ end
40
48
  end
41
49
  end
@@ -16,38 +16,54 @@ module NotNaughty
16
16
  # obj = 'abc'
17
17
  # def obj.errors() @errors ||= NotNauthy::Errors.new end
18
18
  #
19
- # FormatValidation.new({:with => /[a-z]/}, :to_s).call obj, :to_s, 'abc'
19
+ # FormatValidation.new({:with => /[a-z]/}, :to_s).call obj, :to_s, obj
20
20
  # obj.errors.on(:to_s).any? # => false
21
21
  #
22
- # FormatValidation.new({:with => /[A-Z]/}, :to_s).call obj, :to_s, 'abc'
22
+ # FormatValidation.new({:with => /[A-Z]/}, :to_s).call obj, :to_s, obj
23
23
  # obj.errors.on(:to_s) # => ["Format of to_s does not match."]
24
+ #
25
+ # <b>Use predefined format expressions:</b>
26
+ #
27
+ # obj = 'Valid Address <foo@bar.baz>'
28
+ # def obj.errors() @errors ||= NotNauthy::Errors.new end
29
+ #
30
+ # FormatValidation.new({:with => :email}, :to_s).call obj, :to_s, obj
31
+ # obj.errors.on(:to_s).any? # => false
24
32
  class FormatValidation < Validation
25
33
 
26
34
  # Predefined matchers.
27
- DEFINITIONS = {
35
+ PREDEFINED = {
28
36
  :email => /[a-z0-9!#\$%&'*+\/=?^_`{|}~-]+(?:\.[a-z0-9!#\$%&'*+\/=?^_`{|}~-]+)*@(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?/,
29
37
  :ip => /(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)/
30
38
  }
31
39
 
32
- def initialize(opts, attributes) #:nodoc:
33
- format_matcher = if Symbol === opts[:with] then DEFINITIONS[opts[:with]]
34
- elsif opts[:with].respond_to? :match then opts[:with]
35
- end or raise ArgumentError, "#{ opts[:with].inspect } doesn't :match"
36
-
37
- msg = opts[:message] || '%s does not match format.'
40
+ def initialize(valid, attributes) #:nodoc:
41
+ valid[:with] = PREDEFINED.fetch valid[:with] if valid[:with].is_a? Symbol
42
+ valid[:with].respond_to? :match or
43
+ raise ArgumentError, "#{ valid[:with].inspect } doesn't :match"
38
44
 
39
- if opts[:allow_blank] or opts[:allow_nil]
40
- pass = opts[:allow_blank] ? :blank? : :nil?
45
+ valid[:message] ||= '%s does not match format.'
41
46
 
42
- super opts, attributes do |obj, attr, val|
43
- val.send pass or format_matcher.match val or
44
- obj.errors.add attr, msg
45
- end
47
+ if valid[:allow_blank] || valid[:allow_nil]
48
+ valid[:allow] = valid[:allow_blank] ? :blank? : :nil?
49
+ super valid, attributes, &matching_block_with_exception(valid)
46
50
  else
47
- super opts, attributes do |obj, attr, val|
48
- format_matcher.match val or
49
- obj.errors.add attr, msg
50
- end
51
+ super valid, attributes, &matching_block(valid)
52
+ end
53
+ end
54
+
55
+ protected
56
+ def matching_block_with_exception(valid)
57
+ proc do |obj, attr, value|
58
+ value.send valid[:allow] or
59
+ valid[:with].match value or
60
+ obj.errors.add attr, valid[:message]
61
+ end
62
+ end
63
+ def matching_block(valid)
64
+ proc do |obj, attr, value|
65
+ valid[:with].match value or
66
+ obj.errors.add attr, valid[:message]
51
67
  end
52
68
  end
53
69
 
@@ -35,60 +35,56 @@ module NotNaughty
35
35
  # LengthValidation.new({:within => 1..4}, :to_a).
36
36
  # call obj, :to_a, %w[a sentence with five words]
37
37
  # obj.errors.on(:to_s).any? # => true
38
+ #
39
+ # I'm sorry for using eval here...
38
40
  class LengthValidation < Validation
39
41
 
40
- def initialize(opts, attributes) #:nodoc:
42
+ TEMPLATE = <<-BLOCK
43
+ proc do |obj, attr, value|
44
+ value.%s or %s value.length or
45
+ obj.errors.add attr, %s
46
+ end
47
+ BLOCK
41
48
 
42
- block = build_block opts
49
+ def initialize(valid, attributes) #:nodoc:
50
+ super valid, attributes, &build_block(valid)
51
+ end
43
52
 
44
- if opts[:allow_blank]
45
- super opts, attributes do |o, a, v|
46
- block[o, a, v] unless v.blank?
47
- end
53
+ protected
54
+ def build_block(valid) #:nodoc:
55
+ if valid[:is] then is_block valid
56
+ elsif valid[:within] or valid[:minimum] && valid[:maximum] then within_block valid
57
+ elsif valid[:minimum] then minimum_block valid
58
+ elsif valid[:maximum] then maximum_block valid
48
59
  else
49
- super opts, attributes do |o, a, v|
50
- block[o, a, v] unless v.nil?
51
- end
60
+ raise ArgumentError, 'no boundary given'
52
61
  end
53
62
  end
54
63
 
55
- protected
56
- def build_block(opts) #:nodoc:
57
- if __length = opts[:is]
58
- __message = opts[:message] ||
59
- "Length of %s is not equal to #{__length}."
60
- proc do |o, a, v|
61
- o.errors.add a, __message unless __length.eql? v.length
62
- end
63
- elsif opts[:within] or opts[:minimum] && opts[:maximum]
64
- __range = opts[:within]
65
- __range ||= Range.new opts[:minimum], opts[:maximum]
64
+ def is_block(valid)
65
+ valid[:message] ||= "Length of %s is not equal to #{ valid[:is] }."
66
66
 
67
- __message = opts[:message] ||
68
- "Length of %s is not within #{__range.first} and #{__range.last}."
67
+ eval TEMPLATE % [ valid[:allow_blank] ? :blank? : :nil?,
68
+ "#{ valid[:is].inspect } ==", valid[:message].inspect ]
69
+ end
70
+ def within_block(valid)
71
+ valid[:within] ||= Range.new valid[:minimum], valid[:maximum]
72
+ valid[:message] ||= "Length of %s is not within #{ valid[:within].min } and #{ valid[:within].max }."
69
73
 
70
- proc do |o, a, v|
71
- o.errors.add a, __message unless __range.include? v.length
72
- end
73
- elsif opts[:minimum]
74
- __boundary = opts[:minimum]
75
- __message = opts[:message] ||
76
- "Length of %s is smaller than #{__boundary}."
74
+ eval TEMPLATE % [ valid[:allow_blank] ? :blank? : :nil?,
75
+ "(#{ valid[:within].inspect }).include?", valid[:message].inspect ]
76
+ end
77
+ def minimum_block(valid)
78
+ valid[:message] ||= "Length of %s is less than #{ valid[:minimum] }."
77
79
 
78
- proc do |o, a, v|
79
- o.errors.add a, __message unless __boundary <= v.length
80
- end
81
- elsif opts[:maximum]
82
- __boundary = opts[:maximum]
83
- __message = opts[:message] ||
84
- "Length of %s is greater than #{__boundary}."
80
+ eval TEMPLATE % [ valid[:allow_blank] ? :blank? : :nil?,
81
+ "#{ valid[:minimum].inspect } <=", valid[:message].inspect ]
82
+ end
83
+ def maximum_block(valid)
84
+ valid[:message] ||= "Length of %s is greater than #{ valid[:maximum] }."
85
85
 
86
- proc do |o, a, v|
87
- o.errors.add a, __message unless __boundary >= v.length
88
- end
89
- else
90
- raise ArgumentError, 'no boundary given'
91
- end
86
+ eval TEMPLATE % [ valid[:allow_blank] ? :blank? : :nil?,
87
+ "#{ valid[:maximum].inspect } >=", valid[:message].inspect ]
92
88
  end
93
89
 
94
90
  end
@@ -27,16 +27,16 @@ module NotNaughty
27
27
  # obj.errors.on(:to_s).any? # => true
28
28
  class NumericalityValidation < FormatValidation
29
29
 
30
- def initialize(opts, attributes) #:nodoc:
31
- opts[:with] = if opts[:only_integer]
32
- opts[:message] ||= '#{"%s".humanize} is not an integer.'
30
+ def initialize(valid, attributes) #:nodoc:
31
+ valid[:with] = if valid[:only_integer]
32
+ valid[:message] ||= '%s is not an integer.'
33
33
  /^[+-]?\d+$/
34
34
  else
35
- opts[:message] ||= '#{"%s".humanize} is not a number.'
35
+ valid[:message] ||= '%s is not a number.'
36
36
  /^[+-]?\d*\.?\d+$/
37
37
  end
38
38
 
39
- super opts, attributes
39
+ super valid, attributes
40
40
  end
41
41
 
42
42
  end
@@ -19,11 +19,12 @@ module NotNaughty
19
19
  # obj.errors.on(:to_s) # => ["To s is not present."]
20
20
  class PresenceValidation < Validation
21
21
 
22
- def initialize(opts, attributes) #:nodoc:
23
- __message = opts[:message] || '#{"%s".humanize} is not present.'
22
+ def initialize(valid, attributes) #:nodoc:
23
+ valid[:message] ||= '%s is not present.'
24
24
 
25
- super opts, attributes do |o, a, v|
26
- o.errors.add a, __message if v.blank?
25
+ super valid, attributes do |obj, attr, value|
26
+ value.blank? and
27
+ obj.errors.add attr, valid[:message]
27
28
  end
28
29
  end
29
30
 
data/spec/spec_helper.rb CHANGED
@@ -1,4 +1,7 @@
1
- require File.dirname(__FILE__) + '/../lib/not_naughty.rb'
1
+ require 'rubygems'
2
+ require 'spec'
3
+
4
+ require "#{ File.dirname __FILE__ }/../lib/not_naughty.rb"
2
5
 
3
6
  def subject() ::NotNaughty end
4
7
  def h(something)
@@ -94,10 +94,10 @@ describe FormatExample do
94
94
 
95
95
  before(:each) { @example = FormatExample.clone }
96
96
 
97
- it "claims to match 99% of all e-mail addresses out there..." do
97
+ it "claims to match 99.9% of all e-mail addresses out there..." do
98
98
  # Regexp was taken from: http://www.regular-expressions.info/email.html
99
99
  @example.validates_format_of :email,
100
- :with => /\b[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,4}\b/i
100
+ :with => :email
101
101
  @example.new('"Foo Bar" <foo@bar.com>').should be_valid
102
102
  @example.new('foo@bar.com').should be_valid
103
103
  @example.new('foobarcom').should_not be_valid
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: not-naughty
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.6.0
4
+ version: 0.6.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - "Florian A\xC3\x9Fmann"
@@ -9,7 +9,7 @@ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
11
 
12
- date: 2008-10-08 00:00:00 +02:00
12
+ date: 2008-10-10 00:00:00 +02:00
13
13
  default_executable:
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency