attribute_struct 0.1.8 → 0.2.0
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.
- 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:
|