otoroshi 0.0.7 → 0.0.8
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.
- checksums.yaml +4 -4
- data/lib/otoroshi/exceptions.rb +10 -10
- data/lib/otoroshi/initializer.rb +137 -0
- data/lib/otoroshi/sanctuary.rb +43 -182
- metadata +3 -20
- data/lib/doc/Example.html +0 -244
- data/lib/doc/Otoroshi.html +0 -115
- data/lib/doc/Otoroshi/Sanctuary.html +0 -223
- data/lib/doc/Otoroshi/Sanctuary/ClassMethods.html +0 -1511
- data/lib/doc/_index.html +0 -137
- data/lib/doc/class_list.html +0 -51
- data/lib/doc/css/common.css +0 -1
- data/lib/doc/css/full_list.css +0 -58
- data/lib/doc/css/style.css +0 -496
- data/lib/doc/file.README.html +0 -290
- data/lib/doc/file_list.html +0 -56
- data/lib/doc/frames.html +0 -17
- data/lib/doc/index.html +0 -290
- data/lib/doc/js/app.js +0 -314
- data/lib/doc/js/full_list.js +0 -216
- data/lib/doc/js/jquery.js +0 -4
- data/lib/doc/method_list.html +0 -155
- data/lib/doc/top-level-namespace.html +0 -110
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: fba1623080c055e87c2055001a7f2370e459b5fe1a28774375cef3dd9e7da802
|
4
|
+
data.tar.gz: 4c01c52a123157e572b4fdcef7c2e7eb6f0cc6ef2162e49237b5a49785708b70
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 8b89127bff4d54b14be27fe723db61e6f0786b7f0f9f6d4df612ed49b3d86d59f1a1df55038178662e5ce247c4b2f6af16b35e05650730d8b9889debd354ed48
|
7
|
+
data.tar.gz: 177fbc07e846a1cb9cbc7b3e595ce5c0878ff153d6293d9e0ccf986745a0b898e3b2a9be144218b97425ad87b78b4170848b20496ca39bf232ee898f5b1fcb19
|
data/lib/otoroshi/exceptions.rb
CHANGED
@@ -9,11 +9,11 @@ module Otoroshi
|
|
9
9
|
#
|
10
10
|
# @param property [Symbol] name of the property
|
11
11
|
# @param type [Class] class to match
|
12
|
-
# @param
|
13
|
-
def initialize(property, type,
|
12
|
+
# @param collection [true, false] define if it is a collection
|
13
|
+
def initialize(property, type, collection: false)
|
14
14
|
expected_type = type.is_a?(Array) ? type.first || Object : type
|
15
15
|
msg =
|
16
|
-
if
|
16
|
+
if collection
|
17
17
|
":#{property} contains elements that are not instances of #{expected_type}"
|
18
18
|
else
|
19
19
|
":#{property} is not an instance of #{expected_type}"
|
@@ -22,7 +22,7 @@ module Otoroshi
|
|
22
22
|
end
|
23
23
|
end
|
24
24
|
|
25
|
-
# Manages errors raised when value should be an
|
25
|
+
# Manages errors raised when value should be an collection
|
26
26
|
class NotAnArray < Error
|
27
27
|
# Initialize an error
|
28
28
|
#
|
@@ -39,13 +39,13 @@ module Otoroshi
|
|
39
39
|
#
|
40
40
|
# @param property [Symbol] name of the property
|
41
41
|
# @param accepted_values [Array] accepted values
|
42
|
-
# @param
|
43
|
-
def initialize(property, accepted_values,
|
42
|
+
# @param collection [true, false] define if it is an collection
|
43
|
+
def initialize(property, accepted_values, collection: false)
|
44
44
|
# reintegrate the colon for symbols which is lost during interpolation
|
45
45
|
to_s = ->(v) { v.is_a?(Symbol) ? ":#{v}" : v }
|
46
46
|
accepted_values_list = accepted_values.map { |v| to_s.call(v) }.join(', ')
|
47
47
|
msg =
|
48
|
-
if
|
48
|
+
if collection
|
49
49
|
":#{property} contains elements that are not included in [#{accepted_values_list}]"
|
50
50
|
else
|
51
51
|
":#{property} is not included in [#{accepted_values_list}]"
|
@@ -59,10 +59,10 @@ module Otoroshi
|
|
59
59
|
# Initialize an error
|
60
60
|
#
|
61
61
|
# @param property [Symbol] name of the property
|
62
|
-
# @param
|
63
|
-
def initialize(property,
|
62
|
+
# @param collection [true, false] define if it is an collection
|
63
|
+
def initialize(property, collection: false)
|
64
64
|
msg =
|
65
|
-
if
|
65
|
+
if collection
|
66
66
|
":#{property} contains elements that do not respect the assertion"
|
67
67
|
else
|
68
68
|
":#{property} does not respect the assertion"
|
@@ -0,0 +1,137 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Otoroshi
|
4
|
+
# Drawing of #initialize method
|
5
|
+
#
|
6
|
+
class Initializer
|
7
|
+
class << self
|
8
|
+
# Draw a stringified initialize method
|
9
|
+
#
|
10
|
+
# @param properties [Hash] a description of the class properties
|
11
|
+
#
|
12
|
+
# @return [String]
|
13
|
+
#
|
14
|
+
# @example
|
15
|
+
# <<-RUBY
|
16
|
+
# def initialize(foo:, bar: 0)
|
17
|
+
# self.foo = foo
|
18
|
+
# self.bar = bar
|
19
|
+
# end
|
20
|
+
# RUBY
|
21
|
+
def draw(properties)
|
22
|
+
new(properties).draw
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
# Initialize an instance
|
27
|
+
#
|
28
|
+
# @param properties [Hash] a description of the class properties
|
29
|
+
def initialize(properties = {})
|
30
|
+
@properties = properties
|
31
|
+
end
|
32
|
+
|
33
|
+
# Draws a stringified initialize method
|
34
|
+
#
|
35
|
+
# @return [String]
|
36
|
+
#
|
37
|
+
# @example
|
38
|
+
# <<-RUBY
|
39
|
+
# def initialize(foo:, bar: 0)
|
40
|
+
# self.foo = foo
|
41
|
+
# self.bar = bar
|
42
|
+
# end
|
43
|
+
# RUBY
|
44
|
+
def draw
|
45
|
+
<<-RUBY
|
46
|
+
def initialize(#{initialize_parameters})
|
47
|
+
#{initialize_assignments}
|
48
|
+
#{initialize_push_singletons}
|
49
|
+
end
|
50
|
+
RUBY
|
51
|
+
end
|
52
|
+
|
53
|
+
private
|
54
|
+
|
55
|
+
attr_reader :properties
|
56
|
+
|
57
|
+
# Generates initialize method parameters
|
58
|
+
#
|
59
|
+
# @return [String]
|
60
|
+
#
|
61
|
+
# @example Given properties { foo: { allow_nil: false, default: nil }, { allow_nil: true, default: 0 } }
|
62
|
+
# redefine_initialize #=> "foo:, bar: 0"
|
63
|
+
def initialize_parameters
|
64
|
+
parameters =
|
65
|
+
properties.map do |key, options|
|
66
|
+
"#{key}:#{default_parameter_for(options)}"
|
67
|
+
end
|
68
|
+
parameters.join(', ')
|
69
|
+
end
|
70
|
+
|
71
|
+
# Fixes the default value of a parameter depending on options
|
72
|
+
#
|
73
|
+
# @return [String]
|
74
|
+
#
|
75
|
+
# @example when nil is allowed and default is set
|
76
|
+
# default_parameter_for #=> " 0"
|
77
|
+
# @example when nil is allowed and default is not set
|
78
|
+
# default_parameter_for #=> " nil"
|
79
|
+
# @example when nil is not allowed
|
80
|
+
# default_parameter_for #=> ""
|
81
|
+
def default_parameter_for(options)
|
82
|
+
default, allow_nil = options.values_at(:default, :allow_nil)
|
83
|
+
if default
|
84
|
+
symbol_prefix = default.is_a?(Symbol) ? ':' : ''
|
85
|
+
" #{symbol_prefix}#{default}"
|
86
|
+
else
|
87
|
+
allow_nil ? ' nil' : ''
|
88
|
+
end
|
89
|
+
end
|
90
|
+
|
91
|
+
# Generates initialize method assignments
|
92
|
+
#
|
93
|
+
# @return [String]
|
94
|
+
#
|
95
|
+
# @example Given properties { foo: { allow_nil: false, default: nil }, { allow_nil: true, default: 0 } }
|
96
|
+
# initialize_body #=> "self.foo = foo\nself.bar = bar"
|
97
|
+
def initialize_assignments
|
98
|
+
assignments =
|
99
|
+
properties.keys.map do |name|
|
100
|
+
"self.#{name} = #{name}"
|
101
|
+
end
|
102
|
+
assignments.join("\n")
|
103
|
+
end
|
104
|
+
|
105
|
+
# Generates push singleton for each array property
|
106
|
+
#
|
107
|
+
# @return [String]
|
108
|
+
def initialize_push_singletons
|
109
|
+
collections =
|
110
|
+
properties.select do |_, options|
|
111
|
+
options[:type].is_a?(Array) || options[:type] == Array
|
112
|
+
end
|
113
|
+
singletons =
|
114
|
+
collections.keys.map do |name|
|
115
|
+
initialize_push_singleton(name)
|
116
|
+
end
|
117
|
+
singletons.join("\n")
|
118
|
+
end
|
119
|
+
|
120
|
+
# Generates singleton on collection instance variable to overide <<
|
121
|
+
# so value is validated before being added to the collection
|
122
|
+
#
|
123
|
+
# @return [String]
|
124
|
+
def initialize_push_singleton(name)
|
125
|
+
<<-RUBY
|
126
|
+
bind = self
|
127
|
+
@#{name}.singleton_class.send(:define_method, :<<) do |v|
|
128
|
+
bind.send(:"validate_#{name}_type!", [v])
|
129
|
+
bind.send(:"validate_#{name}_inclusion!", [v])
|
130
|
+
bind.send(:"validate_#{name}_assertion!", [v])
|
131
|
+
|
132
|
+
push(v)
|
133
|
+
end
|
134
|
+
RUBY
|
135
|
+
end
|
136
|
+
end
|
137
|
+
end
|
data/lib/otoroshi/sanctuary.rb
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
|
3
|
+
require_relative 'initializer'
|
4
4
|
|
5
5
|
module Otoroshi
|
6
6
|
# This module is designed to be included in a class. This will provide
|
@@ -16,7 +16,7 @@ module Otoroshi
|
|
16
16
|
# property :positive_number, Integer, verify: ->(v) { v >= 0 }
|
17
17
|
# property :number_or_nil, Integer, allow_nil: true
|
18
18
|
# property :number_with_default, Integer, default: 42
|
19
|
-
# property :
|
19
|
+
# property :number_in_collection, Integer, one_of: [1, 2, 3, 5, 8, 13, 21, 34]
|
20
20
|
# end
|
21
21
|
module Sanctuary
|
22
22
|
class << self
|
@@ -27,7 +27,7 @@ module Otoroshi
|
|
27
27
|
end
|
28
28
|
|
29
29
|
# Class methods extended for the base class
|
30
|
-
module ClassMethods
|
30
|
+
module ClassMethods
|
31
31
|
# Adds a new "property" to the class
|
32
32
|
#
|
33
33
|
# @param name [Symbol] the property name
|
@@ -43,30 +43,15 @@ module Otoroshi
|
|
43
43
|
# property name, type: String, assert: ->(v) { v.length > 3 }, allow_nil: true
|
44
44
|
# @example
|
45
45
|
# property scores, type: [Integer], assert: ->(v) { v >= 0 }, default: []
|
46
|
-
def property(
|
47
|
-
name,
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
default: nil
|
53
|
-
)
|
54
|
-
add_to_properties(name, type, one_of, assert, allow_nil, default)
|
55
|
-
define_validate_type!(name, type, allow_nil)
|
56
|
-
define_validate_inclusion!(name, type, one_of, allow_nil)
|
57
|
-
define_validate_assertion!(name, type, assert, allow_nil)
|
46
|
+
def property(name, type = Object, one_of: nil, assert: ->(_) { true }, allow_nil: false, default: nil)
|
47
|
+
add_to_properties(name, type, allow_nil, default)
|
48
|
+
collection = type == Array || type.is_a?(Array)
|
49
|
+
define_validate_type!(name, type, collection, allow_nil)
|
50
|
+
define_validate_inclusion!(name, collection, one_of, allow_nil)
|
51
|
+
define_validate_assertion!(name, collection, assert, allow_nil)
|
58
52
|
define_getter(name)
|
59
53
|
define_setter(name)
|
60
|
-
|
61
|
-
end
|
62
|
-
|
63
|
-
# Checks the type is an array
|
64
|
-
#
|
65
|
-
# @param type [Class, Array<Class>] the tested type
|
66
|
-
#
|
67
|
-
# @return [true, false]
|
68
|
-
def collection?(type)
|
69
|
-
type == Array || type.is_a?(Array)
|
54
|
+
class_eval Initializer.draw(properties), __FILE__, __LINE__ + 1
|
70
55
|
end
|
71
56
|
|
72
57
|
# Returns the class properties
|
@@ -83,12 +68,10 @@ module Otoroshi
|
|
83
68
|
# Updates {properties} to add new property to the returned ones
|
84
69
|
#
|
85
70
|
# @return [void]
|
86
|
-
def add_to_properties(name, type,
|
71
|
+
def add_to_properties(name, type, allow_nil, default)
|
87
72
|
current_state = properties
|
88
73
|
current_state[name] = {
|
89
74
|
type: type,
|
90
|
-
one_of: one_of,
|
91
|
-
assert: assert,
|
92
75
|
allow_nil: allow_nil,
|
93
76
|
default: default
|
94
77
|
}
|
@@ -97,48 +80,42 @@ module Otoroshi
|
|
97
80
|
|
98
81
|
# Defines a private method that raises an error if type is not respected
|
99
82
|
#
|
100
|
-
# @param name [Symbol] the property name
|
101
|
-
# @param type [Class] the type to test against
|
102
|
-
# @param array [true, false] define if the value is an array
|
103
|
-
# @param allow_nil [true, false] allow nil as a value
|
104
|
-
#
|
105
83
|
# @return [void]
|
106
84
|
#
|
107
85
|
# @example
|
108
|
-
# define_validate_type!(score, Integer, false) => def validate_score_type!(value) ...
|
86
|
+
# define_validate_type!(:score, Integer, false) => def validate_score_type!(value) ...
|
109
87
|
# @example Generated method
|
88
|
+
# # given name: :score, type: Integer, allow_nil: false
|
110
89
|
# def validate_score_type!(value)
|
111
90
|
# return if Integer.nil? || false && value.nil?
|
112
91
|
# return if value.is_a? Integer
|
113
92
|
#
|
114
93
|
# raise ArgumentError, ":score does not match required type"
|
115
94
|
# end
|
116
|
-
def define_validate_type!(name, type, allow_nil)
|
95
|
+
def define_validate_type!(name, type, collection, allow_nil)
|
117
96
|
lambda = type_validation(type)
|
118
|
-
|
119
|
-
check_array = ->(v) { v.is_a?(Array) || raise(Otoroshi::NotAnArray, name) }
|
97
|
+
check_collection = ->(v) { v.is_a?(Array) || raise(Otoroshi::NotAnArray, name) }
|
120
98
|
define_method :"validate_#{name}_type!" do |value|
|
121
99
|
return if allow_nil && value.nil?
|
122
100
|
|
123
|
-
|
101
|
+
collection && check_collection.call(value)
|
124
102
|
return if lambda.call(value)
|
125
103
|
|
126
|
-
raise Otoroshi::WrongTypeError.new(name, type,
|
104
|
+
raise Otoroshi::WrongTypeError.new(name, type, collection: collection)
|
127
105
|
end
|
128
106
|
private :"validate_#{name}_type!"
|
129
107
|
end
|
130
108
|
|
131
109
|
# Defines a lambda to be called to validate that value matches the type
|
132
110
|
#
|
133
|
-
# @param type [Class] the type to test against
|
134
|
-
# @param array [true, false] define if the value is an array
|
135
|
-
#
|
136
111
|
# @return [Proc] the lambda to use in order to test that the value matches the type
|
137
112
|
#
|
138
113
|
# @example
|
139
114
|
# type_validation(Integer) #=> ->(v) { v.is_a? Integer }
|
140
115
|
# @example
|
141
116
|
# type_validation([String, Symbol]) #=> ->(v) { [String, Symbol].any? { |t| v.is_a? t } }
|
117
|
+
#
|
118
|
+
# @note params are used for binding in define_method scope
|
142
119
|
def type_validation(type)
|
143
120
|
if type == Array
|
144
121
|
# no expected type for each element, return nil
|
@@ -158,25 +135,22 @@ module Otoroshi
|
|
158
135
|
|
159
136
|
# Defines a private method that raises an error if value is not included in the accepted ones
|
160
137
|
#
|
161
|
-
# @param name [Symbol] the property name
|
162
|
-
# @param array [true, false] define if the value is an array
|
163
|
-
# @param values [Array, nil] the values to test against
|
164
|
-
# @param allow_nil [true, false] allow nil as a value
|
165
|
-
#
|
166
138
|
# @return [void]
|
167
139
|
#
|
168
140
|
# @example
|
169
|
-
#
|
141
|
+
# # given @name = :side
|
142
|
+
# define_validate_inclusion!(:side, ...) => def validate_side_type!(value) ...
|
170
143
|
# @example Generated method
|
144
|
+
# # given name: :side, collection: false, one_of: [:left, :right], allow_nil: false
|
171
145
|
# def validate_side_type!(value)
|
172
146
|
# return if false && value.nil?
|
173
147
|
# return if [:left, :right].include? value
|
174
148
|
#
|
175
149
|
# raise ArgumentError, ":side is not included in accepted values"
|
176
150
|
# end
|
177
|
-
def define_validate_inclusion!(name,
|
178
|
-
validator = collection
|
179
|
-
if
|
151
|
+
def define_validate_inclusion!(name, collection, one_of, allow_nil)
|
152
|
+
validator = collection ? each_inside?(name, one_of) : inside?(name, one_of)
|
153
|
+
if one_of
|
180
154
|
define_method(:"validate_#{name}_inclusion!") do |value|
|
181
155
|
allow_nil && value.nil? || validator.call(value)
|
182
156
|
end
|
@@ -188,47 +162,38 @@ module Otoroshi
|
|
188
162
|
|
189
163
|
# Defines a lambda to be called to validate that value is included in accepted ones
|
190
164
|
#
|
191
|
-
# @param name [Symbol] the property name
|
192
|
-
# @param values [Array, nil] the values to test against
|
193
|
-
#
|
194
165
|
# @return [Proc] the lambda to use in order to test that value is included in accepted ones
|
195
|
-
def inside?(name,
|
166
|
+
def inside?(name, one_of)
|
196
167
|
lambda do |v|
|
197
|
-
|
168
|
+
one_of.include?(v) || raise(Otoroshi::NotAcceptedError.new(name, one_of))
|
198
169
|
end
|
199
170
|
end
|
200
171
|
|
201
172
|
# Defines a lambda to be called to validate that each value is included in accepted ones
|
202
173
|
#
|
203
|
-
# @param name [Symbol] the property name
|
204
|
-
# @param values [Array, nil] the values to test against
|
205
|
-
#
|
206
174
|
# @return [Proc] the lambda to use in order to test that each value is included in accepted ones
|
207
|
-
def each_inside?(name,
|
175
|
+
def each_inside?(name, one_of)
|
208
176
|
lambda do |v|
|
209
|
-
v.all? { |e|
|
177
|
+
v.all? { |e| one_of.include? e } || raise(Otoroshi::NotAcceptedError.new(name, one_of, collection: true))
|
210
178
|
end
|
211
179
|
end
|
212
180
|
|
213
181
|
# Defines a private method that raises an error if assert lambda returns false
|
214
182
|
#
|
215
|
-
# @param name [Symbol] the property name
|
216
|
-
# @param assert [Proc] a lambda processing the value and returning true or false
|
217
|
-
# @param allow_nil [true, false] allow nil as a value
|
218
|
-
#
|
219
183
|
# @return [void]
|
220
184
|
#
|
221
185
|
# @example
|
222
|
-
# define_validate_assertion!(
|
186
|
+
# define_validate_assertion!(:score, ...) #=> def validate_score_assertion!(value) ...
|
223
187
|
# @example Generated instance method
|
188
|
+
# # given name: :score, assert: >(v) { v >= 0 }, allow_nil: false
|
224
189
|
# def validate_score_assertion!(value)
|
225
190
|
# return if false && value.nil?
|
226
191
|
# return if value >= 0
|
227
192
|
#
|
228
193
|
# raise ArgumentError, ":score does not match validation"
|
229
194
|
# end
|
230
|
-
def define_validate_assertion!(name,
|
231
|
-
validator = collection
|
195
|
+
def define_validate_assertion!(name, collection, assert, allow_nil)
|
196
|
+
validator = collection ? each_assert?(name, assert) : assert?(name, assert)
|
232
197
|
define_method :"validate_#{name}_assertion!" do |value|
|
233
198
|
allow_nil && value.nil? || validator.call(value)
|
234
199
|
end
|
@@ -237,57 +202,46 @@ module Otoroshi
|
|
237
202
|
|
238
203
|
# Defines a lambda to be called to validate that value respects the specific
|
239
204
|
#
|
240
|
-
# @param name [Symbol] the property name
|
241
|
-
# @param assert [Proc] a lambda processing the value and returning true or false
|
242
|
-
#
|
243
205
|
# @return [Proc] the lambda to use in order to test that value respects the specific
|
244
206
|
def assert?(name, assert)
|
245
207
|
lambda do |value|
|
246
|
-
|
247
|
-
|
248
|
-
raise Otoroshi::AssertionError, name
|
208
|
+
instance_exec(value, &assert) || raise(Otoroshi::AssertionError, name)
|
249
209
|
end
|
250
210
|
end
|
251
211
|
|
252
212
|
# Defines a lambda to be called to validate that value respects the specific
|
253
213
|
#
|
254
|
-
# @param name [Symbol] the property name
|
255
|
-
# @param validate [Proc] a lambda processing the value and returning true or false
|
256
|
-
#
|
257
214
|
# @return [Proc] the lambda to use in order to test that each value respects the specific
|
258
|
-
def each_assert?(name,
|
215
|
+
def each_assert?(name, assert)
|
259
216
|
lambda do |value|
|
260
|
-
|
261
|
-
|
262
|
-
raise Otoroshi::AssertionError.new(name, array: true)
|
217
|
+
value.all? { |e| instance_exec(e, &assert) } ||
|
218
|
+
raise(Otoroshi::AssertionError.new(name, collection: true))
|
263
219
|
end
|
264
220
|
end
|
265
221
|
|
266
222
|
# Defines a getter method for the property
|
267
223
|
#
|
268
|
-
# @param name [Symbol] the property name
|
269
|
-
#
|
270
224
|
# @return [void]
|
271
225
|
#
|
272
226
|
# @example
|
273
227
|
# define_getter(:score) #=> def score ...
|
274
228
|
# @example Generated instance method
|
275
|
-
#
|
276
|
-
#
|
277
|
-
#
|
229
|
+
# # given name: :score
|
230
|
+
# def score
|
231
|
+
# instance_variable_get(@score)
|
232
|
+
# end
|
278
233
|
def define_getter(name)
|
279
234
|
define_method(name) { instance_variable_get("@#{name}") }
|
280
235
|
end
|
281
236
|
|
282
237
|
# Defines a setter method for the property
|
283
238
|
#
|
284
|
-
# @param name [Symbol] the property name
|
285
|
-
#
|
286
239
|
# @return [void]
|
287
240
|
#
|
288
241
|
# @example
|
289
|
-
#
|
242
|
+
# define_setter(:score) #=> def score=(value) ...
|
290
243
|
# @example Generated instance method
|
244
|
+
# # given name: :score
|
291
245
|
# def score=(value)
|
292
246
|
# validate_score_type!(value)
|
293
247
|
# validate_score!(value)
|
@@ -301,99 +255,6 @@ module Otoroshi
|
|
301
255
|
instance_variable_set("@#{name}", value)
|
302
256
|
end
|
303
257
|
end
|
304
|
-
|
305
|
-
# Redefines initialize method
|
306
|
-
#
|
307
|
-
# @return [void]
|
308
|
-
#
|
309
|
-
# @note method is defined with `class_eval`
|
310
|
-
#
|
311
|
-
# @example Generated method
|
312
|
-
# def initialize(foo:, bar: 0)
|
313
|
-
# self.foo = foo
|
314
|
-
# self.bar = bar
|
315
|
-
# end
|
316
|
-
def redefine_initialize
|
317
|
-
class_eval <<-RUBY, __FILE__, __LINE__ + 1
|
318
|
-
def initialize(#{initialize_parameters})
|
319
|
-
#{initialize_assignments}
|
320
|
-
#{initialize_push_singletons}
|
321
|
-
end
|
322
|
-
RUBY
|
323
|
-
end
|
324
|
-
|
325
|
-
# Generates initialize method parameters
|
326
|
-
#
|
327
|
-
# @return [String]
|
328
|
-
#
|
329
|
-
# @example Given properties { foo: { allow_nil: false, default: nil }, { allow_nil: true, default: 0 } }
|
330
|
-
# redefine_initialize #=> "foo:, bar: 0"
|
331
|
-
def initialize_parameters
|
332
|
-
parameters =
|
333
|
-
properties.map do |key, options|
|
334
|
-
allow_nil, default = options.values
|
335
|
-
"#{key}:#{default_parameter_for(allow_nil, default)}"
|
336
|
-
end
|
337
|
-
parameters.join(', ')
|
338
|
-
end
|
339
|
-
|
340
|
-
# Fixes the default value of a parameter depending on options
|
341
|
-
#
|
342
|
-
# @param options [Hash]
|
343
|
-
#
|
344
|
-
# @return [String]
|
345
|
-
#
|
346
|
-
# @example when nil is allowed and default is set
|
347
|
-
# default_parameter_for(true, 0) #=> " 0"
|
348
|
-
# @example when nil is allowed and default is not set
|
349
|
-
# default_parameter_for(true, nil) #=> " nil"
|
350
|
-
# @example when nil is not allowed
|
351
|
-
# default_parameter_for(false, nil) #=> ""
|
352
|
-
def default_parameter_for(allow_nil, default)
|
353
|
-
if default
|
354
|
-
symbol_prefix = default.is_a?(Symbol) ? ':' : ''
|
355
|
-
" #{symbol_prefix}#{default}"
|
356
|
-
else
|
357
|
-
allow_nil ? ' nil' : ''
|
358
|
-
end
|
359
|
-
end
|
360
|
-
|
361
|
-
# Generates initialize method assignments
|
362
|
-
#
|
363
|
-
# @return [String]
|
364
|
-
#
|
365
|
-
# @example Given properties { foo: { allow_nil: false, default: nil }, { allow_nil: true, default: 0 } }
|
366
|
-
# initialize_body #=> "self.foo = foo\nself.bar = bar"
|
367
|
-
def initialize_assignments
|
368
|
-
properties.keys.map { |name| "self.#{name} = #{name}" }.join("\n")
|
369
|
-
end
|
370
|
-
|
371
|
-
# Generates push singleton for each array property
|
372
|
-
#
|
373
|
-
# @return [String]
|
374
|
-
def initialize_push_singletons
|
375
|
-
collections = properties.select { |_, options| collection?(options[:type]) }
|
376
|
-
singletons =
|
377
|
-
collections.keys.map { |name| initialize_push_singleton(name) }
|
378
|
-
singletons.join("\n")
|
379
|
-
end
|
380
|
-
|
381
|
-
# Generates singleton on array instance variable to overide <<
|
382
|
-
# so value is validated before being added to the array
|
383
|
-
#
|
384
|
-
# @return [String]
|
385
|
-
def initialize_push_singleton(name)
|
386
|
-
<<-RUBY
|
387
|
-
bind = self
|
388
|
-
@#{name}.singleton_class.send(:define_method, :<<) do |v|
|
389
|
-
bind.send(:"validate_#{name}_type!", [v])
|
390
|
-
bind.send(:"validate_#{name}_inclusion!", [v])
|
391
|
-
bind.send(:"validate_#{name}_assertion!", [v])
|
392
|
-
|
393
|
-
push(v)
|
394
|
-
end
|
395
|
-
RUBY
|
396
|
-
end
|
397
258
|
end
|
398
259
|
end
|
399
260
|
end
|