params-validator 0.1.0 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
data/.gitignore CHANGED
@@ -1,4 +1,4 @@
1
1
  *.gem
2
2
  .bundle
3
- Gemfile.lock
3
+ .rvmrc
4
4
  pkg/*
data/Gemfile.lock ADDED
@@ -0,0 +1,24 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ params-validator (0.2.0)
5
+
6
+ GEM
7
+ remote: http://rubygems.org/
8
+ specs:
9
+ diff-lcs (1.1.2)
10
+ rspec (2.5.0)
11
+ rspec-core (~> 2.5.0)
12
+ rspec-expectations (~> 2.5.0)
13
+ rspec-mocks (~> 2.5.0)
14
+ rspec-core (2.5.1)
15
+ rspec-expectations (2.5.0)
16
+ diff-lcs (~> 1.1.2)
17
+ rspec-mocks (2.5.0)
18
+
19
+ PLATFORMS
20
+ ruby
21
+
22
+ DEPENDENCIES
23
+ params-validator!
24
+ rspec
data/README.md CHANGED
@@ -7,11 +7,24 @@ parameters in a method call.
7
7
 
8
8
  gem install params-validator
9
9
 
10
- # Requirementes
10
+ # Requirements
11
+
12
+ # v0.2.0 changes
13
+
14
+ - FEATURE: definition of validation rulesets inside the method, so it improves the code style including the validation as the first step in a method execution (suggested by [osuka](https://github.com/osuka))
15
+
16
+ - FIXED: If a method has a ruleset that defines all the parameters as optional, a nil argument
17
+ is allowed. On previous versions an ArgumentError exception was thrown
18
+
19
+ - FIXED: inheritance allowed. A method can define a more restrictive ruleset in a inherited method.
20
+
21
+ - FIXED: a method validation can be redefined, the first definition will not be used.
22
+
23
+ - MOVED: specs to folder ./spec
11
24
 
12
25
  # Usage
13
26
 
14
- * There are three ways of use:
27
+ * There are four ways of use:
15
28
 
16
29
  * Include validation rules inside the object:
17
30
 
@@ -80,8 +93,20 @@ parameters in a method call.
80
93
  obj.method1({:level => 1}) # This will execute successfully the method call
81
94
  obj.method2({:level => 1}) # This will raise an ArgumentError exception because :data parameter is missing
82
95
 
96
+ * Implicit validation: ruleset defined inside the method, kudos to [osuka](https://github.com/osuka)
97
+
98
+ require 'params-validator'
99
+ class MockObject
100
+ include ParamsValidator::ValidParams
101
+
102
+ def method1(args)
103
+ validate_method(args) do
104
+ level(Fixnum, :optional)
105
+ end
106
+ end
107
+ end
83
108
 
84
- * Client side validation (kudos to @drslump)
109
+ * Client side validation, kudos to [drslump](https://github.com/drslump)
85
110
 
86
111
  obj = ParamsValidator::Request.new
87
112
  obj[:data] = "this is a log"
data/Rakefile CHANGED
@@ -1,2 +1,14 @@
1
1
  require 'bundler'
2
+ require 'rake'
3
+ require 'rspec/core/rake_task'
4
+
2
5
  Bundler::GemHelper.install_tasks
6
+
7
+ desc 'Default: run specs.'
8
+ task :default => :spec
9
+
10
+ desc "Run all specs"
11
+
12
+ RSpec::Core::RakeTask.new do |t|
13
+ t.pattern = './spec/**/*_spec.rb'
14
+ end
@@ -25,7 +25,7 @@ module ParamsValidator
25
25
  def initialize(method_name, &block)
26
26
  @method_name = method_name
27
27
  @parameters = []
28
- block_given? and self.instance_eval &block
28
+ block_given? and self.instance_exec &block
29
29
  end
30
30
 
31
31
  # get mandatory parameters
@@ -41,7 +41,7 @@ module ParamsValidator
41
41
  # Execute validation block in this object scope
42
42
  #
43
43
  def block(&block)
44
- block_given? and self.instance_eval &block
44
+ block_given? and self.instance_exec &block
45
45
  end
46
46
 
47
47
  #
@@ -63,6 +63,10 @@ module ParamsValidator
63
63
  parameter = Parameter.new(meth, args.length < 1 ? Object : args[0], optional, block)
64
64
  @parameters.push parameter
65
65
  end
66
+
67
+ def to_s
68
+ "method <#{self.method_name}> => #{parameters.to_s}"
69
+ end
66
70
 
67
71
  end
68
72
  end
@@ -41,6 +41,21 @@ module ParamsValidator
41
41
 
42
42
  def load_rules(rules)
43
43
  self.class.load_rules(rules)
44
+ end
45
+
46
+ # This method is used for implicit validations (ruleset specification inside a method)
47
+ #
48
+ # @param params method call parameters
49
+ # @param &block DSL that defines the validation ruleset
50
+ # return true if params fit the ruleset defined in &block
51
+ # raise ArgumentError if an error occurred
52
+ #
53
+ def validate_method(params = nil, &block)
54
+ method = MethodValidation.new("foo_bar")
55
+
56
+ block_given? and method.block &block
57
+
58
+ Validator.validate_ruleset(method.parameters, params)
44
59
  end
45
60
 
46
61
  # inner module to define class methods
@@ -50,16 +65,23 @@ module ParamsValidator
50
65
  # should be validated when called.
51
66
  # i.e. validate_method :method1
52
67
  # validate_method [:method1, :method2]
53
- def validate_method(method, &block)
68
+ def validate_method(method=nil, &block)
54
69
  # get the fully qualified method name
55
70
  interface = self.name
56
-
71
+
57
72
  # cast to array if method is one symbol
58
73
  method.instance_of?(Symbol) and method = [method]
59
74
 
60
75
  # wrap each method
61
76
  method.each{|m|
62
77
  interface_method = [interface, m].join("::")
78
+
79
+ if validator.has_method_rule?(interface_method)
80
+ # already has a validation => delete it
81
+ old_method = "#{m}_old"
82
+ self.send :alias_method, *[m, old_method]
83
+ remove_method("#{m}_old".to_sym)
84
+ end
63
85
 
64
86
  # add validation rule to the specific method if a block is defined
65
87
  if block_given?
@@ -8,7 +8,8 @@ require 'params_validator/valid_params'
8
8
  module ParamsValidator
9
9
 
10
10
  #
11
- # This class
11
+ # This class keeps the rulesets defined in the program and performs the validation between
12
+ # a specific ruleset and a set of parameters
12
13
  #
13
14
  class Validator
14
15
 
@@ -43,6 +44,11 @@ module ParamsValidator
43
44
  block_given? and method.block &block
44
45
  @methods_loaded[:"#{method_name}"] = method
45
46
  end
47
+
48
+ def has_method_rule?(method_name)
49
+ !method_name.is_a?(Symbol) and method_name = method_name.to_sym
50
+ @methods_loaded.has_key?(method_name)
51
+ end
46
52
 
47
53
  #
48
54
  # This method validates if the specific call to method_name is valid
@@ -54,7 +60,7 @@ module ParamsValidator
54
60
 
55
61
  # fetch method rulesets
56
62
  method = @methods_loaded[method_name.to_sym]
57
-
63
+
58
64
  if method.nil?
59
65
  # TODO enable devel or prod mode to raise or not an exception
60
66
  errors.push "Unable to validate method #{method_name} with (#{@methods_loaded.keys.length}) keys #{@methods_loaded.keys}"
@@ -68,64 +74,74 @@ module ParamsValidator
68
74
 
69
75
  end
70
76
 
71
- #
72
- # This method validates a params hash against a specific rulset
73
- # @param valid_params ruleset
74
- # @param params
75
- #
76
- def Validator.validate_ruleset(valid_params, params)
77
- errors = []
78
- if !valid_params.nil? and params.nil?
79
- errors.push "Nil parameters when #{valid_params.length} expected"
80
- raise ArgumentError, errors
81
- end
82
-
83
- # if just one param -> include as array with length 1
84
- if valid_params.instance_of?(Array) && valid_params.length == 1 && params.instance_of?(String)
85
- params = {valid_params[0].name.to_sym => params}
86
- end
77
+ class << self
78
+ #
79
+ # This method validates a params hash against a specific ruleset
80
+ # @param valid_params ruleset
81
+ # @param params
82
+ #
83
+ def validate_ruleset(valid_params, params)
84
+ errors = []
85
+
86
+ # if params.nil? but the ruleset defines all the parameters as optional
87
+ # this method should return true
88
+ if !valid_params.nil? and params.nil?
89
+ valid_params.each{|param|
90
+ !param.optional? and (
91
+ errors.push "Nil parameters when #{valid_params.length} expected"
92
+ raise ArgumentError, errors
93
+ )
94
+ }
95
+ return true
96
+ end
87
97
 
88
- # Validate the params
89
- valid_params.each{|key|
90
- # get param
91
- param = params[key.name.to_sym]
92
- check_result = Validator.check_param(key, param)
93
- unless check_result.nil?
94
- errors.push check_result
98
+ # if just one param -> include as array with length 1
99
+ if valid_params.instance_of?(Array) && valid_params.length == 1 && params.instance_of?(String)
100
+ params = {valid_params[0].name.to_sym => params}
95
101
  end
96
- }
97
- unless errors.empty?
98
- raise ArgumentError, errors
99
- end
100
- # no exception -> successfully validated
101
- true
102
102
 
103
- end
103
+ # Validate the params
104
+ valid_params.each{|key|
105
+ # get param
106
+ param = params[key.name.to_sym]
107
+ check_result = Validator.check_param(key, param)
108
+ unless check_result.nil?
109
+ errors.push check_result
110
+ end
111
+ }
112
+ unless errors.empty?
113
+ raise ArgumentError, errors
114
+ end
115
+ # no exception -> successfully validated
116
+ true
104
117
 
105
- #
106
- # This method validates if the specific method is valid
107
- # @param valid_param object containing the param ruleset
108
- # @param param param specified by the user in the method call
109
- #
110
- def Validator.check_param(valid_param, param)
111
- if valid_param.optional? and param.nil? # argument optional and not present -> continue
112
- return nil
113
118
  end
114
119
 
115
- if param.nil? # argument mandatory and not present
116
- return ERROR_MESSAGE_NULL % valid_param.name
117
- else
118
- # check argument type is valid
119
- unless param.is_a?(valid_param.klass)
120
- return ERROR_MESSAGE_TYPE % [valid_param.name, param.class]
120
+ #
121
+ # This method validates if the specific method is valid
122
+ # @param valid_param object containing the param ruleset
123
+ # @param param param specified by the user in the method call
124
+ #
125
+ def check_param(valid_param, param)
126
+ if valid_param.optional? and param.nil? # argument optional and not present -> continue
127
+ return nil
121
128
  end
122
129
 
123
- # check argument satisfies ruleset (if present)
124
- unless valid_param.rule.nil?
125
- !valid_param.rule.call(param) and return ERROR_MESSAGE_BLOCK % valid_param.name
130
+ if param.nil? # argument mandatory and not present
131
+ return ERROR_MESSAGE_NULL % valid_param.name
132
+ else
133
+ # check argument type is valid
134
+ unless param.is_a?(valid_param.klass)
135
+ return ERROR_MESSAGE_TYPE % [valid_param.name, param.class]
136
+ end
137
+
138
+ # check argument satisfies ruleset (if present)
139
+ unless valid_param.rule.nil?
140
+ !valid_param.rule.call(param) and return ERROR_MESSAGE_BLOCK % valid_param.name
141
+ end
126
142
  end
143
+ nil
127
144
  end
128
- nil
129
145
  end
130
146
 
131
147
  end
@@ -4,5 +4,5 @@
4
4
  #
5
5
 
6
6
  module ParamsValidator
7
- VERSION = "0.1.0"
7
+ VERSION = "0.2.0"
8
8
  end
@@ -0,0 +1,65 @@
1
+ $:.unshift File.join(File.dirname(__FILE__),'../test')
2
+
3
+ require 'params-validator'
4
+ require 'mock/implicit_validation_mock_object'
5
+ require 'yamock_object'
6
+
7
+ include Mock
8
+
9
+ describe ParamsValidator::ValidParams do
10
+
11
+ let(:obj) do
12
+ ImplicitValidationMockObject.new
13
+ end
14
+
15
+ describe "validate_method inside method (implicit definition)" do
16
+
17
+ it "executes an empty block and validates true always" do
18
+ obj.log_implicit_validation().should eq(nil)
19
+ end
20
+
21
+ it "executes an empty block and validates true if arguments defined" do
22
+ obj.log_implicit_validation({:level => 1}).should eq(nil)
23
+ end
24
+
25
+ it "raises an exception if mandatory parameter missing" do
26
+ lambda{obj.log_implicit_validation_one_arg()}.should raise_error(ArgumentError)
27
+ end
28
+
29
+ it "raises an exception if invalid type" do
30
+ lambda{obj.log_implicit_validation_one_arg({:level => "1"})}.should raise_error(ArgumentError)
31
+ end
32
+
33
+ it "raises an exception if invalid type (II)" do
34
+ lambda{obj.log_implicit_validation_one_arg({:level => 1.2})}.should raise_error(ArgumentError)
35
+ end
36
+
37
+ it "works if optional attr missing" do
38
+ obj.log_implicit_validation_one_optional_arg({}).should eq(nil)
39
+ end
40
+
41
+ it "works if optional attr missing (nil arguments object)" do
42
+ obj.log_implicit_validation_one_optional_arg(nil).should eq(nil)
43
+ end
44
+ end
45
+
46
+ describe "arguments that validates against a block" do
47
+
48
+ it "works when the argument fits the block" do
49
+ obj.log_implicit_validation_two_args(:level => 1, :data => "foo").should eq(nil)
50
+ end
51
+
52
+ it "works when the argument fits the block and one optional argument is not provided" do
53
+ obj.log_implicit_validation_two_args(:data => "foo").should eq(nil)
54
+ end
55
+
56
+ it "works when the argument fits the block and both optional arguments is not provided" do
57
+ obj.log_implicit_validation_two_args().should eq(nil)
58
+ end
59
+
60
+ it "raises an exception when argument not fit the block" do
61
+ lambda{obj.log_implicit_validation_two_args({:data => ""})}.should raise_error(ArgumentError)
62
+ end
63
+ end
64
+
65
+ end
@@ -0,0 +1,52 @@
1
+ $:.unshift File.join(File.dirname(__FILE__),'../test')
2
+
3
+ require 'params-validator'
4
+ require 'mock/mock_submodule/mock_object'
5
+
6
+ include Mock::MockSubmodule
7
+
8
+ describe ParamsValidator::Validator do
9
+ describe "new defined method" do
10
+ it "works with a new defined method with no arguments" do
11
+ obj = MockObject.new
12
+ obj.log_new_method().should eq(nil)
13
+ end
14
+
15
+ it "works with a new defined method with one argument" do
16
+ obj = MockObject.new
17
+ obj.log_new_method({:level => "2"}).should eq(nil)
18
+ end
19
+
20
+ it "raises an exception with a new defined method one invalid argument" do
21
+ obj = MockObject.new
22
+ lambda{obj.log_new_method({:level => 2})}.should raise_exception(ArgumentError)
23
+ end
24
+ end
25
+
26
+ describe "ruleset inheritance" do
27
+ it "works with a inherited ruleset with valid arguments" do
28
+ obj = MockObject.new
29
+ obj.log_data_block({:level => 1, :data => "foo"}).should eq(true)
30
+ end
31
+
32
+ it "raises an exception with an inherited ruleset with invalid data" do
33
+ obj = MockObject.new
34
+ lambda{obj.log_new_method({:level => 2})}.should raise_exception(ArgumentError)
35
+ end
36
+ end
37
+
38
+ describe "ruleset overwritten" do
39
+ it "works when child ruleset changed and valid params" do
40
+ obj = Mock::MockObject.new
41
+ obj.inherit_method({:level => 1}).should eq(true)
42
+ end
43
+
44
+ it "works when child ruleset changed and invalid params" do
45
+ obj = Mock::MockObject.new
46
+ lambda{obj.inherit_method({:level => "6"})}.should raise_exception(ArgumentError)
47
+ end
48
+
49
+ end
50
+
51
+
52
+ end
@@ -21,7 +21,8 @@ describe ParamsValidator::MethodValidation do
21
21
  }
22
22
 
23
23
  it "params length should be 4" do
24
- method = ParamsValidator::MethodValidation.new("Module::Class:method", &proc)
24
+ method = ParamsValidator::MethodValidation.new("Module::Class:method")
25
+ method.block &proc
25
26
  method.parameters.length.should == 4
26
27
  end
27
28
 
@@ -4,6 +4,8 @@ require 'params-validator'
4
4
 
5
5
  describe ParamsValidator::Parameter do
6
6
  describe "optional" do
7
+
8
+ let("value"){puts "1"}
7
9
  #optional
8
10
  it "optional? returns true if parameter is optional" do
9
11
  param = ParamsValidator::Parameter.new("parameter", Object, true, nil)
@@ -1,4 +1,4 @@
1
- $:.unshift File.join(File.dirname(__FILE__),'.')
1
+ $:.unshift File.join(File.dirname(__FILE__),'../test')
2
2
 
3
3
  require 'params-validator'
4
4
  require 'mock/mock_object'
@@ -1,4 +1,4 @@
1
- $:.unshift File.join(File.dirname(__FILE__),'.')
1
+ $:.unshift File.join(File.dirname(__FILE__),'../test')
2
2
 
3
3
  require 'params-validator'
4
4
  require 'mock/mock_object'
@@ -0,0 +1,31 @@
1
+ require 'params-validator'
2
+
3
+ module Mock
4
+ class ImplicitValidationMockObject
5
+ include ParamsValidator::ValidParams
6
+
7
+ def log_implicit_validation(args=nil)
8
+ end
9
+
10
+ def log_implicit_validation_one_arg(args)
11
+ validate_method(args) do
12
+ level Fixnum
13
+ end
14
+ end
15
+
16
+ def log_implicit_validation_one_optional_arg(args={})
17
+ validate_method(args) do
18
+ level(Fixnum, :optional)
19
+ end
20
+ nil
21
+ end
22
+
23
+ def log_implicit_validation_two_args(args=nil)
24
+ validate_method(args) do
25
+ data(String, :optional) { |data| !data.nil? and data.length > 0}
26
+ level(Fixnum, :optional)
27
+ end
28
+ nil
29
+ end
30
+ end
31
+ end
@@ -4,13 +4,13 @@ module Mock
4
4
  class MockObject
5
5
  include ParamsValidator::ValidParams
6
6
 
7
- [:log, :log_level, :log_level_type, :log_level_type_optional, :log_data, :log_data_block].each{|m|
7
+ [:log, :log_level, :log_level_type, :log_level_type_optional, :log_data, :log_data_block, :inherit_method].each{|m|
8
8
  define_method(m) do |*args, &block|
9
9
  #puts "call to method #{m.to_s}"
10
10
  true
11
11
  end
12
12
  }
13
-
13
+
14
14
  validate_method(:log) do
15
15
  end
16
16
  validate_method(:log_level) do
@@ -30,5 +30,9 @@ module Mock
30
30
  data(String) { |data| !data.nil? and data.length > 0}
31
31
  level(Fixnum, :optional) {|level| level <= 3}
32
32
  end
33
+
34
+ validate_method(:inherit_method) do
35
+ level(Fixnum, :optional)
36
+ end
33
37
  end
34
38
  end
@@ -0,0 +1,25 @@
1
+ require 'params-validator'
2
+ require 'mock/mock_object'
3
+
4
+ module Mock
5
+ module MockSubmodule
6
+ class MockObject < Mock::MockObject
7
+
8
+ def log_new_method(params=nil)
9
+ nil
10
+ end
11
+
12
+ validate_method(:log_new_method) do
13
+ level(String, :optional)
14
+ end
15
+
16
+ def log_data(params)
17
+ true
18
+ end
19
+
20
+ validate_method(:inherit_method) do
21
+ level(Fixnum, :optional) {|level| level <= 3}
22
+ end
23
+ end
24
+ end
25
+ end
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: params-validator
3
3
  version: !ruby/object:Gem::Version
4
- hash: 27
4
+ hash: 23
5
5
  prerelease:
6
6
  segments:
7
7
  - 0
8
- - 1
8
+ - 2
9
9
  - 0
10
- version: 0.1.0
10
+ version: 0.2.0
11
11
  platform: ruby
12
12
  authors:
13
13
  - Juan de Bravo
@@ -15,7 +15,7 @@ autorequire:
15
15
  bindir: bin
16
16
  cert_chain: []
17
17
 
18
- date: 2011-02-24 00:00:00 +01:00
18
+ date: 2011-04-19 00:00:00 +01:00
19
19
  default_executable:
20
20
  dependencies: []
21
21
 
@@ -30,8 +30,8 @@ extra_rdoc_files: []
30
30
 
31
31
  files:
32
32
  - .gitignore
33
- - .rvmrc
34
33
  - Gemfile
34
+ - Gemfile.lock
35
35
  - README.md
36
36
  - Rakefile
37
37
  - lib/params-validator.rb
@@ -42,14 +42,18 @@ files:
42
42
  - lib/params_validator/validator.rb
43
43
  - lib/params_validator/version.rb
44
44
  - params-validator.gemspec
45
+ - spec/implicit_valid_params_spec.rb
46
+ - spec/inheritance_spec.rb
47
+ - spec/method_validation_spec.rb
48
+ - spec/parameter_spec.rb
49
+ - spec/request_spec.rb
50
+ - spec/valid_params_spec.rb
45
51
  - test/main.rb
46
- - test/method_validation_spec.rb
52
+ - test/mock/implicit_validation_mock_object.rb
47
53
  - test/mock/mock_object.rb
48
- - test/parameter_spec.rb
54
+ - test/mock/mock_submodule/mock_object.rb
49
55
  - test/project/provisioning/application.rb
50
56
  - test/project/provisioning/user_object.rb
51
- - test/request_spec.rb
52
- - test/valid_params_spec.rb
53
57
  - test/yamock_object.rb
54
58
  has_rdoc: true
55
59
  homepage: ""
@@ -81,17 +85,21 @@ required_rubygems_version: !ruby/object:Gem::Requirement
81
85
  requirements: []
82
86
 
83
87
  rubyforge_project: params-validator
84
- rubygems_version: 1.4.2
88
+ rubygems_version: 1.6.2
85
89
  signing_key:
86
90
  specification_version: 3
87
91
  summary: params-validators allows to validate the required/optional parameters in a method
88
92
  test_files:
93
+ - spec/implicit_valid_params_spec.rb
94
+ - spec/inheritance_spec.rb
95
+ - spec/method_validation_spec.rb
96
+ - spec/parameter_spec.rb
97
+ - spec/request_spec.rb
98
+ - spec/valid_params_spec.rb
89
99
  - test/main.rb
90
- - test/method_validation_spec.rb
100
+ - test/mock/implicit_validation_mock_object.rb
91
101
  - test/mock/mock_object.rb
92
- - test/parameter_spec.rb
102
+ - test/mock/mock_submodule/mock_object.rb
93
103
  - test/project/provisioning/application.rb
94
104
  - test/project/provisioning/user_object.rb
95
- - test/request_spec.rb
96
- - test/valid_params_spec.rb
97
105
  - test/yamock_object.rb
data/.rvmrc DELETED
@@ -1,2 +0,0 @@
1
- rvm_gemset_create_on_use_flag=1
2
- rvm gemset use params-validator