params-validator 0.1.0 → 0.2.0

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/.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