attribute_struct 0.1.8 → 0.2.0
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGELOG.md +6 -0
- data/CONTRIBUTING.md +25 -0
- data/Gemfile.lock +1 -1
- data/LICENSE +13 -0
- data/attribute_struct.gemspec +1 -0
- data/lib/attribute_struct/attribute_hash.rb +8 -0
- data/lib/attribute_struct/attribute_struct.rb +177 -60
- data/lib/attribute_struct/monkey_camels.rb +13 -4
- data/lib/attribute_struct/version.rb +3 -2
- data/test/specs/collapse.rb +80 -0
- metadata +7 -3
data/CHANGELOG.md
CHANGED
@@ -1,3 +1,9 @@
|
|
1
|
+
## v0.2.0
|
2
|
+
* Add support for value setting into given context level
|
3
|
+
* Add #build helper method
|
4
|
+
* Introduce `:value_collapse` option for multi set combination instead of replacement
|
5
|
+
* Provide bang suffix aliases
|
6
|
+
|
1
7
|
## v0.1.8
|
2
8
|
* Basic (optional) auto camel detection on import
|
3
9
|
* Add hash helper methods out to class
|
data/CONTRIBUTING.md
ADDED
@@ -0,0 +1,25 @@
|
|
1
|
+
# Contributing
|
2
|
+
|
3
|
+
## Branches
|
4
|
+
|
5
|
+
### `master` branch
|
6
|
+
|
7
|
+
The master branch is the current stable released version.
|
8
|
+
|
9
|
+
### `develop` branch
|
10
|
+
|
11
|
+
The develop branch is the current edge of development.
|
12
|
+
|
13
|
+
## Pull requests
|
14
|
+
|
15
|
+
* https://github.com/chrisroberts/attribute_struct/pulls
|
16
|
+
|
17
|
+
Please base all pull requests off the `develop` branch. Merges to
|
18
|
+
`master` only occur through the `develop` branch. Pull requests
|
19
|
+
based on `master` will likely be cherry picked.
|
20
|
+
|
21
|
+
## Issues
|
22
|
+
|
23
|
+
Need to report an issue? Use the github issues:
|
24
|
+
|
25
|
+
* https://github.com/chrisroberts/attribute_struct/issues
|
data/Gemfile.lock
CHANGED
data/LICENSE
ADDED
@@ -0,0 +1,13 @@
|
|
1
|
+
Copyright 2014 Chris Roberts
|
2
|
+
|
3
|
+
Licensed under the Apache License, Version 2.0 (the "License");
|
4
|
+
you may not use this file except in compliance with the License.
|
5
|
+
You may obtain a copy of the License at
|
6
|
+
|
7
|
+
http://www.apache.org/licenses/LICENSE-2.0
|
8
|
+
|
9
|
+
Unless required by applicable law or agreed to in writing, software
|
10
|
+
distributed under the License is distributed on an "AS IS" BASIS,
|
11
|
+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
12
|
+
See the License for the specific language governing permissions and
|
13
|
+
limitations under the License.
|
data/attribute_struct.gemspec
CHANGED
@@ -5,6 +5,7 @@ Gem::Specification.new do |s|
|
|
5
5
|
s.version = AttributeStruct::VERSION.version
|
6
6
|
s.summary = 'Attribute structures'
|
7
7
|
s.author = 'Chris Roberts'
|
8
|
+
s.license = 'Apache 2.0'
|
8
9
|
s.email = 'chrisroberts.code@gmail.com'
|
9
10
|
s.homepage = 'http://github.com/chrisroberts/attribute_struct'
|
10
11
|
s.description = 'Attribute structures'
|
@@ -5,5 +5,13 @@ class AttributeStruct
|
|
5
5
|
class AttributeHash < ::Hash
|
6
6
|
include ::Hashie::Extensions::DeepMerge
|
7
7
|
include ::Hashie::Extensions::IndifferentAccess
|
8
|
+
|
9
|
+
def to_hash
|
10
|
+
::Hash[
|
11
|
+
self.map do |k,v|
|
12
|
+
[k, v.is_a?(::Hash) ? v.to_hash : v]
|
13
|
+
end
|
14
|
+
]
|
15
|
+
end
|
8
16
|
end
|
9
17
|
end
|
@@ -2,13 +2,15 @@ class AttributeStruct < BasicObject
|
|
2
2
|
|
3
3
|
class << self
|
4
4
|
|
5
|
-
#
|
5
|
+
# @return [Truthy, Falsey] global flag for camel keys
|
6
6
|
attr_reader :camel_keys
|
7
|
-
#
|
7
|
+
# @return [Truthy, Falsey] force chef tooling (Mash)
|
8
8
|
attr_accessor :force_chef
|
9
9
|
|
10
|
-
# val:: bool
|
11
10
|
# Automatically converts keys to camel case
|
11
|
+
#
|
12
|
+
# @param val [TrueClass, FalseClass]
|
13
|
+
# @return [TrueClass, FalseClass]
|
12
14
|
def camel_keys=(val)
|
13
15
|
load_the_camels if val
|
14
16
|
@camel_keys = !!val
|
@@ -22,7 +24,7 @@ class AttributeStruct < BasicObject
|
|
22
24
|
end
|
23
25
|
end
|
24
26
|
|
25
|
-
#
|
27
|
+
# Determine what hash library to load based on availability
|
26
28
|
def load_the_hash
|
27
29
|
unless(@hash_loaded)
|
28
30
|
if(defined?(Chef) || force_chef)
|
@@ -36,47 +38,97 @@ class AttributeStruct < BasicObject
|
|
36
38
|
end
|
37
39
|
end
|
38
40
|
|
41
|
+
# @return [AttributeStruct::AttributeHash, Mash]
|
39
42
|
def hashish
|
40
43
|
load_the_hash
|
41
44
|
@hash_loaded == :chef ? ::Mash : ::AttributeStruct::AttributeHash
|
42
45
|
end
|
43
46
|
|
47
|
+
# Create AttributeStruct instance and dump the resulting hash
|
48
|
+
def build(&block)
|
49
|
+
raise ArgumentError.new 'Block required for build!' unless block
|
50
|
+
new(&block)._dump
|
51
|
+
end
|
52
|
+
|
44
53
|
end
|
45
54
|
|
46
|
-
#
|
55
|
+
# @return [Truthy, Falsey] current camelizing setting
|
47
56
|
attr_reader :_camel_keys
|
48
|
-
|
49
|
-
|
57
|
+
# @return [AtributeStruct::AttributeHash, Mash] holding space for state
|
58
|
+
attr_reader :_arg_state
|
59
|
+
|
60
|
+
# Create new instance
|
61
|
+
#
|
62
|
+
# @param init_hash [Hash] hash to initialize struct
|
63
|
+
# @yield block to execute within struct context
|
64
|
+
def initialize(init_hash=nil, &block)
|
50
65
|
_klass.load_the_hash
|
51
66
|
@_camel_keys = _klass.camel_keys
|
67
|
+
@_arg_state = self.class.hashish.new
|
52
68
|
@table = __hashish.new
|
53
|
-
|
54
|
-
|
55
|
-
_load(args.first)
|
56
|
-
end
|
69
|
+
if(init_hash)
|
70
|
+
_load(init_hash)
|
57
71
|
end
|
58
72
|
if(block)
|
59
73
|
self.instance_exec(&block)
|
60
74
|
end
|
61
75
|
end
|
62
76
|
|
63
|
-
#
|
64
|
-
#
|
77
|
+
# Execute block within current context
|
78
|
+
#
|
79
|
+
# @yield block to execute
|
80
|
+
# @return [Object]
|
81
|
+
def _build(&block)
|
82
|
+
self.instance_exec(&block)
|
83
|
+
end
|
84
|
+
|
85
|
+
# Set state into current context
|
86
|
+
#
|
87
|
+
# @param args [Hashish] hashish type holding data for context
|
88
|
+
# @return [Hashish]
|
89
|
+
def _set_state(args={})
|
90
|
+
_arg_state.merge!(args)
|
91
|
+
end
|
92
|
+
|
93
|
+
# Value of requested state
|
94
|
+
#
|
95
|
+
# @param key [Symbol, String]
|
96
|
+
# @param traverse [TrueClass, FalseClass] traverse towards root for matching key
|
97
|
+
# @return [Object, NilClass]
|
98
|
+
def _state(key, traverse=true)
|
99
|
+
if(_arg_state.keys.include?(key))
|
100
|
+
_arg_state[key]
|
101
|
+
else
|
102
|
+
if(traverse && _parent)
|
103
|
+
_parent._state(key)
|
104
|
+
end
|
105
|
+
end
|
106
|
+
end
|
107
|
+
|
108
|
+
# Enable/disable camel keys
|
109
|
+
#
|
110
|
+
# @param val [TrueClass, FalseClass]
|
111
|
+
# @return [TrueClass, FalseClass]
|
65
112
|
def _camel_keys=(val)
|
66
113
|
_klass.load_the_camels if val
|
67
114
|
@_camel_keys = !!val
|
68
115
|
end
|
69
116
|
|
70
|
-
#
|
71
|
-
#
|
117
|
+
# Direct data access
|
118
|
+
#
|
119
|
+
# @param key [String, Symbol]
|
120
|
+
# @return [Object]
|
72
121
|
def [](key)
|
73
122
|
_data[_process_key(key)]
|
74
123
|
end
|
75
124
|
|
76
|
-
# key
|
77
|
-
#
|
78
|
-
#
|
79
|
-
#
|
125
|
+
# Directly set value into struct. Useful when the key
|
126
|
+
# is not valid ruby syntax for a method
|
127
|
+
#
|
128
|
+
# @param key [String, Symbol]
|
129
|
+
# @param val [Object]
|
130
|
+
# @yield block to execute within context
|
131
|
+
# @return [Object]
|
80
132
|
def _set(key, val=nil, &block)
|
81
133
|
if(val)
|
82
134
|
self.method_missing(key, val, &block)
|
@@ -84,42 +136,73 @@ class AttributeStruct < BasicObject
|
|
84
136
|
self.method_missing(key, &block)
|
85
137
|
end
|
86
138
|
end
|
87
|
-
|
88
|
-
|
139
|
+
alias_method :set!, :_set
|
140
|
+
|
141
|
+
# Provides struct DSL behavior
|
142
|
+
#
|
143
|
+
# @param sym [Symbol, String] method name
|
144
|
+
# @param args [Object] argument list
|
145
|
+
# @yield provided block
|
146
|
+
# @return [Object] existing value or newly set value
|
147
|
+
# @note Dragons and unicorns all over in here
|
89
148
|
def method_missing(sym, *args, &block)
|
90
149
|
if((s = sym.to_s).end_with?('='))
|
91
150
|
s.slice!(-1, s.length)
|
92
151
|
sym = s
|
93
152
|
end
|
94
153
|
sym = _process_key(sym)
|
95
|
-
@table[sym] ||= _klass_new
|
96
154
|
if(!args.empty? || block)
|
97
155
|
if(args.empty? && block)
|
98
|
-
|
156
|
+
if(_state(:value_collapse))
|
157
|
+
orig = @table.fetch(sym, :__unset__)
|
158
|
+
end
|
159
|
+
base = _klass_new
|
99
160
|
if(block.arity == 0)
|
100
161
|
base.instance_exec(&block)
|
101
162
|
else
|
102
163
|
base.instance_exec(base, &block)
|
103
164
|
end
|
104
|
-
|
165
|
+
if(orig.is_a?(::NilClass))
|
166
|
+
@table[sym] = base
|
167
|
+
else
|
168
|
+
if(orig == :__unset__)
|
169
|
+
@table[sym] = base
|
170
|
+
else
|
171
|
+
orig = [orig] unless orig.is_a?(::Array)
|
172
|
+
orig << base
|
173
|
+
@table[sym] = orig
|
174
|
+
end
|
175
|
+
end
|
105
176
|
elsif(!args.empty? && block)
|
106
177
|
base = @table[sym]
|
107
178
|
base = _klass_new unless base.is_a?(_klass)
|
108
|
-
@table[sym] = base
|
109
179
|
leaf = base
|
180
|
+
key = sym
|
110
181
|
args.each do |arg|
|
111
182
|
leaf = base[arg]
|
183
|
+
key = arg
|
112
184
|
unless(leaf.is_a?(_klass))
|
113
185
|
leaf = _klass_new
|
114
186
|
base._set(arg, leaf)
|
115
187
|
base = leaf
|
116
188
|
end
|
117
189
|
end
|
190
|
+
if(!leaf.nil? && _state(:value_collapse))
|
191
|
+
orig = leaf
|
192
|
+
leaf = orig.parent._klass_new
|
193
|
+
end
|
118
194
|
if(block.arity == 0)
|
119
195
|
leaf.instance_exec(&block)
|
120
196
|
else
|
121
197
|
leaf.instance_exec(leaf, &block)
|
122
198
|
end
|
199
|
+
if(orig)
|
200
|
+
orig = [orig] unless orig.is_a?(::Array)
|
201
|
+
orig << leaf
|
202
|
+
else
|
203
|
+
orig = leaf
|
204
|
+
end
|
205
|
+
@table[sym] = orig
|
123
206
|
else
|
124
207
|
if(args.size > 1)
|
125
208
|
@table[sym] = _klass_new unless @table[sym].is_a?(_klass)
|
@@ -131,42 +214,54 @@ class AttributeStruct < BasicObject
|
|
131
214
|
end
|
132
215
|
return endpoint # custom break out
|
133
216
|
else
|
134
|
-
@table[sym]
|
217
|
+
if(_state(:value_collapse) && !(leaf = @table[sym]).nil?)
|
218
|
+
leaf = [leaf] unless leaf.is_a?(::Array)
|
219
|
+
leaf << args.first
|
220
|
+
@table[sym] = leaf
|
221
|
+
else
|
222
|
+
@table[sym] = args.first
|
223
|
+
end
|
135
224
|
end
|
136
225
|
end
|
137
226
|
end
|
227
|
+
@table[sym] = _klass_new if @table[sym].nil? && !@table[sym].is_a?(_klass)
|
138
228
|
@table[sym]
|
139
229
|
end
|
140
230
|
|
141
|
-
#
|
231
|
+
# @return [TrueClass, FalseClass] struct is nil (empty data)
|
142
232
|
def nil?
|
143
233
|
_data.empty?
|
144
234
|
end
|
145
235
|
|
146
|
-
#
|
147
|
-
#
|
236
|
+
# Determine if self is a class
|
237
|
+
#
|
238
|
+
# @param klass [Class]
|
239
|
+
# @return [TrueClass, FalseClass]
|
148
240
|
def is_a?(klass)
|
149
241
|
klass.ancestors.include?(_klass)
|
150
242
|
end
|
151
243
|
alias_method :kind_of?, :is_a?
|
152
244
|
|
153
|
-
#
|
245
|
+
# @return [Array<String,Symbol>] keys within struct
|
154
246
|
def _keys
|
155
247
|
_data.keys
|
156
248
|
end
|
157
249
|
|
158
|
-
#
|
250
|
+
# @return [AttributeStruct::AttributeHash, Mash] underlying struct data
|
159
251
|
def _data
|
160
252
|
@table
|
161
253
|
end
|
162
254
|
|
163
|
-
#
|
164
|
-
#
|
255
|
+
# Delete entry from struct
|
256
|
+
#
|
257
|
+
# @param key [String, Symbol]
|
258
|
+
# @return [Object] value of entry
|
165
259
|
def _delete(key)
|
166
260
|
_data.delete(_process_key(key))
|
167
261
|
end
|
262
|
+
alias_method :delete!, :_delete
|
168
263
|
|
169
|
-
#
|
264
|
+
# @return [AttributeStruct::AttributeHash, Mash] dump struct to hashish
|
170
265
|
def _dump
|
171
266
|
processed = @table.map do |key, value|
|
172
267
|
if(value.is_a?(::Enumerable))
|
@@ -183,9 +278,12 @@ class AttributeStruct < BasicObject
|
|
183
278
|
end
|
184
279
|
__hashish[*processed.flatten(1)]
|
185
280
|
end
|
281
|
+
alias_method :dump!, :_dump
|
186
282
|
|
187
|
-
#
|
188
|
-
#
|
283
|
+
# Clear current struct data and replace
|
284
|
+
#
|
285
|
+
# @param hashish [Hash] hashish type instance
|
286
|
+
# @return [self]
|
189
287
|
def _load(hashish)
|
190
288
|
@table.clear
|
191
289
|
if(_root._camel_keys_action == :auto_discovery)
|
@@ -213,11 +311,13 @@ class AttributeStruct < BasicObject
|
|
213
311
|
self
|
214
312
|
end
|
215
313
|
|
216
|
-
#
|
217
|
-
#
|
218
|
-
|
314
|
+
# Perform deep merge
|
315
|
+
#
|
316
|
+
# @param overlay [AttributeStruct]
|
317
|
+
# @return [AttributeStruct] newly merged instance
|
318
|
+
def _merge(overlay)
|
219
319
|
source = _deep_copy
|
220
|
-
dest =
|
320
|
+
dest = overlay._deep_copy
|
221
321
|
if(defined?(::Chef))
|
222
322
|
result = ::Chef::Mixin::DeepMerge.merge(source, dest)
|
223
323
|
else
|
@@ -226,21 +326,26 @@ class AttributeStruct < BasicObject
|
|
226
326
|
_klass.new(result)
|
227
327
|
end
|
228
328
|
|
229
|
-
#
|
230
|
-
#
|
231
|
-
#
|
232
|
-
|
233
|
-
|
329
|
+
# Perform deep merge in place
|
330
|
+
#
|
331
|
+
# @param overlay [AttributeStruct]
|
332
|
+
# @return [self]
|
333
|
+
def _merge!(overlay)
|
334
|
+
result = _merge(overlay)._dump
|
234
335
|
_load(result)
|
235
336
|
self
|
236
337
|
end
|
237
338
|
|
238
|
-
#
|
339
|
+
# @return [Class] hashish type available
|
239
340
|
def __hashish
|
240
341
|
defined?(::Chef) ? ::Mash : ::AttributeStruct::AttributeHash
|
241
342
|
end
|
242
343
|
|
243
|
-
#
|
344
|
+
# Provide dup of instance
|
345
|
+
#
|
346
|
+
# @param v [Object]
|
347
|
+
# @return [Object] duped instance
|
348
|
+
# @note if Symbol provided, String is returned
|
244
349
|
def _do_dup(v)
|
245
350
|
begin
|
246
351
|
v.dup
|
@@ -249,8 +354,10 @@ class AttributeStruct < BasicObject
|
|
249
354
|
end
|
250
355
|
end
|
251
356
|
|
252
|
-
#
|
253
|
-
#
|
357
|
+
# Create a "deep" copy
|
358
|
+
#
|
359
|
+
# @param thing [Object] struct to copy. defaults to self
|
360
|
+
# @return [Object] new instance
|
254
361
|
def _deep_copy(thing=nil)
|
255
362
|
thing ||= _dump
|
256
363
|
if(thing.is_a?(::Enumerable))
|
@@ -264,8 +371,11 @@ class AttributeStruct < BasicObject
|
|
264
371
|
val
|
265
372
|
end
|
266
373
|
|
267
|
-
# key
|
268
|
-
#
|
374
|
+
# Provide expected key format based on context
|
375
|
+
#
|
376
|
+
# @param key [String, Symbol]
|
377
|
+
# @param args [Object] argument list (:force will force processing)
|
378
|
+
# @return [String, Symbol]
|
269
379
|
def _process_key(key, *args)
|
270
380
|
key = key.to_s
|
271
381
|
if(_camel_keys && _camel_keys_action)
|
@@ -288,14 +398,16 @@ class AttributeStruct < BasicObject
|
|
288
398
|
key
|
289
399
|
end
|
290
400
|
end
|
401
|
+
alias_method :process_key!, :_process_key
|
291
402
|
|
292
|
-
#
|
403
|
+
# @return [Class] this class
|
293
404
|
def _klass
|
294
405
|
::AttributeStruct
|
295
406
|
end
|
296
407
|
alias_method :class, :_klass
|
297
408
|
|
298
|
-
#
|
409
|
+
# @return [AttributeStruct] new struct instance
|
410
|
+
# @note will set self as parent and propogate camelizing status
|
299
411
|
def _klass_new
|
300
412
|
n = _klass.new
|
301
413
|
unless(_camel_keys_action == :auto_discovery)
|
@@ -306,22 +418,26 @@ class AttributeStruct < BasicObject
|
|
306
418
|
n
|
307
419
|
end
|
308
420
|
|
309
|
-
#
|
310
|
-
#
|
421
|
+
# Set custom rule for processed keys at this context level
|
422
|
+
#
|
423
|
+
# @param v [Symbol] :auto_disable or :auto_enable
|
424
|
+
# @return [Symbol]
|
311
425
|
def _camel_keys_set(v)
|
312
426
|
@_camel_keys_set = v
|
313
427
|
end
|
314
428
|
|
315
|
-
#
|
429
|
+
# @return [Symbol, NilClass] :auto_disable or :auto_enable
|
316
430
|
def _camel_keys_action
|
317
431
|
@_camel_keys_set
|
318
432
|
end
|
319
433
|
|
434
|
+
# @return [AttributeStruct, NilClass] parent of this struct
|
320
435
|
def _parent(obj=nil)
|
321
436
|
@_parent = obj if obj
|
322
437
|
@_parent
|
323
438
|
end
|
324
439
|
|
440
|
+
# @return [AttributeStruct, NilClass] root of the struct or nil if self is root
|
325
441
|
def _root
|
326
442
|
r = self
|
327
443
|
until(r._parent.nil?)
|
@@ -330,10 +446,10 @@ class AttributeStruct < BasicObject
|
|
330
446
|
r
|
331
447
|
end
|
332
448
|
|
333
|
-
#
|
334
|
-
#
|
335
|
-
#
|
336
|
-
#
|
449
|
+
# Create an Array and evaluate discovered AttributeStructs
|
450
|
+
#
|
451
|
+
# @param args [Object] array contents
|
452
|
+
# @return [Array]
|
337
453
|
def _array(*args)
|
338
454
|
args.map do |maybe_block|
|
339
455
|
if(maybe_block.is_a?(::Proc))
|
@@ -349,5 +465,6 @@ class AttributeStruct < BasicObject
|
|
349
465
|
end
|
350
466
|
end
|
351
467
|
end
|
468
|
+
alias_method :array!, :_array
|
352
469
|
|
353
470
|
end
|
@@ -5,7 +5,7 @@ module MonkeyCamels
|
|
5
5
|
klass.class_eval do
|
6
6
|
|
7
7
|
include Humps
|
8
|
-
|
8
|
+
|
9
9
|
alias_method :un_camel_to_s, :to_s
|
10
10
|
alias_method :to_s, :camel_to_s
|
11
11
|
alias_method :un_camel_initialize_copy, :initialize_copy
|
@@ -14,27 +14,36 @@ module MonkeyCamels
|
|
14
14
|
end
|
15
15
|
end
|
16
16
|
|
17
|
+
# Create a camel copy based on settings
|
18
|
+
#
|
19
|
+
# @return [String]
|
17
20
|
def camel_initialize_copy(orig)
|
18
21
|
new_val = un_camel_initialize_copy(orig)
|
19
22
|
orig._camel? ? new_val : new_val._no_hump
|
20
23
|
end
|
21
|
-
|
24
|
+
|
25
|
+
# Provide string formatted based on hump setting
|
26
|
+
#
|
27
|
+
# @return [String]
|
22
28
|
def camel_to_s
|
23
29
|
val = un_camel_to_s
|
24
30
|
_camel? ? val : val._no_hump
|
25
31
|
end
|
26
32
|
|
27
33
|
module Humps
|
28
|
-
|
34
|
+
|
35
|
+
# @return [TrueClass, FalseClass] camelized
|
29
36
|
def _camel?
|
30
37
|
!@__not_camel
|
31
38
|
end
|
32
39
|
|
40
|
+
# @return [self] disable camelizing
|
33
41
|
def _no_hump
|
34
42
|
@__not_camel = true
|
35
43
|
self
|
36
44
|
end
|
37
45
|
|
46
|
+
# @return [self] enable camelizing
|
38
47
|
def _hump
|
39
48
|
@__not_camel = false
|
40
49
|
self
|
@@ -48,7 +57,7 @@ end
|
|
48
57
|
String.send(:include, MonkeyCamels)
|
49
58
|
Symbol.send(:include, MonkeyCamels)
|
50
59
|
|
51
|
-
# Specialized type
|
60
|
+
# Specialized String type
|
52
61
|
class CamelString < String
|
53
62
|
def initialize(val=nil)
|
54
63
|
super
|
@@ -0,0 +1,80 @@
|
|
1
|
+
require 'minitest/autorun'
|
2
|
+
|
3
|
+
describe AttributeStruct do
|
4
|
+
describe 'Collapse' do
|
5
|
+
describe 'direct value set' do
|
6
|
+
|
7
|
+
describe 'When values are not collapsed' do
|
8
|
+
before do
|
9
|
+
@struct = AttributeStruct.new
|
10
|
+
@struct.direct.assignment 1
|
11
|
+
@struct.direct.assignment 2
|
12
|
+
@dump = @struct._dump
|
13
|
+
end
|
14
|
+
|
15
|
+
it 'should return last set value' do
|
16
|
+
@dump['direct']['assignment'].must_equal 2
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
describe 'When values are collapsed' do
|
21
|
+
before do
|
22
|
+
@struct = AttributeStruct.new
|
23
|
+
@struct._set_state(:value_collapse => true)
|
24
|
+
@struct.direct.assignment 1
|
25
|
+
@struct.direct.assignment 2
|
26
|
+
@dump = @struct._dump
|
27
|
+
end
|
28
|
+
|
29
|
+
it 'should return both assigned values as an array' do
|
30
|
+
@dump['direct']['assignment'].must_equal [1,2]
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
end
|
35
|
+
|
36
|
+
describe 'block value set' do
|
37
|
+
|
38
|
+
describe 'When values are not collapsed' do
|
39
|
+
before do
|
40
|
+
@struct = AttributeStruct.new
|
41
|
+
@struct.direct do
|
42
|
+
assignment true
|
43
|
+
end
|
44
|
+
@struct.direct do
|
45
|
+
assignment false
|
46
|
+
end
|
47
|
+
@dump = @struct._dump
|
48
|
+
end
|
49
|
+
|
50
|
+
it 'should return last set value' do
|
51
|
+
@dump['direct']['assignment'].must_equal false
|
52
|
+
end
|
53
|
+
|
54
|
+
end
|
55
|
+
|
56
|
+
describe 'When values are collapsed' do
|
57
|
+
before do
|
58
|
+
@struct = AttributeStruct.new
|
59
|
+
@struct._set_state(:value_collapse => true)
|
60
|
+
@struct.direct do
|
61
|
+
assignment true
|
62
|
+
end
|
63
|
+
@struct.direct do
|
64
|
+
assignment false
|
65
|
+
end
|
66
|
+
@dump = @struct._dump
|
67
|
+
end
|
68
|
+
|
69
|
+
it 'should return both assigned values as an array' do
|
70
|
+
@dump['direct'].must_equal [
|
71
|
+
{'assignment' => true},
|
72
|
+
{'assignment' => false}
|
73
|
+
]
|
74
|
+
end
|
75
|
+
|
76
|
+
end
|
77
|
+
|
78
|
+
end
|
79
|
+
end
|
80
|
+
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: attribute_struct
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.2.0
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date:
|
12
|
+
date: 2014-05-27 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: hashie
|
@@ -42,13 +42,17 @@ files:
|
|
42
42
|
- test/specs/camel.rb
|
43
43
|
- test/specs/merging.rb
|
44
44
|
- test/specs/basic.rb
|
45
|
+
- test/specs/collapse.rb
|
45
46
|
- Gemfile
|
46
47
|
- README.md
|
48
|
+
- LICENSE
|
47
49
|
- attribute_struct.gemspec
|
48
50
|
- CHANGELOG.md
|
51
|
+
- CONTRIBUTING.md
|
49
52
|
- Gemfile.lock
|
50
53
|
homepage: http://github.com/chrisroberts/attribute_struct
|
51
|
-
licenses:
|
54
|
+
licenses:
|
55
|
+
- Apache 2.0
|
52
56
|
post_install_message:
|
53
57
|
rdoc_options: []
|
54
58
|
require_paths:
|