errapi 0.1.2 → 0.1.3
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/VERSION +1 -1
- data/lib/errapi.rb +27 -22
- data/lib/errapi/configuration.rb +49 -4
- data/lib/errapi/object_validator.rb +11 -2
- data/lib/errapi/plugins.rb +10 -0
- data/lib/errapi/plugins/i18n_messages.rb +3 -2
- data/lib/errapi/plugins/location.rb +19 -19
- data/lib/errapi/plugins/reason.rb +15 -15
- data/lib/errapi/validations.rb +25 -6
- data/lib/errapi/validations/exclusion.rb +4 -0
- data/lib/errapi/validations/format.rb +3 -0
- data/lib/errapi/validations/inclusion.rb +4 -0
- data/lib/errapi/validations/length.rb +4 -0
- data/lib/errapi/validations/presence.rb +28 -27
- data/lib/errapi/validations/trim.rb +3 -0
- data/lib/errapi/validations/type.rb +3 -0
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 544cdac914cba1a85759631310e365ffebf9c821
|
4
|
+
data.tar.gz: d33e3f71d0a276dea1d45e767b44db39f96b4e98
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 12c749f8d759cc133a292a54d1565838740db17b7bb6127893da00faab32a814bd680ef8f68d313f84386dbb8f91f5861af986bb2fa5cf21fb217067e5170059
|
7
|
+
data.tar.gz: a53453d8aebf3bda928c582d9c02645e1579efe83269a9e1403ce80af91c2458e2637e3096c5eda25123da869be3f86c923d0dbe2c2e6999ddeddca66481d8ee
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.1.
|
1
|
+
0.1.3
|
data/lib/errapi.rb
CHANGED
@@ -1,21 +1,28 @@
|
|
1
1
|
module Errapi
|
2
|
-
VERSION = '0.1.
|
2
|
+
VERSION = '0.1.3'
|
3
3
|
end
|
4
4
|
|
5
5
|
Dir[File.join File.dirname(__FILE__), File.basename(__FILE__, '.*'), '*.rb'].each{ |lib| require lib }
|
6
6
|
|
7
7
|
module Errapi
|
8
8
|
|
9
|
-
def self.configure
|
9
|
+
def self.configure *args, &block
|
10
10
|
|
11
|
-
|
12
|
-
name
|
11
|
+
options = args.last.kind_of?(Hash) ? args.pop : {}
|
12
|
+
name = args.shift || :default
|
13
13
|
|
14
|
+
init_configs
|
14
15
|
if @configs[name]
|
15
|
-
|
16
|
+
raise ArgumentError, %/Configuration "#{name}" has already been configured./
|
16
17
|
else
|
17
|
-
@configs[name] = Configuration.new
|
18
|
+
@configs[name] = options[:config] || Configuration.new
|
19
|
+
end
|
20
|
+
|
21
|
+
if options.fetch :defaults, true
|
22
|
+
default_config! @configs[name]
|
18
23
|
end
|
24
|
+
|
25
|
+
@configs[name].configure &block
|
19
26
|
end
|
20
27
|
|
21
28
|
def self.config name = nil
|
@@ -25,23 +32,21 @@ module Errapi
|
|
25
32
|
private
|
26
33
|
|
27
34
|
def self.init_configs
|
28
|
-
@configs ? @configs : @configs = {
|
35
|
+
@configs ? @configs : @configs = {}
|
29
36
|
end
|
30
37
|
|
31
|
-
def self.default_config
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
config.register_condition Errapi::Condition::ErrorCheck
|
45
|
-
end
|
38
|
+
def self.default_config! config
|
39
|
+
config.plugin Errapi::Plugins::I18nMessages.new
|
40
|
+
config.plugin Errapi::Plugins::Reason.new
|
41
|
+
config.plugin Errapi::Plugins::Location.new
|
42
|
+
config.validation_factory Errapi::Validations::Exclusion::Factory.new
|
43
|
+
config.validation_factory Errapi::Validations::Format::Factory.new
|
44
|
+
config.validation_factory Errapi::Validations::Inclusion::Factory.new
|
45
|
+
config.validation_factory Errapi::Validations::Length::Factory.new
|
46
|
+
config.validation_factory Errapi::Validations::Presence::Factory.new
|
47
|
+
config.validation_factory Errapi::Validations::Trim::Factory.new
|
48
|
+
config.validation_factory Errapi::Validations::Type::Factory.new
|
49
|
+
config.condition_factory Errapi::Condition::SimpleCheck
|
50
|
+
config.condition_factory Errapi::Condition::ErrorCheck
|
46
51
|
end
|
47
52
|
end
|
data/lib/errapi/configuration.rb
CHANGED
@@ -12,10 +12,29 @@ module Errapi
|
|
12
12
|
@validation_factories = {}
|
13
13
|
@condition_factories = {}
|
14
14
|
@location_factories = {}
|
15
|
+
@configured = false
|
16
|
+
@configured_blocks = []
|
17
|
+
end
|
18
|
+
|
19
|
+
def configured?
|
20
|
+
@configured
|
15
21
|
end
|
16
22
|
|
17
23
|
def configure
|
18
|
-
|
24
|
+
raise "Configuration can only be done once." if @configured
|
25
|
+
yield self if block_given?
|
26
|
+
@configured_blocks.each{ |block| block.call }
|
27
|
+
@configured_blocks.clear
|
28
|
+
@configured = true
|
29
|
+
self
|
30
|
+
end
|
31
|
+
|
32
|
+
def on_configured &block
|
33
|
+
if @configured
|
34
|
+
block.call
|
35
|
+
else
|
36
|
+
@configured_blocks << block
|
37
|
+
end
|
19
38
|
end
|
20
39
|
|
21
40
|
def new_error options = {}
|
@@ -35,30 +54,46 @@ module Errapi
|
|
35
54
|
end
|
36
55
|
|
37
56
|
def plugin impl, options = {}
|
38
|
-
name =
|
57
|
+
name = implementation_name impl, options
|
39
58
|
impl.config = self if impl.respond_to? :config=
|
40
59
|
@plugins[name] = impl
|
41
60
|
end
|
42
61
|
|
62
|
+
def remove_plugin name
|
63
|
+
raise ArgumentError, "No plugin registered for name #{name.inspect}" unless @plugins.key? name
|
64
|
+
@plugins.delete name
|
65
|
+
end
|
66
|
+
|
43
67
|
def validation_factory factory, options = {}
|
44
|
-
name =
|
68
|
+
name = implementation_name factory, options
|
45
69
|
factory.config = self if factory.respond_to? :config=
|
46
70
|
@validation_factories[name] = factory
|
47
71
|
end
|
48
72
|
|
73
|
+
def remove_validation_factory name
|
74
|
+
raise ArgumentError, "No validation factory registered for name #{name.inspect}" unless @validation_factories.key? name
|
75
|
+
@validation_factories.delete name
|
76
|
+
end
|
77
|
+
|
49
78
|
def validation name, options = {}
|
50
79
|
raise ArgumentError, "No validation factory registered for name #{name.inspect}" unless @validation_factories.key? name
|
51
80
|
factory = @validation_factories[name]
|
52
81
|
factory.respond_to?(:validation) ? factory.validation(options) : factory.new(options)
|
53
82
|
end
|
54
83
|
|
55
|
-
def
|
84
|
+
def condition_factory factory
|
56
85
|
factory.conditionals.each do |conditional|
|
57
86
|
raise ArgumentError, "Conditional #{conditional} should start with 'if' or 'unless'." unless conditional.to_s.match /^(if|unless)/
|
58
87
|
@condition_factories[conditional] = factory
|
59
88
|
end
|
60
89
|
end
|
61
90
|
|
91
|
+
def remove_condition_factory factory
|
92
|
+
factory.conditionals.each do |conditional|
|
93
|
+
@condition_factories.delete conditional
|
94
|
+
end
|
95
|
+
end
|
96
|
+
|
62
97
|
def extract_conditions! source, options = {}
|
63
98
|
[].tap do |conditions|
|
64
99
|
@condition_factories.each_pair do |conditional,factory|
|
@@ -70,6 +105,16 @@ module Errapi
|
|
70
105
|
|
71
106
|
private
|
72
107
|
|
108
|
+
def implementation_name impl, options = {}
|
109
|
+
if options[:name]
|
110
|
+
options[:name].to_sym
|
111
|
+
elsif impl.respond_to? :name
|
112
|
+
impl.name.to_sym
|
113
|
+
else
|
114
|
+
raise ArgumentError, "Plugins and factories added to a configuration must respond to #name or be supplied with the :name option."
|
115
|
+
end
|
116
|
+
end
|
117
|
+
|
73
118
|
def apply_plugins operation, *args
|
74
119
|
@plugins.each_pair do |name,plugin|
|
75
120
|
plugin.send operation, *args if plugin.respond_to? operation
|
@@ -5,14 +5,18 @@ module Errapi
|
|
5
5
|
class ObjectValidator
|
6
6
|
include LocationBuilders
|
7
7
|
|
8
|
+
# TODO: remove "options" or if used, pass them to new validators instantiated in #register_validations
|
8
9
|
def initialize config, options = {}, &block
|
9
|
-
# TODO: remove these options or if used, pass them to new validators instantiated in #register_validations
|
10
10
|
@config = config
|
11
11
|
@validations = []
|
12
|
-
|
12
|
+
|
13
|
+
@config.on_configured do
|
14
|
+
instance_eval &block if block
|
15
|
+
end
|
13
16
|
end
|
14
17
|
|
15
18
|
def validates *args, &block
|
19
|
+
check_config!
|
16
20
|
register_validations *args, &block
|
17
21
|
end
|
18
22
|
|
@@ -27,6 +31,7 @@ module Errapi
|
|
27
31
|
end
|
28
32
|
|
29
33
|
def validate value, context, options = {}
|
34
|
+
check_config!
|
30
35
|
# TODO: skip validation by default if previous errors at current location
|
31
36
|
# TODO: add support for previous value and skip validation by default if value is unchanged
|
32
37
|
|
@@ -186,6 +191,10 @@ module Errapi
|
|
186
191
|
@validations << validations_definition
|
187
192
|
end
|
188
193
|
|
194
|
+
def check_config!
|
195
|
+
raise "Configuration has not been done. You must call Errapi.config to complete the configuration process." unless @config.configured?
|
196
|
+
end
|
197
|
+
|
189
198
|
class ContextProxy
|
190
199
|
instance_methods.each{ |m| undef_method m unless m =~ /(^__|^send$|^object_id$)/ }
|
191
200
|
attr_accessor :current_location
|
data/lib/errapi/plugins.rb
CHANGED
@@ -1,4 +1,14 @@
|
|
1
1
|
module Errapi::Plugins
|
2
|
+
class Base
|
3
|
+
|
4
|
+
def self.plugin_name name = nil
|
5
|
+
name ? @name = name : @name
|
6
|
+
end
|
7
|
+
|
8
|
+
def name
|
9
|
+
self.class.name
|
10
|
+
end
|
11
|
+
end
|
2
12
|
end
|
3
13
|
|
4
14
|
Dir[File.join File.dirname(__FILE__), File.basename(__FILE__, '.*'), '*.rb'].each{ |lib| require lib }
|
@@ -1,8 +1,9 @@
|
|
1
1
|
require 'i18n'
|
2
2
|
|
3
3
|
# TODO: support interpolating source and target name (e.g. "Project name cannot be null.")
|
4
|
-
|
5
|
-
class
|
4
|
+
module Errapi::Plugins
|
5
|
+
class I18nMessages < Base
|
6
|
+
plugin_name :message
|
6
7
|
|
7
8
|
def serialize_error error, serialized
|
8
9
|
return if serialized.key? :message
|
@@ -1,29 +1,29 @@
|
|
1
|
-
module Errapi
|
2
|
-
class
|
3
|
-
|
4
|
-
attr_writer :config
|
5
|
-
attr_accessor :camelize
|
1
|
+
module Errapi::Plugins
|
2
|
+
class Location < Base
|
3
|
+
plugin_name :location
|
6
4
|
|
7
|
-
|
8
|
-
|
5
|
+
attr_writer :config
|
6
|
+
attr_accessor :camelize
|
9
7
|
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
8
|
+
def serialize_error error, serialized
|
9
|
+
if error.location && error.location.respond_to?(:serialize)
|
10
|
+
|
11
|
+
serialized_location = error.location.serialize
|
12
|
+
unless serialized_location.nil?
|
13
|
+
serialized[:location] = serialized_location
|
14
|
+
serialized[location_type_key] = error.location.location_type if error.location.respond_to? :location_type
|
15
15
|
end
|
16
16
|
end
|
17
|
+
end
|
17
18
|
|
18
|
-
|
19
|
+
private
|
19
20
|
|
20
|
-
|
21
|
-
|
22
|
-
|
21
|
+
def location_type_key
|
22
|
+
camelize? ? :locationType : :location_type
|
23
|
+
end
|
23
24
|
|
24
|
-
|
25
|
-
|
26
|
-
end
|
25
|
+
def camelize?
|
26
|
+
@camelize.nil? ? @config.options.camelize : @camelize
|
27
27
|
end
|
28
28
|
end
|
29
29
|
end
|
@@ -1,22 +1,22 @@
|
|
1
|
-
module Errapi
|
2
|
-
class
|
3
|
-
|
4
|
-
attr_writer :config
|
5
|
-
attr_accessor :camelize
|
1
|
+
module Errapi::Plugins
|
2
|
+
class Reason < Base
|
3
|
+
plugin_name :reason
|
6
4
|
|
7
|
-
|
8
|
-
|
9
|
-
end
|
5
|
+
attr_writer :config
|
6
|
+
attr_accessor :camelize
|
10
7
|
|
11
|
-
|
8
|
+
def serialize_error error, serialized
|
9
|
+
serialized[:reason] = serialized_reason error
|
10
|
+
end
|
11
|
+
|
12
|
+
private
|
12
13
|
|
13
|
-
|
14
|
-
|
15
|
-
|
14
|
+
def serialized_reason error
|
15
|
+
camelize? ? Utils.camelize(error.reason.to_s).to_sym : error.reason
|
16
|
+
end
|
16
17
|
|
17
|
-
|
18
|
-
|
19
|
-
end
|
18
|
+
def camelize?
|
19
|
+
@camelize.nil? ? @config.options.camelize : @camelize
|
20
20
|
end
|
21
21
|
end
|
22
22
|
end
|
data/lib/errapi/validations.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
require File.join(File.dirname(__FILE__), 'utils.rb')
|
2
|
+
|
1
3
|
module Errapi::Validations
|
2
4
|
|
3
5
|
class Base
|
@@ -37,7 +39,28 @@ module Errapi::Validations
|
|
37
39
|
end
|
38
40
|
end
|
39
41
|
|
40
|
-
class
|
42
|
+
class ValidationFactory
|
43
|
+
|
44
|
+
def self.build impl, options = {}
|
45
|
+
@validation_class = impl
|
46
|
+
@name = options[:name] || Errapi::Utils.underscore(impl.to_s.sub(/.*::/, '')).to_sym
|
47
|
+
end
|
48
|
+
|
49
|
+
def self.name
|
50
|
+
@name
|
51
|
+
end
|
52
|
+
|
53
|
+
def name
|
54
|
+
self.class.name
|
55
|
+
end
|
56
|
+
|
57
|
+
def self.validation_class
|
58
|
+
@validation_class
|
59
|
+
end
|
60
|
+
|
61
|
+
def validation_class
|
62
|
+
self.class.validation_class
|
63
|
+
end
|
41
64
|
|
42
65
|
def config= config
|
43
66
|
raise "A configuration has already been set for this factory." if @config
|
@@ -45,11 +68,7 @@ module Errapi::Validations
|
|
45
68
|
end
|
46
69
|
|
47
70
|
def validation options = {}
|
48
|
-
|
49
|
-
end
|
50
|
-
|
51
|
-
def to_s
|
52
|
-
Errapi::Utils.underscore self.class.name.sub(/.*::/, '')
|
71
|
+
validation_class.new options
|
53
72
|
end
|
54
73
|
end
|
55
74
|
end
|
@@ -1,38 +1,39 @@
|
|
1
1
|
module Errapi::Validations
|
2
|
-
class Presence <
|
3
|
-
class
|
2
|
+
class Presence < Base
|
3
|
+
class Factory < ValidationFactory
|
4
|
+
build Presence
|
5
|
+
end
|
4
6
|
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
end
|
7
|
+
def validate value, context, options = {}
|
8
|
+
if reason = check(value, options.fetch(:value_set, true))
|
9
|
+
context.add_error reason: reason
|
9
10
|
end
|
11
|
+
end
|
10
12
|
|
11
|
-
|
13
|
+
private
|
12
14
|
|
13
|
-
|
15
|
+
BLANK_REGEXP = /\A[[:space:]]*\z/
|
14
16
|
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
end
|
17
|
+
def check value, value_set
|
18
|
+
# TODO: allow customization (e.g. values that are not required, booleans, etc)
|
19
|
+
if !value_set
|
20
|
+
:missing
|
21
|
+
elsif value.nil?
|
22
|
+
:null
|
23
|
+
elsif value.respond_to?(:empty?) && value.empty?
|
24
|
+
:empty
|
25
|
+
elsif value_blank? value
|
26
|
+
:blank
|
26
27
|
end
|
28
|
+
end
|
27
29
|
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
end
|
30
|
+
def value_blank? value
|
31
|
+
if value.respond_to? :blank?
|
32
|
+
value.blank?
|
33
|
+
elsif value.kind_of? String
|
34
|
+
BLANK_REGEXP === value
|
35
|
+
else
|
36
|
+
false
|
36
37
|
end
|
37
38
|
end
|
38
39
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: errapi
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.3
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Simon Oulevay
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2015-01-
|
11
|
+
date: 2015-01-27 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: i18n
|