params-validator 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
data/.gitignore ADDED
@@ -0,0 +1,4 @@
1
+ *.gem
2
+ .bundle
3
+ Gemfile.lock
4
+ pkg/*
data/.rvmrc ADDED
@@ -0,0 +1,2 @@
1
+ rvm_gemset_create_on_use_flag=1
2
+ rvm gemset use params-validator
data/Gemfile ADDED
@@ -0,0 +1,9 @@
1
+ source "http://rubygems.org"
2
+
3
+ # Specify your gem's dependencies in params-validator.gemspec
4
+ gemspec
5
+
6
+ group :development, :test do
7
+ gem 'rspec'
8
+ end
9
+
data/README.md ADDED
@@ -0,0 +1,99 @@
1
+ # Introduction
2
+
3
+ The aim of params-validator is to allow an easy way to validate the
4
+ parameters in a method call.
5
+
6
+ # Install
7
+
8
+ gem install params-validator
9
+
10
+ # Requirementes
11
+
12
+ # Usage
13
+
14
+ * There are three ways of use:
15
+
16
+ * Include validation rules inside the object:
17
+
18
+ require 'params-validator'
19
+ class MockObject
20
+ include ParamsValidator::ValidParams
21
+ # define two useless methods
22
+ [:method1, :method2].each{|m|
23
+ define_method(m) do |*args, &block|
24
+ puts {:foo => "bar"}
25
+ true
26
+ end
27
+ }
28
+ # method1 arguments ruleset
29
+ validate_method(:method1) do
30
+ level(Fixnum, :optional)
31
+ end
32
+ # method2 arguments ruleset
33
+ validate_method(:method2) do
34
+ data(String) { |data| !data.nil? and data.length > 0}
35
+ level(Fixnum, :optional) {|level| level <= 3}
36
+ end
37
+ end
38
+
39
+
40
+ When calling a specific method, an ArgumentError exception will be raised if at least one parameter is invalid
41
+
42
+ obj = MockObject.new
43
+ obj.method1({:level => "1"}) # This will raise an ArgumentError exception because :level parameter type is invalid
44
+ obj.method1({:level => 1}) # This will execute successfully the method call
45
+ obj.method2({:level => 1}) # This will raise an ArgumentError exception because :data parameter is missing
46
+
47
+ * Include validation rules outside the object:
48
+
49
+ class MockObject
50
+ include ParamsValidator::ValidParams
51
+ # define two useless methods
52
+ [:method1, :method2].each{|m|
53
+ define_method(m) do |*args, &block|
54
+ true
55
+ end
56
+ }
57
+ # method1 and method2 should be validated, but no ruleset is defined
58
+ validate_method [:method1, :method2]
59
+ end
60
+
61
+
62
+ Then in a separate file, rulesets must be loaded:
63
+
64
+ require 'params-validator'
65
+ include ParamsValidator::ValidParams
66
+ # define rulesets
67
+ rules = <<EOF
68
+ validation_rule("MockObject::method1") do
69
+ level(Fixnum, :optional)
70
+ end
71
+ validation_rule("MockObject::method2") do
72
+ data(String) { |data| !data.nil? and data.length > 0}
73
+ level(Fixnum, :optional) {|level| level <= 3}
74
+ end
75
+ EOF
76
+ # load rulesets in validation framework
77
+ load_rules(rules)
78
+ obj = MockObject.new
79
+ obj.method1({:level => "1"}) # This will raise an ArgumentError exception because :level parameter type is invalid
80
+ obj.method1({:level => 1}) # This will execute successfully the method call
81
+ obj.method2({:level => 1}) # This will raise an ArgumentError exception because :data parameter is missing
82
+
83
+
84
+ * Client side validation (kudos to @drslump)
85
+
86
+ obj = ParamsValidator::Request.new
87
+ obj[:data] = "this is a log"
88
+ obj[:level] = 1
89
+ ruleset = MockObject.get_rule(:method2)
90
+ obj.valid?(ruleset) # false
91
+ begin
92
+ obj.validate(ruleset)
93
+ rescue ArgumentError => ae
94
+ p ae.message # array with validation errors
95
+ end
96
+
97
+
98
+ More examples can be found in test folder.
99
+
data/Rakefile ADDED
@@ -0,0 +1,2 @@
1
+ require 'bundler'
2
+ Bundler::GemHelper.install_tasks
@@ -0,0 +1,9 @@
1
+ require 'params_validator/validator'
2
+ require 'params_validator/request'
3
+
4
+ #
5
+ # Juan de Bravo <juandebravo@gmail.com>
6
+ #
7
+ module ParamsValidator
8
+ # this file just import the required files
9
+ end
@@ -0,0 +1,69 @@
1
+ require 'params_validator/parameter'
2
+
3
+ #
4
+ # Juan de Bravo <juandebravo@gmail.com>
5
+ #
6
+ module ParamsValidator
7
+
8
+ #
9
+ # This class models the information required to validate
10
+ # a specific method call
11
+ #
12
+ class MethodValidation
13
+
14
+ # fully qualified method name
15
+ attr_accessor :method_name
16
+
17
+ # parameters expected by the method
18
+ attr_accessor :parameters
19
+
20
+ #
21
+ # MethodValidation constructor
22
+ # @param method_name fully qualified method name (Module::Class::method)
23
+ # @param block the block to be executed
24
+ #
25
+ def initialize(method_name, &block)
26
+ @method_name = method_name
27
+ @parameters = []
28
+ block_given? and self.instance_eval &block
29
+ end
30
+
31
+ # get mandatory parameters
32
+ def mandatories
33
+ values = []
34
+ @parameters.each{|param|
35
+ param.mandatory? and values << param
36
+ }
37
+ values
38
+ end
39
+
40
+ #
41
+ # Execute validation block in this object scope
42
+ #
43
+ def block(&block)
44
+ block_given? and self.instance_eval &block
45
+ end
46
+
47
+ #
48
+ # DSL that defines the validation rules.
49
+ # parameter (Object, :optional = false) { block }
50
+ #
51
+ def method_missing(meth, *args, &block)
52
+
53
+ if args.length < 2
54
+ optional = false
55
+ else
56
+ if args[1].eql?(:optional)
57
+ optional = true
58
+ else
59
+ optional = false
60
+ end
61
+ end
62
+
63
+ parameter = Parameter.new(meth, args.length < 1 ? Object : args[0], optional, block)
64
+ @parameters.push parameter
65
+ end
66
+
67
+ end
68
+ end
69
+
@@ -0,0 +1,39 @@
1
+ #
2
+ # Juan de Bravo <juandebravo@gmail.com>
3
+ #
4
+
5
+ module ParamsValidator
6
+
7
+ #
8
+ # Parameter definition
9
+ #
10
+ class Parameter
11
+
12
+ # parameter name
13
+ attr_accessor :name
14
+
15
+ # set if parameter is mandatory or optional
16
+ attr_accessor :optional
17
+
18
+ # parameter type (Object by default)
19
+ attr_accessor :klass
20
+
21
+ # specific ruleset (i.e. max or min length)
22
+ attr_accessor :rule
23
+
24
+ def initialize(name, klass = Object, optional = false, rule = nil)
25
+ @name = name.to_sym
26
+ @optional = optional
27
+ @klass = klass
28
+ @rule = rule
29
+ end
30
+
31
+ def optional?
32
+ @optional
33
+ end
34
+
35
+ def mandatory?
36
+ !@optional
37
+ end
38
+ end
39
+ end
@@ -0,0 +1,48 @@
1
+ require 'params_validator/validator'
2
+
3
+ #
4
+ # Juan de Bravo <juandebravo@gmail.com>
5
+ #
6
+
7
+ module ParamsValidator
8
+ #
9
+ # Class used to enhance the way to pass parameters to a method
10
+ #
11
+ class Request < Hash
12
+
13
+ def initialize(params = nil)
14
+ super(params)
15
+ end
16
+
17
+ def add(key, value)
18
+ self[key.to_sym] = value
19
+ self
20
+ end
21
+
22
+ alias :delete_old :delete
23
+
24
+ def delete(key)
25
+ delete_old(key)
26
+ self
27
+ end
28
+
29
+ def params
30
+ keys
31
+ end
32
+
33
+ alias :size :length
34
+
35
+ def validate(ruleset)
36
+ ParamsValidator::Validator.validate_ruleset(ruleset, self)
37
+ end
38
+
39
+ def valid?(ruleset)
40
+ begin
41
+ validate(ruleset)
42
+ true
43
+ rescue
44
+ false
45
+ end
46
+ end
47
+ end
48
+ end
@@ -0,0 +1,106 @@
1
+ #
2
+ # Juan de Bravo <juandebravo@gmail.com>
3
+ #
4
+
5
+ module ParamsValidator
6
+
7
+ #
8
+ # Module to be included in a class which methods should be validated
9
+ #
10
+ module ValidParams
11
+
12
+ def self.included(base)
13
+ base.extend(ClassMethods)
14
+ end
15
+
16
+ #
17
+ # This method is called to validate the request parameters to a specific method before calling the method itself
18
+ # @param params Hash of parameters to validate
19
+ # @param interface_method String containing the fully qualified method name (Module1::Module2::Class::method)
20
+ #
21
+ def previous_validation(params = nil, interface_method = nil)
22
+ unless validator.nil?
23
+ if interface_method.nil?
24
+ interface = caller[0][/^(.*)(\.rb).*$/, 1].split('/').last
25
+ interface = caller[0][/^(.*)(\.rb).*$/, 1].split('/')
26
+ interface.shift
27
+ interface = interface.map!{|x| x.capitalize}.join("::")
28
+ method = caller[0][/`([^']*)'/, 1]
29
+ interface_method = [interface, method].join("::")
30
+ else
31
+ # Got directly the method name in interface_method
32
+ end
33
+ params.instance_of?(Array) and params = params[0]
34
+ validator.validate_params(interface_method, params)
35
+ end
36
+ end
37
+
38
+ def validator
39
+ self.class.validator
40
+ end
41
+
42
+ def load_rules(rules)
43
+ self.class.load_rules(rules)
44
+ end
45
+
46
+ # inner module to define class methods
47
+ module ClassMethods
48
+
49
+ # This method is used in classes to define which methods
50
+ # should be validated when called.
51
+ # i.e. validate_method :method1
52
+ # validate_method [:method1, :method2]
53
+ def validate_method(method, &block)
54
+ # get the fully qualified method name
55
+ interface = self.name
56
+
57
+ # cast to array if method is one symbol
58
+ method.instance_of?(Symbol) and method = [method]
59
+
60
+ # wrap each method
61
+ method.each{|m|
62
+ interface_method = [interface, m].join("::")
63
+
64
+ # add validation rule to the specific method if a block is defined
65
+ if block_given?
66
+ validator.validation_rule(interface_method, &block)
67
+ end
68
+
69
+ # wrap old method with the previous validation
70
+ old_method = "#{m}_old"
71
+ self.send :alias_method, *[old_method, m]
72
+
73
+ define_method(m) do |*args, &block|
74
+ # validate parameters
75
+ previous_validation(args, interface_method)
76
+ # call method
77
+ send(old_method, *args, &block)
78
+ end
79
+ }
80
+ end
81
+
82
+ # get the specified rule for a method
83
+ def get_rule(method)
84
+ object_name = self.name
85
+ key = "#{object_name}::#{method}"
86
+ method_validation = validator.methods_loaded[key.to_sym]
87
+ unless method_validation.nil?
88
+ return method_validation.parameters
89
+ end
90
+ nil
91
+ end
92
+
93
+ # validator object
94
+ def validator
95
+ @@validator ||= Validator.new
96
+ end
97
+
98
+ # shortcut to validator.load_rules
99
+ def load_rules(rules)
100
+ validator.load_rules(rules)
101
+ end
102
+
103
+ end
104
+
105
+ end
106
+ end
@@ -0,0 +1,132 @@
1
+ require 'params_validator/method_validation'
2
+ require 'params_validator/valid_params'
3
+
4
+ #
5
+ # Juan de Bravo <juandebravo@gmail.com>
6
+ #
7
+
8
+ module ParamsValidator
9
+
10
+ #
11
+ # This class
12
+ #
13
+ class Validator
14
+
15
+ ERROR_MESSAGE_NULL = "Parameter %s cannot be null"
16
+ ERROR_MESSAGE_TYPE = "Parameter %s present but invalid type %s"
17
+ ERROR_MESSAGE_BLOCK = "Parameter %s present but does not match the ruleset"
18
+
19
+ attr_reader :methods_loaded
20
+
21
+ def initialize
22
+ @methods_loaded = {}
23
+ end
24
+
25
+ #
26
+ # This method loads new rules in memory
27
+ # validatation_rule method do
28
+ # param1 (type) &block
29
+ # param2 (type) &block
30
+ # end
31
+ #
32
+ def load_rules(rules)
33
+ self.instance_eval(rules)
34
+ end
35
+
36
+ #
37
+ # This method is part of the DSL and defines a new validator rule
38
+ # @param method_name fully qualified method name (Module::Class::method)
39
+ # @param block the block to be executed
40
+ #
41
+ def validation_rule(method_name, &block)
42
+ method = MethodValidation.new(method_name)
43
+ block_given? and method.block &block
44
+ @methods_loaded[:"#{method_name}"] = method
45
+ end
46
+
47
+ #
48
+ # This method validates if the specific call to method_name is valid
49
+ # @param method_name fully qualified method name (Module::Class::method)
50
+ # @param params
51
+ #
52
+ def validate_params(method_name, params)
53
+ errors = []
54
+
55
+ # fetch method rulesets
56
+ method = @methods_loaded[method_name.to_sym]
57
+
58
+ if method.nil?
59
+ # TODO enable devel or prod mode to raise or not an exception
60
+ errors.push "Unable to validate method #{method_name} with (#{@methods_loaded.keys.length}) keys #{@methods_loaded.keys}"
61
+ raise ArgumentError, errors
62
+ end
63
+
64
+ # fetch all params (optional and mandatory)
65
+ check_params = method.parameters
66
+
67
+ self.class.validate_ruleset(check_params, params)
68
+
69
+ end
70
+
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
87
+
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
95
+ end
96
+ }
97
+ unless errors.empty?
98
+ raise ArgumentError, errors
99
+ end
100
+ # no exception -> successfully validated
101
+ true
102
+
103
+ end
104
+
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
+ end
114
+
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]
121
+ end
122
+
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
126
+ end
127
+ end
128
+ nil
129
+ end
130
+
131
+ end
132
+ end
@@ -0,0 +1,8 @@
1
+
2
+ #
3
+ # Juan de Bravo <juandebravo@gmail.com>
4
+ #
5
+
6
+ module ParamsValidator
7
+ VERSION = "0.1.0"
8
+ end
@@ -0,0 +1,23 @@
1
+ # -*- encoding: utf-8 -*-
2
+ $:.push File.expand_path("lib", ".")
3
+
4
+ require "params_validator/version"
5
+
6
+ Gem::Specification.new do |s|
7
+ s.name = "params-validator"
8
+ s.version = ParamsValidator::VERSION
9
+ s.platform = Gem::Platform::RUBY
10
+ s.authors = ["Juan de Bravo"]
11
+ s.email = ["juandebravo@gmail.com"]
12
+ s.homepage = ""
13
+ s.summary = "params-validators allows to validate the required/optional parameters in a method"
14
+ s.description = "params-validators allows to validate the required/optional parameters in a method"
15
+
16
+ s.rubyforge_project = "params-validator"
17
+
18
+ s.files = `git ls-files`.split("\n")
19
+ s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
20
+ s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
21
+ s.require_paths = ["lib"]
22
+
23
+ end
data/test/main.rb ADDED
@@ -0,0 +1,39 @@
1
+ $:.unshift File.join(File.dirname(__FILE__),'..','lib')
2
+
3
+ require 'params-validator'
4
+ require 'project/provisioning/user_object'
5
+ require 'project/provisioning/application'
6
+
7
+ if __FILE__ == $0
8
+ rules = <<EOF
9
+ validation_rule "Project::Provisioning::UserObject::create" do
10
+ name (String) {|value| value.length > 5 && value.length < 10}
11
+ password String
12
+ birthday (Fixnum) {|value| Time.now.year > value}
13
+ description(String, :optional) {|value| value.length > 50 && value.length < 100}
14
+ end
15
+
16
+ validation_rule "Project::Provisioning::UserObject::delete" do
17
+ user_id (String)
18
+ end
19
+ EOF
20
+
21
+ include ParamsValidator::ValidParams
22
+
23
+ load_rules(rules)
24
+
25
+
26
+ user = Project::Provisioning::UserObject.new
27
+ begin
28
+ user.create({:name => "juan", :password1 => "project", :birthday => 1978})
29
+ rescue ArgumentError => ex
30
+ p ex.message
31
+ end
32
+ user.delete({:user_id => "juan"})
33
+
34
+ application = Project::Provisioning::Application.new
35
+ application.create({:user_id => "juan"})
36
+
37
+ application.delete({:app_id => "app1"})
38
+
39
+ end
@@ -0,0 +1,49 @@
1
+ require 'params-validator'
2
+
3
+ describe ParamsValidator::MethodValidation do
4
+ describe "method_name" do
5
+ it "method_name returns the valid method name" do
6
+ method = ParamsValidator::MethodValidation.new("method_name")
7
+ method.method_name.should == "method_name"
8
+ end
9
+ it "method_name with module/class returns the valid method name" do
10
+ method = ParamsValidator::MethodValidation.new("Module1::Module2::Class::method")
11
+ method.method_name.should eq("Module1::Module2::Class::method")
12
+ end
13
+ end
14
+
15
+ describe "parameters" do
16
+ proc = lambda{
17
+ name(String) {|value| value.length > 5 && value.length < 10}
18
+ password
19
+ birthday(Fixnum) {|value| Time.now.year > value}
20
+ description(String, :optional) {|value| value.length > 50 && value.length < 100}
21
+ }
22
+
23
+ it "params length should be 4" do
24
+ method = ParamsValidator::MethodValidation.new("Module::Class:method", &proc)
25
+ method.parameters.length.should == 4
26
+ end
27
+
28
+ it "mandatory params length should be 3" do
29
+ method = ParamsValidator::MethodValidation.new("Module::Class:method", &proc)
30
+ method.parameters.length.should == 4
31
+ end
32
+
33
+ it "default object should be Object" do
34
+ method = ParamsValidator::MethodValidation.new("Module::Class:method", &proc)
35
+ method.parameters[1].klass.should == Object
36
+ end
37
+
38
+ it "parameter with ruleset should have rule attribute" do
39
+ method = ParamsValidator::MethodValidation.new("Module::Class:method", &proc)
40
+ method.parameters[0].rule.should_not == nil
41
+ end
42
+
43
+ it "parameter without ruleset should have nil rule attribute" do
44
+ method = ParamsValidator::MethodValidation.new("Module::Class:method", &proc)
45
+ method.parameters[1].rule.should == nil
46
+ end
47
+ end
48
+
49
+ end
@@ -0,0 +1,34 @@
1
+ require 'params-validator'
2
+
3
+ module Mock
4
+ class MockObject
5
+ include ParamsValidator::ValidParams
6
+
7
+ [:log, :log_level, :log_level_type, :log_level_type_optional, :log_data, :log_data_block].each{|m|
8
+ define_method(m) do |*args, &block|
9
+ #puts "call to method #{m.to_s}"
10
+ true
11
+ end
12
+ }
13
+
14
+ validate_method(:log) do
15
+ end
16
+ validate_method(:log_level) do
17
+ level
18
+ end
19
+ validate_method(:log_level_type) do
20
+ level Fixnum
21
+ end
22
+ validate_method(:log_level_type_optional) do
23
+ level(Fixnum, :optional)
24
+ end
25
+ validate_method(:log_data) do
26
+ data(String)
27
+ level(Fixnum, :optional)
28
+ end
29
+ validate_method(:log_data_block) do
30
+ data(String) { |data| !data.nil? and data.length > 0}
31
+ level(Fixnum, :optional) {|level| level <= 3}
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,37 @@
1
+ $:.unshift File.join(File.dirname(__FILE__),'..','lib')
2
+
3
+ require 'params-validator'
4
+
5
+ describe ParamsValidator::Parameter do
6
+ describe "optional" do
7
+ #optional
8
+ it "optional? returns true if parameter is optional" do
9
+ param = ParamsValidator::Parameter.new("parameter", Object, true, nil)
10
+ param.optional?.should == true
11
+ end
12
+ it "optional? returns false if parameter is mandatory" do
13
+ param = ParamsValidator::Parameter.new("parameter", Object, false, nil)
14
+ param.optional?.should == false
15
+ end
16
+ end
17
+
18
+ describe "ruleset" do
19
+ # ruleset
20
+ it "rule returns nil if parameter has no ruleset defined" do
21
+ param = ParamsValidator::Parameter.new("parameter", Object, false, nil)
22
+ param.rule.should == nil
23
+ end
24
+ end
25
+
26
+ describe "klass" do
27
+ # klass
28
+ it "klass returns parameter class if defined" do
29
+ param = ParamsValidator::Parameter.new("parameter", String)
30
+ param.klass.should == String
31
+ end
32
+ it "klass returns Object class if undefined" do
33
+ param = ParamsValidator::Parameter.new("parameter")
34
+ param.klass.should == Object
35
+ end
36
+ end
37
+ end
@@ -0,0 +1,31 @@
1
+ require 'params-validator'
2
+
3
+ module Project::Provisioning
4
+ class Application
5
+ include ParamsValidator::ValidParams
6
+
7
+ def create(params)
8
+ puts "create a specific #{self.class.name}"
9
+ end
10
+
11
+ def delete(params)
12
+ puts "delete a specific #{self.class.name}"
13
+ end
14
+
15
+ rules = <<EOF
16
+ validation_rule "Project::Provisioning::Application::create" do
17
+ user_id (String)
18
+ end
19
+ EOF
20
+
21
+ load_rules(rules)
22
+
23
+
24
+ validate_method :create
25
+
26
+ validate_method(:delete) {
27
+ app_id (String)
28
+ }
29
+
30
+ end
31
+ end
@@ -0,0 +1,20 @@
1
+ require 'params-validator'
2
+
3
+ module Project
4
+ module Provisioning
5
+ class UserObject
6
+ include ParamsValidator::ValidParams
7
+
8
+ def create(params)
9
+ puts "create a specific user"
10
+ end
11
+
12
+ def delete(params)
13
+ puts "delete a specific user"
14
+ end
15
+
16
+ validate_method [:delete, :create]
17
+
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,79 @@
1
+ $:.unshift File.join(File.dirname(__FILE__),'.')
2
+
3
+ require 'params-validator'
4
+ require 'mock/mock_object'
5
+ require 'yamock_object'
6
+
7
+
8
+ describe ParamsValidator::Request do
9
+ describe "handle parameters" do
10
+
11
+ it "add any parameter" do
12
+ obj = ParamsValidator::Request.new
13
+ obj.add(:foo, "bar")
14
+ obj.add(:length, 3)
15
+ obj.size.should eq(2)
16
+ end
17
+
18
+ it "delete any parameter" do
19
+ obj = ParamsValidator::Request.new
20
+ obj.add(:foo, "bar")
21
+ obj.add(:length, 3)
22
+ obj.delete(:length)
23
+ obj.size.should eq(1)
24
+ end
25
+ end
26
+
27
+ describe "validate parameters" do
28
+
29
+ it "validation return true with valid parameters" do
30
+ obj = ParamsValidator::Request.new
31
+ obj[:data] = "this is a log"
32
+ obj[:level] = 1
33
+ ruleset = Mock::MockObject.get_rule(:log_data_block)
34
+ obj.validate(ruleset).should eq(true)
35
+ end
36
+
37
+ it "validation throw exception with invalid parameters" do
38
+ obj = ParamsValidator::Request.new
39
+ obj[:data] = "this is a log"
40
+ obj[:level] = "1"
41
+ ruleset = Mock::MockObject.get_rule(:log_data_block)
42
+ lambda{obj.validate(ruleset)}.should raise_error(ArgumentError)
43
+ end
44
+
45
+ it "validation throw exception with the correct number of errors" do
46
+ obj = ParamsValidator::Request.new
47
+ obj[:data] = ""
48
+ obj[:level] = "1"
49
+ ruleset = Mock::MockObject.get_rule(:log_data_block)
50
+ begin
51
+ obj.validate(ruleset)
52
+ rescue ArgumentError => ae
53
+ ae.message.length.should eq(2)
54
+ end
55
+ end
56
+
57
+ end
58
+
59
+ describe "valid? method" do
60
+
61
+ it "returns true if valid" do
62
+ obj = ParamsValidator::Request.new
63
+ obj[:data] = "this is a log"
64
+ obj[:level] = 1
65
+ ruleset = Mock::MockObject.get_rule(:log_data_block)
66
+ obj.valid?(ruleset).should eq(true)
67
+ end
68
+
69
+ it "returns false if invalid" do
70
+ obj = ParamsValidator::Request.new
71
+ obj[:data] = "this is a log"
72
+ obj[:level] = "1"
73
+ ruleset = Mock::MockObject.get_rule(:log_data_block)
74
+ obj.valid?(ruleset).should eq(false)
75
+ end
76
+
77
+ end
78
+
79
+ end
@@ -0,0 +1,99 @@
1
+ $:.unshift File.join(File.dirname(__FILE__),'.')
2
+
3
+ require 'params-validator'
4
+ require 'mock/mock_object'
5
+ require 'yamock_object'
6
+
7
+ include Mock
8
+
9
+ describe ParamsValidator::ValidParams do
10
+ describe "validate_method inside class" do
11
+ it "executes an empty block and validates true always" do
12
+ obj = MockObject.new
13
+ obj.log({}).should eq(true)
14
+ end
15
+
16
+ it "raises an exception if mandatory parameter missing" do
17
+ obj = MockObject.new
18
+ lambda{obj.log_level({})}.should raise_error(ArgumentError)
19
+ end
20
+
21
+ it "raises an exception if mandatory parameter included but invalid type" do
22
+ obj = MockObject.new
23
+ lambda{obj.log_level_type({:level => "INFO"})}.should raise_error(ArgumentError)
24
+ end
25
+
26
+ it "raises an exception if optional parameter included but invalid type" do
27
+ obj = MockObject.new
28
+ lambda{obj.log_level_type_optional({:level => "INFO"})}.should raise_error(ArgumentError)
29
+ end
30
+
31
+ it "executes a valid ruleset with mandatory parameters" do
32
+ obj = MockObject.new
33
+ obj.log_level_type({:level => 3}).should eq(true)
34
+ end
35
+
36
+ it "executes a valid ruleset with mandatory and optional parameters included" do
37
+ obj = MockObject.new
38
+ obj.log_data({:level => 3, :data => "This is a test"}).should eq(true)
39
+ end
40
+
41
+ it "executes a valid ruleset with mandatory parameters included and optional parameters missing" do
42
+ obj = MockObject.new
43
+ obj.log_data({:data => "This is a test"}).should eq(true)
44
+ end
45
+
46
+ it "executes a valid ruleset with validation block for parameters" do
47
+ obj = MockObject.new
48
+ obj.log_data_block({:data => "This is a test", :level => 1}).should eq(true)
49
+ end
50
+
51
+ it "executes a valid ruleset with invalid validation block for mandatory parameter" do
52
+ obj = MockObject.new
53
+ lambda{obj.log_data_block({:data => ""})}.should raise_error(ArgumentError)
54
+ end
55
+
56
+ it "executes a valid ruleset with invalid validation block for optional parameter" do
57
+ obj = MockObject.new
58
+ lambda{obj.log_data_block({:data => "", :level => 5})}.should raise_error(ArgumentError)
59
+ end
60
+ end
61
+
62
+ describe "validate_method inline" do
63
+ rules = <<EOF
64
+ validation_rule("YamockObject::log") do
65
+ end
66
+ validation_rule("YamockObject::log_level") do
67
+ level
68
+ end
69
+ validation_rule("YamockObject::log_level_type") do
70
+ level Fixnum
71
+ end
72
+ validation_rule("YamockObject::log_level_type_optional") do
73
+ level(Fixnum, :optional)
74
+ end
75
+ validation_rule("YamockObject::log_data") do
76
+ data(String)
77
+ level(Fixnum, :optional)
78
+ end
79
+ validation_rule("YamockObject::log_data_block") do
80
+ data(String) { |data| !data.nil? and data.length > 0}
81
+ level(Fixnum, :optional) {|level| level <= 3}
82
+ end
83
+
84
+ EOF
85
+
86
+ include ParamsValidator::ValidParams
87
+ load_rules(rules)
88
+
89
+ it "executes a valid ruleset with invalid validation block for optional parameter" do
90
+ obj = YamockObject.new
91
+ lambda{obj.log_data_block({:data => "", :level => 5})}.should raise_error(ArgumentError)
92
+ end
93
+ it "executes a valid ruleset with valid validation blocks" do
94
+ obj = YamockObject.new
95
+ obj.log_data_block({:data => "info", :level => 2}).should eq(true)
96
+ end
97
+ end
98
+
99
+ end
@@ -0,0 +1,16 @@
1
+ require 'params-validator'
2
+
3
+ class YamockObject
4
+ include ParamsValidator::ValidParams
5
+
6
+ METHODS = [:log, :log_level, :log_level_type, :log_level_type_optional, :log_data, :log_data_block]
7
+
8
+ METHODS.each{|m|
9
+ define_method(m) do |*args, &block|
10
+ true
11
+ end
12
+ }
13
+
14
+ validate_method METHODS
15
+ end
16
+
metadata ADDED
@@ -0,0 +1,97 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: params-validator
3
+ version: !ruby/object:Gem::Version
4
+ hash: 27
5
+ prerelease:
6
+ segments:
7
+ - 0
8
+ - 1
9
+ - 0
10
+ version: 0.1.0
11
+ platform: ruby
12
+ authors:
13
+ - Juan de Bravo
14
+ autorequire:
15
+ bindir: bin
16
+ cert_chain: []
17
+
18
+ date: 2011-02-24 00:00:00 +01:00
19
+ default_executable:
20
+ dependencies: []
21
+
22
+ description: params-validators allows to validate the required/optional parameters in a method
23
+ email:
24
+ - juandebravo@gmail.com
25
+ executables: []
26
+
27
+ extensions: []
28
+
29
+ extra_rdoc_files: []
30
+
31
+ files:
32
+ - .gitignore
33
+ - .rvmrc
34
+ - Gemfile
35
+ - README.md
36
+ - Rakefile
37
+ - lib/params-validator.rb
38
+ - lib/params_validator/method_validation.rb
39
+ - lib/params_validator/parameter.rb
40
+ - lib/params_validator/request.rb
41
+ - lib/params_validator/valid_params.rb
42
+ - lib/params_validator/validator.rb
43
+ - lib/params_validator/version.rb
44
+ - params-validator.gemspec
45
+ - test/main.rb
46
+ - test/method_validation_spec.rb
47
+ - test/mock/mock_object.rb
48
+ - test/parameter_spec.rb
49
+ - test/project/provisioning/application.rb
50
+ - test/project/provisioning/user_object.rb
51
+ - test/request_spec.rb
52
+ - test/valid_params_spec.rb
53
+ - test/yamock_object.rb
54
+ has_rdoc: true
55
+ homepage: ""
56
+ licenses: []
57
+
58
+ post_install_message:
59
+ rdoc_options: []
60
+
61
+ require_paths:
62
+ - lib
63
+ required_ruby_version: !ruby/object:Gem::Requirement
64
+ none: false
65
+ requirements:
66
+ - - ">="
67
+ - !ruby/object:Gem::Version
68
+ hash: 3
69
+ segments:
70
+ - 0
71
+ version: "0"
72
+ required_rubygems_version: !ruby/object:Gem::Requirement
73
+ none: false
74
+ requirements:
75
+ - - ">="
76
+ - !ruby/object:Gem::Version
77
+ hash: 3
78
+ segments:
79
+ - 0
80
+ version: "0"
81
+ requirements: []
82
+
83
+ rubyforge_project: params-validator
84
+ rubygems_version: 1.4.2
85
+ signing_key:
86
+ specification_version: 3
87
+ summary: params-validators allows to validate the required/optional parameters in a method
88
+ test_files:
89
+ - test/main.rb
90
+ - test/method_validation_spec.rb
91
+ - test/mock/mock_object.rb
92
+ - test/parameter_spec.rb
93
+ - test/project/provisioning/application.rb
94
+ - test/project/provisioning/user_object.rb
95
+ - test/request_spec.rb
96
+ - test/valid_params_spec.rb
97
+ - test/yamock_object.rb