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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: af49a7ace939612da586885e144e872e26f9bab6
4
- data.tar.gz: a55532d8fc6a2eb3350b19768e5ac403f3329b2b
3
+ metadata.gz: c1be90f666a6468f4f4e574b85edcf706d7336a7
4
+ data.tar.gz: c485bbe47dbd2ff849aad2b3c7dc4a9b8521cc0a
5
5
  SHA512:
6
- metadata.gz: df2402e3c80c6d2ec64291d61a31f3c9e8c50dff4383f29b1f72e56bd801473a40daea2b9e97199f87a16a959ec63670af210fedbd4a343b68c0a5c7cbd34ecb
7
- data.tar.gz: 5dd6bcb8988fb8a1add9932e038fd84df732f5c84c494efcfbe00be5ac3f549bc6f70a07cb34506fd23dd1ef30e7e0e274a7b53e1e3bbab281cf03a45ee4d3dc
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`.
@@ -8,6 +8,7 @@ require 'eapi/children'
8
8
  require 'eapi/multiple_value'
9
9
  require 'eapi/definition_runners'
10
10
  require 'eapi/type_checker'
11
+ require 'eapi/value_ignore_checker'
11
12
  require 'eapi/methods'
12
13
  require 'eapi/value_converter'
13
14
  require 'eapi/common'
@@ -22,6 +22,11 @@ module Eapi
22
22
  def validate!
23
23
  raise Eapi::Errors::InvalidElementError, "errors: #{errors.full_messages}, self: #{self.inspect}" unless valid?
24
24
  end
25
+
26
+ def render
27
+ validate!
28
+ perform_render
29
+ end
25
30
  end
26
31
 
27
32
  module ClassMethods
@@ -12,20 +12,22 @@ module Eapi
12
12
  Eapi::Common.add_features klass
13
13
  end
14
14
 
15
- def render
16
- validate!
17
- create_hash
15
+ def to_h
16
+ render
18
17
  end
19
18
 
20
- alias_method :to_h, :render
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.nil?
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
@@ -30,15 +30,12 @@ module Eapi
30
30
  true
31
31
  end
32
32
 
33
- def render
34
- validate!
35
- create_array
33
+ def to_a
34
+ render
36
35
  end
37
36
 
38
- alias_method :to_a, :render
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 << value
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
@@ -1,3 +1,3 @@
1
1
  module Eapi
2
- VERSION = "0.3.0"
2
+ VERSION = "0.4.0"
3
3
  end
@@ -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 exluding nils (if all validations pass)' do
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.3.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-19 00:00:00.000000000 Z
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: