not-naughty 0.6.1 → 0.6.2
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 +6 -0
- data/Rakefile +1 -1
- data/lib/not_naughty.rb +5 -5
- data/lib/not_naughty/class_methods.rb +78 -0
- data/lib/not_naughty/validation.rb +11 -5
- data/spec/{builder_spec.rb → class_methods_spec.rb} +11 -25
- data/spec/not_naughty_spec.rb +5 -5
- data/spec/spec_helper.rb +1 -0
- data/spec/validation_spec.rb +3 -4
- metadata +4 -4
- data/lib/not_naughty/builder.rb +0 -67
data/CHANGELOG.rdoc
CHANGED
@@ -1,3 +1,9 @@
|
|
1
|
+
=== 0.6.2 (2008-10-31)
|
2
|
+
* NotNaughty::Builder is now NotNaughty::ClassMethods
|
3
|
+
* NotNaughty::Builder::ValidationDelegator is now NotNaughty::ClassMethods::Builder
|
4
|
+
* NotNaughty::ClassMethods::Builder does not inherit from Delegation anymore, so { format :with => /rx/ } works
|
5
|
+
* NotNaughty::Validation loads validations from directories listed in load_paths
|
6
|
+
|
1
7
|
=== 0.6.1 (2008-10-10)
|
2
8
|
* builder/validation cleanups
|
3
9
|
* added gemspecs for github
|
data/Rakefile
CHANGED
data/lib/not_naughty.rb
CHANGED
@@ -1,4 +1,3 @@
|
|
1
|
-
require 'delegate'
|
2
1
|
require 'forwardable'
|
3
2
|
require 'observer'
|
4
3
|
|
@@ -12,19 +11,20 @@ require 'core_extensions'
|
|
12
11
|
module NotNaughty
|
13
12
|
require 'not_naughty/validator'
|
14
13
|
|
15
|
-
require 'not_naughty/
|
14
|
+
require 'not_naughty/class_methods'
|
16
15
|
require 'not_naughty/validation'
|
17
|
-
Validation.add_observer
|
16
|
+
Validation.add_observer ClassMethods
|
18
17
|
|
19
18
|
require 'not_naughty/violation'
|
20
19
|
require 'not_naughty/error_handler'
|
21
20
|
require 'not_naughty/instance_methods'
|
22
21
|
|
23
|
-
# Extended classes get NotNaughty::
|
22
|
+
# Extended classes get NotNaughty::ClassMethods and
|
23
|
+
# NotNaughty::InstanceMethods.
|
24
24
|
def self.extended(base)
|
25
25
|
base.instance_eval do
|
26
26
|
include InstanceMethods
|
27
|
-
extend
|
27
|
+
extend ClassMethods
|
28
28
|
end
|
29
29
|
end
|
30
30
|
|
@@ -0,0 +1,78 @@
|
|
1
|
+
module NotNaughty
|
2
|
+
module ClassMethods
|
3
|
+
|
4
|
+
def self.update(validation) # :nodoc:
|
5
|
+
if basename = validation.name[/([^:]+)Validation$/, 1]
|
6
|
+
define_method 'validates_%s_of' % basename.downcase do |*params|
|
7
|
+
validator.add_validation(validation, *params)
|
8
|
+
end
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
# == Syntactic sugar.
|
13
|
+
#
|
14
|
+
# <b>Example:</b>
|
15
|
+
# validates { presence_of :example, :if => :reading? }
|
16
|
+
# # => validate_presence_of :example, :if => :reading?
|
17
|
+
# validates(:name) { presence and length :minimum => 6 }
|
18
|
+
# # => validates_presence_of :name
|
19
|
+
# validates_length_of :name, :minimum => 6
|
20
|
+
# validates(:temp, :if => water?) { value :lt => 100 }
|
21
|
+
# # => validates_value_of :temp, :lt => 100, :if => water?
|
22
|
+
def validates(*params, &block)
|
23
|
+
Builder.new(self, *params).instance_eval(&block)
|
24
|
+
end
|
25
|
+
|
26
|
+
# Allows adding validations the legacy way.
|
27
|
+
def validates_each(*attributes, &block)
|
28
|
+
validator.add_validation(*attributes, &block)
|
29
|
+
end
|
30
|
+
|
31
|
+
# With this you get syntactical sugar for all descendants of Validation
|
32
|
+
# see validates for examples.
|
33
|
+
class Builder
|
34
|
+
|
35
|
+
def initialize(klass, *params) # :nodoc:
|
36
|
+
@_vd_obj = klass
|
37
|
+
@_vd_obj_opts = params.extract_options!
|
38
|
+
@_vd_obj_attrs = params
|
39
|
+
|
40
|
+
methods = ClassMethods.instance_methods(false).grep(/^validates_.+_of$/)
|
41
|
+
|
42
|
+
if @_vd_obj_attrs.empty?
|
43
|
+
for method in methods
|
44
|
+
eval <<-EOS
|
45
|
+
def self.#{ method[/^validates_(.+)$/, 1] }(*params)
|
46
|
+
params << @_vd_obj_opts.merge(params.extract_options!)
|
47
|
+
|
48
|
+
begin
|
49
|
+
@_vd_obj.__send__(:#{ method }, *params)
|
50
|
+
rescue Exception
|
51
|
+
$@.delete_if { |s| /^\\(eval\\):/ =~ s }
|
52
|
+
raise
|
53
|
+
end
|
54
|
+
end
|
55
|
+
EOS
|
56
|
+
end
|
57
|
+
else
|
58
|
+
for method in methods
|
59
|
+
eval <<-EOS
|
60
|
+
def self.#{ method[/^validates_(.+)_of$/, 1] }(*args)
|
61
|
+
params = @_vd_obj_attrs.dup
|
62
|
+
params << @_vd_obj_opts.merge(args.extract_options!)
|
63
|
+
|
64
|
+
begin
|
65
|
+
@_vd_obj.__send__(:#{ method }, *params)
|
66
|
+
rescue Exception
|
67
|
+
$@.delete_if { |s| /^\\(eval\\):/ =~ s }
|
68
|
+
raise
|
69
|
+
end
|
70
|
+
end
|
71
|
+
EOS
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
end
|
78
|
+
end
|
@@ -5,14 +5,20 @@ module NotNaughty
|
|
5
5
|
# See new for more information.
|
6
6
|
class Validation
|
7
7
|
|
8
|
-
|
9
|
-
|
10
|
-
|
8
|
+
# Returns array of paths which are scanned for validations by load.
|
9
|
+
def self.load_paths
|
10
|
+
@load_paths
|
11
|
+
end
|
12
|
+
@load_paths = [File.join(%W[#{ File.dirname __FILE__ } validations])]
|
13
|
+
PATTERN = File.join %w[%s ** %s_validation.rb]
|
11
14
|
|
12
|
-
# Loads validations.
|
15
|
+
# Loads validations from load_paths.
|
13
16
|
def self.load(*validations)
|
14
17
|
validations.each do |validation|
|
15
|
-
|
18
|
+
@load_paths.each do |load_path|
|
19
|
+
pattern = PATTERN % [load_path, validation]
|
20
|
+
Dir[pattern].each { |validation_path| require validation_path }
|
21
|
+
end
|
16
22
|
end
|
17
23
|
end
|
18
24
|
|
@@ -1,6 +1,6 @@
|
|
1
1
|
require "#{ File.dirname(__FILE__) }/spec_helper.rb"
|
2
2
|
|
3
|
-
describe subject::
|
3
|
+
describe subject::ClassMethods do
|
4
4
|
|
5
5
|
before(:each) do
|
6
6
|
@validatable = Class.new(Object) do
|
@@ -10,14 +10,12 @@ describe subject::Builder do
|
|
10
10
|
def validation_state() state end
|
11
11
|
end
|
12
12
|
@validatable.validator = mock 'Validator'
|
13
|
-
@validatable.extend(subject::
|
13
|
+
@validatable.extend(subject::ClassMethods)
|
14
14
|
end
|
15
15
|
|
16
16
|
it "should have a delegator class" do
|
17
|
-
subject::
|
18
|
-
should include('
|
19
|
-
subject::Builder.const_get('ValidationDelegator').
|
20
|
-
should < SimpleDelegator
|
17
|
+
subject::ClassMethods.constants.
|
18
|
+
should include('Builder')
|
21
19
|
end
|
22
20
|
it "should provide the :validates builder method" do
|
23
21
|
@validatable.should respond_to(:validates)
|
@@ -36,9 +34,12 @@ describe subject::Builder do
|
|
36
34
|
end
|
37
35
|
it "should add validation for :firstname and :lastname via :validates" do
|
38
36
|
@validatable.validator.should_receive(:add_validation).
|
39
|
-
with(NotNaughty::PresenceValidation, :firstname, :lastname, {})
|
37
|
+
with(NotNaughty::PresenceValidation, :firstname, :lastname, {})
|
40
38
|
@validatable.validates { presence_of :firstname, :lastname }
|
41
|
-
|
39
|
+
|
40
|
+
@validatable.validator.should_receive(:add_validation).
|
41
|
+
with(NotNaughty::FormatValidation, :firstname, :lastname, :with => /Hello World!/)
|
42
|
+
@validatable.validates(:firstname, :lastname) { format :with => /Hello World!/ }
|
42
43
|
end
|
43
44
|
it "should register validation" do
|
44
45
|
validation = Class.new(subject::Validation) do
|
@@ -54,23 +55,8 @@ describe subject::Builder do
|
|
54
55
|
end
|
55
56
|
it "should build the Validations with :validates_each" do
|
56
57
|
@validatable.validator = mock 'Validator'
|
57
|
-
@validatable.validator.
|
58
|
-
|
59
|
-
with(:a, :b)
|
60
|
-
@validatable.validates_each(:a, :b) {|o, a, v|}
|
61
|
-
|
62
|
-
pending 'expect a block'
|
63
|
-
end
|
64
|
-
it "should support :each in validates block" do
|
65
|
-
@validatable.validator = mock 'Validator'
|
66
|
-
@validatable.validator.
|
67
|
-
should_receive(:add_validation).
|
68
|
-
with(:a, :b, {})
|
69
|
-
@validatable.validates do
|
70
|
-
each(:a, :b) {|o, a, v|}
|
71
|
-
end
|
72
|
-
|
73
|
-
pending 'expect a block'
|
58
|
+
@validatable.validator.should_receive(:add_validation)
|
59
|
+
@validatable.validates_each
|
74
60
|
end
|
75
61
|
it "should raise a NoMethodError is builder method does not exist" do
|
76
62
|
lambda { @validatable.validates() { bunch_of :holy_crap } }.
|
data/spec/not_naughty_spec.rb
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
require "#{ File.dirname(__FILE__) }/spec_helper.rb"
|
2
2
|
|
3
|
-
module subject::
|
3
|
+
module subject::ClassMethods
|
4
4
|
def self.extended(base) end
|
5
5
|
end
|
6
6
|
module subject::InstanceMethods
|
@@ -12,7 +12,7 @@ describe subject do
|
|
12
12
|
it "should load necessary files" do
|
13
13
|
subject::should be_const_defined(:Validation)
|
14
14
|
subject::should be_const_defined(:Validator)
|
15
|
-
subject::should be_const_defined(:
|
15
|
+
subject::should be_const_defined(:ClassMethods)
|
16
16
|
subject::should be_const_defined(:InstanceMethods)
|
17
17
|
subject::should be_const_defined(:Violation)
|
18
18
|
end
|
@@ -31,7 +31,7 @@ describe subject do
|
|
31
31
|
it "should extend the receiver if validator is defined" do
|
32
32
|
validated = Class.new(Object)
|
33
33
|
|
34
|
-
subject::
|
34
|
+
subject::ClassMethods.should_receive(:extended).with(validated)
|
35
35
|
subject::InstanceMethods.should_receive(:included).with(validated)
|
36
36
|
|
37
37
|
validated.extend subject
|
@@ -74,9 +74,9 @@ describe subject do
|
|
74
74
|
instance.should_receive(:valid?).once.and_return(false)
|
75
75
|
instance.clone.should == false
|
76
76
|
end
|
77
|
-
it "should add
|
77
|
+
it "should add ClassMethods to Validation observers" do
|
78
78
|
subject::Validation.instance_variable_get(:@observer_peers).
|
79
|
-
should include(subject::
|
79
|
+
should include(subject::ClassMethods)
|
80
80
|
end
|
81
81
|
|
82
82
|
end
|
data/spec/spec_helper.rb
CHANGED
data/spec/validation_spec.rb
CHANGED
@@ -1,12 +1,11 @@
|
|
1
|
-
require "#{ File.dirname
|
1
|
+
require "#{ File.dirname __FILE__ }/spec_helper.rb"
|
2
2
|
|
3
3
|
describe subject::Validation do
|
4
4
|
|
5
5
|
it "should register validations if inherited" do
|
6
|
-
subject::
|
7
|
-
should_receive(:update).
|
6
|
+
subject::ClassMethods.
|
7
|
+
should_receive(:update).once.
|
8
8
|
with Class.new(subject::Validation)
|
9
|
-
pending 'This one kinda sucks...'
|
10
9
|
end
|
11
10
|
it "should build validations with block" do
|
12
11
|
block = proc {|o, a, v|}
|
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.
|
4
|
+
version: 0.6.2
|
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-
|
12
|
+
date: 2008-10-31 00:00:00 +01:00
|
13
13
|
default_executable:
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
@@ -36,7 +36,7 @@ files:
|
|
36
36
|
- COPYING
|
37
37
|
- README.rdoc
|
38
38
|
- Rakefile
|
39
|
-
- spec/
|
39
|
+
- spec/class_methods_spec.rb
|
40
40
|
- spec/error_handler_spec.rb
|
41
41
|
- spec/not_naughty_spec.rb
|
42
42
|
- spec/rcov.opts
|
@@ -48,7 +48,7 @@ files:
|
|
48
48
|
- spec/violation_spec.rb
|
49
49
|
- lib/core_extensions.rb
|
50
50
|
- lib/not_naughty
|
51
|
-
- lib/not_naughty/
|
51
|
+
- lib/not_naughty/class_methods.rb
|
52
52
|
- lib/not_naughty/error_handler.rb
|
53
53
|
- lib/not_naughty/instance_methods.rb
|
54
54
|
- lib/not_naughty/validation.rb
|
data/lib/not_naughty/builder.rb
DELETED
@@ -1,67 +0,0 @@
|
|
1
|
-
module NotNaughty
|
2
|
-
|
3
|
-
# == Builder that builds
|
4
|
-
#
|
5
|
-
# With this you get syntactical sugar for all descendants of Validation, see
|
6
|
-
# validates for examples.
|
7
|
-
module Builder
|
8
|
-
|
9
|
-
# Observer method that creates Validation builder methods.
|
10
|
-
#
|
11
|
-
# A Validation with the class name TestValidation will get the
|
12
|
-
# builder method <tt>validate_test_of</tt> that adds a validation via
|
13
|
-
# add_validation in the current <tt>validator</tt>.
|
14
|
-
def self.update(validation)
|
15
|
-
if basename = validation.name[/([^:]+)Validation$/, 1]
|
16
|
-
define_method 'validates_%s_of' % basename.downcase do |*params|
|
17
|
-
validator.add_validation(validation, *params)
|
18
|
-
end
|
19
|
-
end
|
20
|
-
end
|
21
|
-
|
22
|
-
# == Syntactic sugar.
|
23
|
-
#
|
24
|
-
# <b>Example:</b>
|
25
|
-
# validates { presence_of :example, :if => :reading? }
|
26
|
-
# # => validate_presence_of :example, :if => :reading?
|
27
|
-
# validates(:name) { presence and length :minimum => 6 }
|
28
|
-
# # => validates_presence_of :name
|
29
|
-
# validates_length_of :name, :minimum => 6
|
30
|
-
# validates(:temp, :if => water?) { value :lt => 100 }
|
31
|
-
# # => validates_value_of :temp, :lt => 100, :if => water?
|
32
|
-
def validates(*params, &block)
|
33
|
-
ValidationDelegator.new(self, *params).instance_eval(&block)
|
34
|
-
end
|
35
|
-
|
36
|
-
# Allows adding validations the legacy way.
|
37
|
-
def validates_each(*attributes, &block)
|
38
|
-
validator.add_validation(*attributes, &block)
|
39
|
-
end
|
40
|
-
|
41
|
-
class ValidationDelegator < SimpleDelegator #:nodoc:all
|
42
|
-
def initialize(receiver, *params)
|
43
|
-
@_sd_obj_opts = params.extract_options!
|
44
|
-
@_sd_obj_attributes = params
|
45
|
-
|
46
|
-
super receiver
|
47
|
-
end
|
48
|
-
def method_missing(method_sym, *params) #:nodoc:
|
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]]
|
54
|
-
else
|
55
|
-
[:"validates_#{ method_sym }", params + [valid]]
|
56
|
-
end
|
57
|
-
|
58
|
-
if @_sd_obj.respond_to? method_sym
|
59
|
-
@_sd_obj.send(method_sym, *params); true
|
60
|
-
else
|
61
|
-
raise NoMethodError, "unable to evaluate ´#{method_sym}(#{ params.map {|p|p.inspect} * ','})'"
|
62
|
-
end
|
63
|
-
end
|
64
|
-
end
|
65
|
-
|
66
|
-
end
|
67
|
-
end
|