eapi 0.3.0 → 0.4.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +195 -167
- data/lib/eapi.rb +1 -0
- data/lib/eapi/common.rb +5 -0
- data/lib/eapi/item.rb +9 -7
- data/lib/eapi/list.rb +9 -7
- data/lib/eapi/methods/accessor.rb +6 -1
- data/lib/eapi/methods/properties.rb +9 -1
- data/lib/eapi/value_ignore_checker.rb +28 -0
- data/lib/eapi/version.rb +1 -1
- data/spec/ignore_spec.rb +178 -0
- data/spec/{to_h_spec.rb → render_spec.rb} +24 -2
- metadata +7 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: c1be90f666a6468f4f4e574b85edcf706d7336a7
|
4
|
+
data.tar.gz: c485bbe47dbd2ff849aad2b3c7dc4a9b8521cc0a
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: da17b4c132b4f45b868bf64eb1fde65faafe04e34fea500694b372aa057f7c1c21076c222e45169c7f45bdcfe5b66fed65e21bcfec86d2578f45c3fca423951a
|
7
|
+
data.tar.gz: 433e10ff4cd1bd992eef4a4779c003891d9c2f35d72e46ce4559ef83593c88b1e58731868519f538b13f63e10bf4a4f61b9e3d7b1e00f470144bdbab8ee9e46a
|
data/README.md
CHANGED
@@ -63,6 +63,201 @@ This will provide:
|
|
63
63
|
|
64
64
|
We'll se this in detail.
|
65
65
|
|
66
|
+
|
67
|
+
## Common behaviour to `Item` and `List`
|
68
|
+
|
69
|
+
The following features are shared between `List`s and `Item`s.
|
70
|
+
|
71
|
+
### Convert to hashes: `render` and `perform_render`
|
72
|
+
|
73
|
+
All Eapi objects respond to `render` and return by default a hash (for `Item` objects) or an array (for `List` objects), as it is the main purpose of this gem. It will execute any validation (see property definition), and if everything is ok, it will convert it to the simple structure.
|
74
|
+
|
75
|
+
`Item` objects will invoke `render` when receiving `to_h`, while `List` objects will do the same when receiving `to_a`.
|
76
|
+
|
77
|
+
#### Methods involved
|
78
|
+
|
79
|
+
Inside, `render` will call `valid?`, raise an error of type `Eapi::Errors::InvalidElementError` if something is not right, and if everything is ok it will call `perform_render`.
|
80
|
+
|
81
|
+
On `Item` objects, the `perform_render` method will create a hash with the properties as keys. Each value will be "converted" (see "Values conversion" section). On `List` objects, the `perform_render` will create an array, with all
|
82
|
+
|
83
|
+
#### Values conversion
|
84
|
+
|
85
|
+
By default, each property will be converted into a simple element (Array, Hash, or simple value).
|
86
|
+
|
87
|
+
1. If a value responds to `render`, it will call that method. That way, Eapi objects that are values of some properties or lists will be validated and rendered (converted) themselves (render / value conversion cascade).
|
88
|
+
2. If a value is an Array or a Set, `to_a` will be invoked and all values will be converted in the same way.
|
89
|
+
3. If a value respond to `to_h`, it will be called.
|
90
|
+
|
91
|
+
#### Ignoring values
|
92
|
+
|
93
|
+
By default, any `nil` values will be omitted in the final structure by the `perform_render` method, in both `Item` and `List`.
|
94
|
+
|
95
|
+
With the `ignore` option in the definition, that behaviour can be modified.
|
96
|
+
|
97
|
+
* `ignore: false`: that no value will be ignored
|
98
|
+
* `ignore: :blank?`: with a string or a symbol in the `ignore` option, the value will be ignored if it respond truthy to the message represented by that `ignore` option. (ie: `ignore: :blank?` => all values that return truthy to `value.blank?` will be ignored)
|
99
|
+
* `ignore: Proc|Callable|Lambda`: with a callable object in the `ignore` option, the value will be ignored if the callable object respond truthy when invoked with the value as argument.
|
100
|
+
|
101
|
+
```ruby
|
102
|
+
class ExampleItem
|
103
|
+
include Eapi::Item
|
104
|
+
|
105
|
+
# by default, ignored if value is `nil`
|
106
|
+
property :prop1
|
107
|
+
|
108
|
+
# ignored if value returns truthy to `.blank?`
|
109
|
+
property :prop2, ignore: :blank?
|
110
|
+
|
111
|
+
# never ignored
|
112
|
+
property :prop3, ignore: false
|
113
|
+
|
114
|
+
# ignored if the callable object returns true when `.call(value)` (in this case, if the value is equal to "i don't want you")
|
115
|
+
property :prop4, ignore: Proc.new {|val| val == "i don't want you"}
|
116
|
+
end
|
117
|
+
```
|
118
|
+
|
119
|
+
#### Example
|
120
|
+
|
121
|
+
To demonstrate this behaviour we'll have an Eapi enabled class `ExampleEapi` and another `ComplexValue` class that responds to `to_h`. We'll set into the `ExampleEapi` object complex properties to demonstrate the conversion into a simple structure.
|
122
|
+
|
123
|
+
```ruby
|
124
|
+
class ComplexValue
|
125
|
+
def to_h
|
126
|
+
{
|
127
|
+
a: Set.new(['hello', 'world', MyTestObject.new])
|
128
|
+
}
|
129
|
+
end
|
130
|
+
end
|
131
|
+
|
132
|
+
class ExampleEapi
|
133
|
+
include Eapi::Item
|
134
|
+
|
135
|
+
property :something, required: true
|
136
|
+
property :other
|
137
|
+
end
|
138
|
+
|
139
|
+
# TESTING `render`
|
140
|
+
|
141
|
+
list = Set.new [
|
142
|
+
OpenStruct.new(a: 1, 'b' => 2),
|
143
|
+
{c: 3, 'd' => 4},
|
144
|
+
nil
|
145
|
+
]
|
146
|
+
|
147
|
+
eapi = ExampleEapi.new something: list, other: ComplexValue.new
|
148
|
+
|
149
|
+
# same as eapi.to_h
|
150
|
+
eapi.render # =>
|
151
|
+
# {
|
152
|
+
# something: [
|
153
|
+
# {a: 1, b: 2},
|
154
|
+
# {c: 3, d: 4},
|
155
|
+
# ],
|
156
|
+
#
|
157
|
+
# other: {
|
158
|
+
# a: [
|
159
|
+
# 'hello',
|
160
|
+
# 'world',
|
161
|
+
# {a: 'hello'}
|
162
|
+
# ]
|
163
|
+
# }
|
164
|
+
# }
|
165
|
+
```
|
166
|
+
|
167
|
+
### Pose as other types
|
168
|
+
|
169
|
+
An Eapi class can poses as other types, for purposes of `type` checking in a property definition. We use the class method `is` for this.
|
170
|
+
|
171
|
+
the `is?` method is also available as an instance method.
|
172
|
+
|
173
|
+
Eapi also creates specific instance and class methods like `is_a_some_type?` or `is_an_another_type?`.
|
174
|
+
|
175
|
+
example:
|
176
|
+
|
177
|
+
```ruby
|
178
|
+
class SuperTestKlass
|
179
|
+
include Eapi::Item
|
180
|
+
end
|
181
|
+
|
182
|
+
class TestKlass < SuperTestKlass
|
183
|
+
is :one_thing, :other_thing, OtherType
|
184
|
+
end
|
185
|
+
|
186
|
+
TestKlass.is? TestKlass # => true
|
187
|
+
TestKlass.is? 'TestKlass' # => true
|
188
|
+
TestKlass.is? :TestKlass # => true
|
189
|
+
|
190
|
+
TestKlass.is? SuperTestKlass # => true
|
191
|
+
TestKlass.is? 'SuperTestKlass' # => true
|
192
|
+
TestKlass.is? :SuperTestKlass # => true
|
193
|
+
|
194
|
+
TestKlass.is? :one_thing # => true
|
195
|
+
TestKlass.is? :other_thing # => true
|
196
|
+
TestKlass.is? :other_thing # => true
|
197
|
+
TestKlass.is? OtherType # => true
|
198
|
+
TestKlass.is? :OtherType # => true
|
199
|
+
|
200
|
+
TestKlass.is? SomethingElse # => false
|
201
|
+
TestKlass.is? :SomethingElse # => false
|
202
|
+
|
203
|
+
# also works on instance
|
204
|
+
obj = TestKlass.new
|
205
|
+
obj.is? TestKlass # => true
|
206
|
+
obj.is? :one_thing # => true
|
207
|
+
|
208
|
+
# specific type test methods
|
209
|
+
TestKlass.is_a_test_klass? # => true
|
210
|
+
TestKlass.is_an_one_thing? # => true
|
211
|
+
TestKlass.is_a_super_duper_thing? # => false
|
212
|
+
|
213
|
+
obj.is_a_test_klass? # => true
|
214
|
+
obj.is_an_one_thing? # => true
|
215
|
+
obj.is_a_super_duper_thing? # => false
|
216
|
+
```
|
217
|
+
|
218
|
+
### Object creation shortcut: calling methods in Eapi
|
219
|
+
|
220
|
+
Calling a method with the desired class name in `Eapi` module will do the same as `DesiredClass.new(...)`. The name can be the same as the class, or an underscorised version, or a simple underscored one.
|
221
|
+
|
222
|
+
The goal is to use `Eapi.esr_search(name: 'Paco')` as a shortcut to `Esr::Search.new(name: 'Paco')`. We can also use `Eapi.Esr_Search(...)` and other combinations.
|
223
|
+
|
224
|
+
To show this feature and all the combinations for method names, we'll use the 2 example classes that are used in the actual test rspec.
|
225
|
+
|
226
|
+
```ruby
|
227
|
+
class MyTestKlassOutside
|
228
|
+
include Eapi::Item
|
229
|
+
|
230
|
+
property :something
|
231
|
+
end
|
232
|
+
|
233
|
+
module Somewhere
|
234
|
+
class TestKlassInModule
|
235
|
+
include Eapi::Item
|
236
|
+
|
237
|
+
property :something
|
238
|
+
end
|
239
|
+
end
|
240
|
+
```
|
241
|
+
|
242
|
+
As shown by rspec run:
|
243
|
+
|
244
|
+
```
|
245
|
+
initialise using method calls to Eapi
|
246
|
+
Eapi.MyTestKlassOutside(...)
|
247
|
+
calls MyTestKlassOutside.new
|
248
|
+
Eapi.my_test_klass_outside(...)
|
249
|
+
calls MyTestKlassOutside.new
|
250
|
+
Eapi.Somewhere__TestKlassInModule(...)
|
251
|
+
calls Somewhere::TestKlassInModule.new
|
252
|
+
Eapi.somewhere__test_klass_in_module(...)
|
253
|
+
calls Somewhere::TestKlassInModule.new
|
254
|
+
Eapi.Somewhere_TestKlassInModule(...)
|
255
|
+
calls Somewhere::TestKlassInModule.new
|
256
|
+
Eapi.somewhere_test_klass_in_module(...)
|
257
|
+
calls Somewhere::TestKlassInModule.new
|
258
|
+
```
|
259
|
+
|
260
|
+
|
66
261
|
## `Eapi::Item`: Property based Item objects
|
67
262
|
|
68
263
|
### `initialize` method
|
@@ -141,76 +336,6 @@ x.one # => :fluent
|
|
141
336
|
res.equal? x # => true
|
142
337
|
```
|
143
338
|
|
144
|
-
### Convert to hashes: `render`, `to_h` and `create_hash`
|
145
|
-
|
146
|
-
All Eapi classes respond to `render` and return a hash (for `Item` classes) or an array (for `List` classes), as it is the main purpose of this gem. It will execute any validation (see property definition), and if everything is ok, it will convert it to a simple hash structure.
|
147
|
-
|
148
|
-
`Item` classes will invoke `render` when receiving `to_h`, while `List` classes will do the same when receiving `to_a`
|
149
|
-
|
150
|
-
#### Methods involved
|
151
|
-
|
152
|
-
Inside, `render` will call `valid?`, raise an error of type `Eapi::Errors::InvalidElementError` if something is not right, and if everything is ok it will call `create_hash`.
|
153
|
-
|
154
|
-
The `create_hash` method will create a hash with the properties as keys. Each value will be "converted" (see "Values conversion" section).
|
155
|
-
|
156
|
-
#### Values conversion
|
157
|
-
|
158
|
-
By default, each property will be converted into a simple element (Array, Hash, or simple value).
|
159
|
-
|
160
|
-
1. If a value responds to `render`, it will call that method. That way, Eapi objects that are values of some properties or lists will be validated and rendered (converted) themselves (render / value conversion cascade).
|
161
|
-
2. If a value is an Array or a Set, `to_a` will be invoked and all values will be converted in the same way.
|
162
|
-
3. If a value respond to `to_h`, it will be called.
|
163
|
-
|
164
|
-
important: *any nil value will be omitted* in the final hash.
|
165
|
-
|
166
|
-
#### Example
|
167
|
-
|
168
|
-
To demonstrate this behaviour we'll have an Eapi enabled class `ExampleEapi` and another `ComplexValue` class that responds to `to_h`. We'll set into the `ExampleEapi` object complex properties to demonstrate the conversion into a simple structure.
|
169
|
-
|
170
|
-
```ruby
|
171
|
-
class ComplexValue
|
172
|
-
def to_h
|
173
|
-
{
|
174
|
-
a: Set.new(['hello', 'world', MyTestObject.new])
|
175
|
-
}
|
176
|
-
end
|
177
|
-
end
|
178
|
-
|
179
|
-
class ExampleEapi
|
180
|
-
include Eapi::Item
|
181
|
-
|
182
|
-
property :something, required: true
|
183
|
-
property :other
|
184
|
-
end
|
185
|
-
|
186
|
-
# TESTING `render`
|
187
|
-
|
188
|
-
list = Set.new [
|
189
|
-
OpenStruct.new(a: 1, 'b' => 2),
|
190
|
-
{c: 3, 'd' => 4},
|
191
|
-
nil
|
192
|
-
]
|
193
|
-
|
194
|
-
eapi = ExampleEapi.new something: list, other: ComplexValue.new
|
195
|
-
|
196
|
-
# same as eapi.to_h
|
197
|
-
eapi.render # =>
|
198
|
-
# {
|
199
|
-
# something: [
|
200
|
-
# {a: 1, b: 2},
|
201
|
-
# {c: 3, d: 4},
|
202
|
-
# ],
|
203
|
-
#
|
204
|
-
# other: {
|
205
|
-
# a: [
|
206
|
-
# 'hello',
|
207
|
-
# 'world',
|
208
|
-
# {a: 'hello'}
|
209
|
-
# ]
|
210
|
-
# }
|
211
|
-
# }
|
212
|
-
```
|
213
|
-
|
214
339
|
### Property definition
|
215
340
|
|
216
341
|
When defining the property, we can specify some options to specify what values are expected in that property. This serves for validation and automatic initialisation.
|
@@ -621,103 +746,6 @@ l.add(1)
|
|
621
746
|
l.valid? # => false
|
622
747
|
```
|
623
748
|
|
624
|
-
## Common to `Item` and `List`
|
625
|
-
|
626
|
-
The following features are shared between `List`s and `Item`s.
|
627
|
-
|
628
|
-
### Pose as other types
|
629
|
-
|
630
|
-
An Eapi class can poses as other types, for purposes of `type` checking in a property definition. We use the class method `is` for this.
|
631
|
-
|
632
|
-
the `is?` method is also available as an instance method.
|
633
|
-
|
634
|
-
Eapi also creates specific instance and class methods like `is_a_some_type?` or `is_an_another_type?`.
|
635
|
-
|
636
|
-
example:
|
637
|
-
|
638
|
-
```ruby
|
639
|
-
class SuperTestKlass
|
640
|
-
include Eapi::Item
|
641
|
-
end
|
642
|
-
|
643
|
-
class TestKlass < SuperTestKlass
|
644
|
-
is :one_thing, :other_thing, OtherType
|
645
|
-
end
|
646
|
-
|
647
|
-
TestKlass.is? TestKlass # => true
|
648
|
-
TestKlass.is? 'TestKlass' # => true
|
649
|
-
TestKlass.is? :TestKlass # => true
|
650
|
-
|
651
|
-
TestKlass.is? SuperTestKlass # => true
|
652
|
-
TestKlass.is? 'SuperTestKlass' # => true
|
653
|
-
TestKlass.is? :SuperTestKlass # => true
|
654
|
-
|
655
|
-
TestKlass.is? :one_thing # => true
|
656
|
-
TestKlass.is? :other_thing # => true
|
657
|
-
TestKlass.is? :other_thing # => true
|
658
|
-
TestKlass.is? OtherType # => true
|
659
|
-
TestKlass.is? :OtherType # => true
|
660
|
-
|
661
|
-
TestKlass.is? SomethingElse # => false
|
662
|
-
TestKlass.is? :SomethingElse # => false
|
663
|
-
|
664
|
-
# also works on instance
|
665
|
-
obj = TestKlass.new
|
666
|
-
obj.is? TestKlass # => true
|
667
|
-
obj.is? :one_thing # => true
|
668
|
-
|
669
|
-
# specific type test methods
|
670
|
-
TestKlass.is_a_test_klass? # => true
|
671
|
-
TestKlass.is_an_one_thing? # => true
|
672
|
-
TestKlass.is_a_super_duper_thing? # => false
|
673
|
-
|
674
|
-
obj.is_a_test_klass? # => true
|
675
|
-
obj.is_an_one_thing? # => true
|
676
|
-
obj.is_a_super_duper_thing? # => false
|
677
|
-
```
|
678
|
-
|
679
|
-
### Object creation shortcut: calling methods in Eapi
|
680
|
-
|
681
|
-
Calling a method with the desired class name in `Eapi` module will do the same as `DesiredClass.new(...)`. The name can be the same as the class, or an underscorised version, or a simple underscored one.
|
682
|
-
|
683
|
-
The goal is to use `Eapi.esr_search(name: 'Paco')` as a shortcut to `Esr::Search.new(name: 'Paco')`. We can also use `Eapi.Esr_Search(...)` and other combinations.
|
684
|
-
|
685
|
-
To show this feature and all the combinations for method names, we'll use the 2 example classes that are used in the actual test rspec.
|
686
|
-
|
687
|
-
```ruby
|
688
|
-
class MyTestKlassOutside
|
689
|
-
include Eapi::Item
|
690
|
-
|
691
|
-
property :something
|
692
|
-
end
|
693
|
-
|
694
|
-
module Somewhere
|
695
|
-
class TestKlassInModule
|
696
|
-
include Eapi::Item
|
697
|
-
|
698
|
-
property :something
|
699
|
-
end
|
700
|
-
end
|
701
|
-
```
|
702
|
-
|
703
|
-
As shown by rspec run:
|
704
|
-
|
705
|
-
```
|
706
|
-
initialise using method calls to Eapi
|
707
|
-
Eapi.MyTestKlassOutside(...)
|
708
|
-
calls MyTestKlassOutside.new
|
709
|
-
Eapi.my_test_klass_outside(...)
|
710
|
-
calls MyTestKlassOutside.new
|
711
|
-
Eapi.Somewhere__TestKlassInModule(...)
|
712
|
-
calls Somewhere::TestKlassInModule.new
|
713
|
-
Eapi.somewhere__test_klass_in_module(...)
|
714
|
-
calls Somewhere::TestKlassInModule.new
|
715
|
-
Eapi.Somewhere_TestKlassInModule(...)
|
716
|
-
calls Somewhere::TestKlassInModule.new
|
717
|
-
Eapi.somewhere_test_klass_in_module(...)
|
718
|
-
calls Somewhere::TestKlassInModule.new
|
719
|
-
```
|
720
|
-
|
721
749
|
## Using Eapi in your own library
|
722
750
|
|
723
751
|
You can add the functionality of Eapi to your own library module, and use it instead of `Eapi::Item` or `Eapi::List`.
|
data/lib/eapi.rb
CHANGED
data/lib/eapi/common.rb
CHANGED
data/lib/eapi/item.rb
CHANGED
@@ -12,20 +12,22 @@ module Eapi
|
|
12
12
|
Eapi::Common.add_features klass
|
13
13
|
end
|
14
14
|
|
15
|
-
def
|
16
|
-
|
17
|
-
create_hash
|
15
|
+
def to_h
|
16
|
+
render
|
18
17
|
end
|
19
18
|
|
20
|
-
|
21
|
-
|
22
|
-
def create_hash
|
19
|
+
def perform_render
|
23
20
|
{}.tap do |hash|
|
24
21
|
_properties.each do |prop|
|
25
22
|
val = converted_value_for(prop)
|
26
|
-
hash[prop] = val unless val
|
23
|
+
hash[prop] = val unless to_be_ignored?(val, prop)
|
27
24
|
end
|
28
25
|
end
|
29
26
|
end
|
27
|
+
|
28
|
+
private
|
29
|
+
def to_be_ignored?(value, property)
|
30
|
+
Eapi::ValueIgnoreChecker.to_be_ignored? value, self.class.ignore_definition(property)
|
31
|
+
end
|
30
32
|
end
|
31
33
|
end
|
data/lib/eapi/list.rb
CHANGED
@@ -30,15 +30,12 @@ module Eapi
|
|
30
30
|
true
|
31
31
|
end
|
32
32
|
|
33
|
-
def
|
34
|
-
|
35
|
-
create_array
|
33
|
+
def to_a
|
34
|
+
render
|
36
35
|
end
|
37
36
|
|
38
|
-
|
39
|
-
|
40
|
-
def create_array
|
41
|
-
_list.map { |val| convert_value val }
|
37
|
+
def perform_render
|
38
|
+
_list.map { |val| convert_value val }.reject { |x| to_be_ignored x }
|
42
39
|
end
|
43
40
|
|
44
41
|
def _list
|
@@ -77,6 +74,11 @@ module Eapi
|
|
77
74
|
|
78
75
|
protected :initialize_copy
|
79
76
|
|
77
|
+
private
|
78
|
+
def to_be_ignored(value)
|
79
|
+
Eapi::ValueIgnoreChecker.to_be_ignored? value, self.class.elements_ignore_definition
|
80
|
+
end
|
81
|
+
|
80
82
|
# transpose, assoc, rassoc , permutation, combination, repeated_permutation, repeated_combination, product, pack ?? => do not use the methods
|
81
83
|
end
|
82
84
|
|
@@ -10,7 +10,12 @@ module Eapi
|
|
10
10
|
|
11
11
|
define_method fluent_adder do |value|
|
12
12
|
current = send(getter) || send(init)
|
13
|
-
current
|
13
|
+
if current.respond_to? :add
|
14
|
+
current.add value
|
15
|
+
else
|
16
|
+
current << value
|
17
|
+
end
|
18
|
+
|
14
19
|
send(fluent_setter, current)
|
15
20
|
end
|
16
21
|
end
|
@@ -71,6 +71,10 @@ module Eapi
|
|
71
71
|
@_property_definitions ||= {}
|
72
72
|
end
|
73
73
|
|
74
|
+
def ignore_definition(field)
|
75
|
+
definition_for(field).fetch(:ignore, :nil?)
|
76
|
+
end
|
77
|
+
|
74
78
|
private :_property_allow_raw
|
75
79
|
private :_property_definitions
|
76
80
|
private :run_property_definition
|
@@ -90,13 +94,17 @@ module Eapi
|
|
90
94
|
property_allow_raw?(:_list)
|
91
95
|
end
|
92
96
|
|
97
|
+
def elements_ignore_definition
|
98
|
+
definition_for_elements.fetch(:ignore, :nil?)
|
99
|
+
end
|
100
|
+
|
93
101
|
def elements(definition)
|
94
102
|
run_list_definition definition
|
95
103
|
store_list_definition definition
|
96
104
|
end
|
97
105
|
|
98
106
|
def definition_for_elements
|
99
|
-
@_list_definition
|
107
|
+
@_list_definition ||= {}
|
100
108
|
end
|
101
109
|
|
102
110
|
def store_list_definition(definition)
|
@@ -0,0 +1,28 @@
|
|
1
|
+
module Eapi
|
2
|
+
class ValueIgnoreChecker
|
3
|
+
def self.to_be_ignored?(value, ignore_definition = nil)
|
4
|
+
if ignore_definition.nil?
|
5
|
+
check_by_default value
|
6
|
+
elsif !ignore_definition
|
7
|
+
false
|
8
|
+
elsif ignore_definition.respond_to? :call
|
9
|
+
check_by_callable value, ignore_definition
|
10
|
+
else
|
11
|
+
check_by_message value, ignore_definition
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
private
|
16
|
+
def self.check_by_default(value)
|
17
|
+
value.nil?
|
18
|
+
end
|
19
|
+
|
20
|
+
def self.check_by_message(value, ignore_definition)
|
21
|
+
value.send ignore_definition
|
22
|
+
end
|
23
|
+
|
24
|
+
def self.check_by_callable(value, ignore_definition)
|
25
|
+
ignore_definition.call value
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
data/lib/eapi/version.rb
CHANGED
data/spec/ignore_spec.rb
ADDED
@@ -0,0 +1,178 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
RSpec.describe Eapi do
|
4
|
+
|
5
|
+
class IgnoreSpecTestItemDefault
|
6
|
+
include Eapi::Item
|
7
|
+
property :something
|
8
|
+
end
|
9
|
+
|
10
|
+
class IgnoreSpecTestItemFalse
|
11
|
+
include Eapi::Item
|
12
|
+
property :something, ignore: false
|
13
|
+
end
|
14
|
+
|
15
|
+
class IgnoreSpecTestItemSymbol
|
16
|
+
include Eapi::Item
|
17
|
+
property :something, ignore: :blank?
|
18
|
+
end
|
19
|
+
|
20
|
+
class IgnoreSpecTestItemProc
|
21
|
+
include Eapi::Item
|
22
|
+
property :something, ignore: Proc.new { |x| x.to_s == 'ignoreme' }
|
23
|
+
end
|
24
|
+
|
25
|
+
class IgnoreSpecTestListDefault
|
26
|
+
include Eapi::List
|
27
|
+
end
|
28
|
+
|
29
|
+
class IgnoreSpecTestListFalse
|
30
|
+
include Eapi::List
|
31
|
+
|
32
|
+
elements ignore: false
|
33
|
+
end
|
34
|
+
|
35
|
+
class IgnoreSpecTestListSymbol
|
36
|
+
include Eapi::List
|
37
|
+
|
38
|
+
elements ignore: :blank?
|
39
|
+
end
|
40
|
+
|
41
|
+
class IgnoreSpecTestListProc
|
42
|
+
include Eapi::List
|
43
|
+
|
44
|
+
elements ignore: Proc.new { |x| x.to_s == 'ignoreme' }
|
45
|
+
end
|
46
|
+
|
47
|
+
|
48
|
+
describe 'ignore values on render' do
|
49
|
+
describe 'default (no specification in definition)' do
|
50
|
+
describe 'Item' do
|
51
|
+
subject { IgnoreSpecTestItemDefault.new }
|
52
|
+
it 'ignore nil values' do
|
53
|
+
subject.something nil
|
54
|
+
expect_not_in_hash
|
55
|
+
end
|
56
|
+
|
57
|
+
it 'does not ignore any other value' do
|
58
|
+
subject.something 1
|
59
|
+
expect_in_hash
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
describe 'List' do
|
64
|
+
subject { IgnoreSpecTestListDefault.new }
|
65
|
+
it 'ignore nil values' do
|
66
|
+
subject.add nil
|
67
|
+
expect_not_in_array
|
68
|
+
end
|
69
|
+
|
70
|
+
it 'does not ignore any other value' do
|
71
|
+
subject.add 1
|
72
|
+
expect_in_array
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
describe 'message (symbol or string)' do
|
78
|
+
describe 'Item' do
|
79
|
+
subject { IgnoreSpecTestItemSymbol.new }
|
80
|
+
it 'ignore if sending the message to the value returns truthy' do
|
81
|
+
subject.something ""
|
82
|
+
expect_not_in_hash
|
83
|
+
end
|
84
|
+
|
85
|
+
it 'does not ignore any other value' do
|
86
|
+
subject.something 1
|
87
|
+
expect_in_hash
|
88
|
+
end
|
89
|
+
end
|
90
|
+
|
91
|
+
describe 'List' do
|
92
|
+
subject { IgnoreSpecTestListSymbol.new }
|
93
|
+
it 'ignore if sending the message to the value returns truthy' do
|
94
|
+
subject.add ""
|
95
|
+
expect_not_in_array
|
96
|
+
end
|
97
|
+
|
98
|
+
it 'does not ignore any other value' do
|
99
|
+
subject.add 1
|
100
|
+
expect_in_array
|
101
|
+
end
|
102
|
+
end
|
103
|
+
end
|
104
|
+
|
105
|
+
describe 'false' do
|
106
|
+
describe 'Item' do
|
107
|
+
subject { IgnoreSpecTestItemFalse.new }
|
108
|
+
it 'do not ignore any value (even nils)' do
|
109
|
+
subject.something nil
|
110
|
+
expect_in_hash
|
111
|
+
end
|
112
|
+
|
113
|
+
it 'does not ignore any other value' do
|
114
|
+
subject.something 1
|
115
|
+
expect_in_hash
|
116
|
+
end
|
117
|
+
end
|
118
|
+
|
119
|
+
describe 'List' do
|
120
|
+
subject { IgnoreSpecTestListFalse.new }
|
121
|
+
it 'do not ignore any value (even nils)' do
|
122
|
+
subject.add nil
|
123
|
+
expect_in_array
|
124
|
+
end
|
125
|
+
|
126
|
+
it 'does not ignore any other value' do
|
127
|
+
subject.add 1
|
128
|
+
expect_in_array
|
129
|
+
end
|
130
|
+
end
|
131
|
+
end
|
132
|
+
|
133
|
+
describe 'callable' do
|
134
|
+
describe 'Item' do
|
135
|
+
subject { IgnoreSpecTestItemProc.new }
|
136
|
+
it 'ignore if the callable element with the value returns truthy' do
|
137
|
+
subject.something :ignoreme
|
138
|
+
expect_not_in_hash
|
139
|
+
end
|
140
|
+
|
141
|
+
it 'does not ignore any other value' do
|
142
|
+
subject.something 1
|
143
|
+
expect_in_hash
|
144
|
+
end
|
145
|
+
end
|
146
|
+
|
147
|
+
describe 'List' do
|
148
|
+
subject { IgnoreSpecTestListProc.new }
|
149
|
+
it 'ignore if the callable element with the value returns truthy' do
|
150
|
+
subject.add :ignoreme
|
151
|
+
expect_not_in_array
|
152
|
+
end
|
153
|
+
|
154
|
+
it 'does not ignore any other value' do
|
155
|
+
subject.add 1
|
156
|
+
expect_in_array
|
157
|
+
end
|
158
|
+
end
|
159
|
+
end
|
160
|
+
end
|
161
|
+
|
162
|
+
|
163
|
+
def expect_not_in_hash
|
164
|
+
expect(subject.render.key? :something).to be false
|
165
|
+
end
|
166
|
+
|
167
|
+
def expect_in_hash
|
168
|
+
expect(subject.render.key? :something).to be true
|
169
|
+
end
|
170
|
+
|
171
|
+
def expect_not_in_array
|
172
|
+
expect(subject.render).to be_empty
|
173
|
+
end
|
174
|
+
|
175
|
+
def expect_in_array
|
176
|
+
expect(subject.render).not_to be_empty
|
177
|
+
end
|
178
|
+
end
|
@@ -8,6 +8,7 @@ RSpec.describe Eapi do
|
|
8
8
|
|
9
9
|
property :something, required: true
|
10
10
|
property :other
|
11
|
+
property :again
|
11
12
|
end
|
12
13
|
|
13
14
|
class MyTestObject
|
@@ -36,6 +37,24 @@ RSpec.describe Eapi do
|
|
36
37
|
end
|
37
38
|
end
|
38
39
|
|
40
|
+
class MyTestObjectComplexRender
|
41
|
+
def render
|
42
|
+
{
|
43
|
+
a: Set.new(['hello', 'world', MyTestObject.new])
|
44
|
+
}
|
45
|
+
end
|
46
|
+
|
47
|
+
def expected
|
48
|
+
{
|
49
|
+
a: [
|
50
|
+
'hello',
|
51
|
+
'world',
|
52
|
+
{a: 'hello'}
|
53
|
+
]
|
54
|
+
}
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
39
58
|
it 'raise error if invalid' do
|
40
59
|
eapi = MyTestClassToH.new
|
41
60
|
expect { eapi.to_h }.to raise_error do |error|
|
@@ -58,7 +77,7 @@ RSpec.describe Eapi do
|
|
58
77
|
expect(eapi.to_h).to eq expected
|
59
78
|
end
|
60
79
|
|
61
|
-
it 'hash with elements, all converted to basic Arrays and Hashes (keys as symbols), and
|
80
|
+
it 'hash with elements, all converted to basic Arrays and Hashes (keys as symbols), and excluding nils (if all validations pass)' do
|
62
81
|
list = Set.new [
|
63
82
|
OpenStruct.new(a: 1, 'b' => 2),
|
64
83
|
{c: 3, 'd' => 4},
|
@@ -66,6 +85,7 @@ RSpec.describe Eapi do
|
|
66
85
|
]
|
67
86
|
|
68
87
|
other = MyTestObjectComplex.new
|
88
|
+
again = MyTestObjectComplexRender.new
|
69
89
|
|
70
90
|
expected = {
|
71
91
|
something: [
|
@@ -73,12 +93,14 @@ RSpec.describe Eapi do
|
|
73
93
|
{c: 3, d: 4},
|
74
94
|
],
|
75
95
|
|
76
|
-
other: other.expected
|
96
|
+
other: other.expected,
|
97
|
+
again: again.expected
|
77
98
|
}
|
78
99
|
|
79
100
|
eapi = MyTestClassToH.new
|
80
101
|
eapi.something list
|
81
102
|
eapi.other other
|
103
|
+
eapi.again other
|
82
104
|
|
83
105
|
expect(eapi.to_h).to eq expected
|
84
106
|
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: eapi
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.4.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Eduardo Turiño
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2014-07-
|
11
|
+
date: 2014-07-22 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -211,15 +211,17 @@ files:
|
|
211
211
|
- lib/eapi/multiple_value.rb
|
212
212
|
- lib/eapi/type_checker.rb
|
213
213
|
- lib/eapi/value_converter.rb
|
214
|
+
- lib/eapi/value_ignore_checker.rb
|
214
215
|
- lib/eapi/version.rb
|
215
216
|
- spec/basic_spec.rb
|
216
217
|
- spec/definition_spec.rb
|
217
218
|
- spec/extension_spec.rb
|
218
219
|
- spec/function_spec.rb
|
220
|
+
- spec/ignore_spec.rb
|
219
221
|
- spec/list_elements_spec.rb
|
220
222
|
- spec/list_spec.rb
|
223
|
+
- spec/render_spec.rb
|
221
224
|
- spec/spec_helper.rb
|
222
|
-
- spec/to_h_spec.rb
|
223
225
|
- spec/type_spec.rb
|
224
226
|
- spec/validations_spec.rb
|
225
227
|
homepage: ''
|
@@ -252,10 +254,11 @@ test_files:
|
|
252
254
|
- spec/definition_spec.rb
|
253
255
|
- spec/extension_spec.rb
|
254
256
|
- spec/function_spec.rb
|
257
|
+
- spec/ignore_spec.rb
|
255
258
|
- spec/list_elements_spec.rb
|
256
259
|
- spec/list_spec.rb
|
260
|
+
- spec/render_spec.rb
|
257
261
|
- spec/spec_helper.rb
|
258
|
-
- spec/to_h_spec.rb
|
259
262
|
- spec/type_spec.rb
|
260
263
|
- spec/validations_spec.rb
|
261
264
|
has_rdoc:
|