nugrant 2.1.2 → 2.1.4

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.
Files changed (71) hide show
  1. checksums.yaml +5 -5
  2. data/.gitignore +23 -23
  3. data/.travis.yml +15 -10
  4. data/CHANGELOG.md +347 -338
  5. data/CONTRIBUTORS.md +7 -5
  6. data/Gemfile +13 -13
  7. data/README.md +601 -601
  8. data/lib/nugrant/bag.rb +264 -264
  9. data/lib/nugrant/config.rb +201 -201
  10. data/lib/nugrant/helper/bag.rb +38 -38
  11. data/lib/nugrant/helper/env/exporter.rb +195 -195
  12. data/lib/nugrant/helper/env/namer.rb +47 -47
  13. data/lib/nugrant/helper/parameters.rb +12 -12
  14. data/lib/nugrant/helper/stack.rb +86 -86
  15. data/lib/nugrant/mixin/parameters.rb +178 -178
  16. data/lib/nugrant/parameters.rb +29 -29
  17. data/lib/nugrant/vagrant/errors.rb +35 -35
  18. data/lib/nugrant/vagrant/v2/action/auto_export.rb +45 -45
  19. data/lib/nugrant/vagrant/v2/action.rb +17 -17
  20. data/lib/nugrant/vagrant/v2/command/env.rb +118 -118
  21. data/lib/nugrant/vagrant/v2/command/parameters.rb +153 -153
  22. data/lib/nugrant/vagrant/v2/command/restricted_keys.rb +64 -64
  23. data/lib/nugrant/vagrant/v2/command/root.rb +95 -95
  24. data/lib/nugrant/vagrant/v2/config/user.rb +29 -29
  25. data/lib/nugrant/vagrant/v2/helper.rb +96 -96
  26. data/lib/nugrant/vagrant/v2/plugin.rb +34 -34
  27. data/lib/nugrant/version.rb +3 -3
  28. data/lib/nugrant.rb +31 -31
  29. data/locales/en.yml +24 -24
  30. data/locales/fr.yml +24 -24
  31. data/nugrant.gemspec +32 -32
  32. data/test/lib/nugrant/helper/env/test_exporter.rb +238 -238
  33. data/test/lib/nugrant/helper/test_bag.rb +16 -16
  34. data/test/lib/nugrant/helper/test_parameters.rb +17 -17
  35. data/test/lib/nugrant/helper/test_stack.rb +152 -152
  36. data/test/lib/nugrant/test_bag.rb +450 -450
  37. data/test/lib/nugrant/test_config.rb +201 -201
  38. data/test/lib/nugrant/test_parameters.rb +438 -438
  39. data/test/lib/test_helper.rb +3 -3
  40. data/test/resources/README.md +52 -52
  41. data/test/resources/json/params_current_1.json +6 -6
  42. data/test/resources/json/params_current_2.json +29 -29
  43. data/test/resources/json/params_user_nil_values.json +9 -9
  44. data/test/resources/vagrantfiles/v2.auto_export +13 -13
  45. data/test/resources/vagrantfiles/v2.bag_inside_array +15 -15
  46. data/test/resources/vagrantfiles/v2.defaults_mixed_string_symbols +18 -18
  47. data/test/resources/vagrantfiles/v2.defaults_null_values_in_vagrantuser +23 -23
  48. data/test/resources/vagrantfiles/v2.defaults_using_string +18 -18
  49. data/test/resources/vagrantfiles/v2.defaults_using_symbol +18 -18
  50. data/test/resources/vagrantfiles/v2.empty +2 -2
  51. data/test/resources/vagrantfiles/v2.fake +29 -29
  52. data/test/resources/vagrantfiles/v2.missing_parameter +3 -3
  53. data/test/resources/vagrantfiles/v2.real +22 -22
  54. data/test/resources/yaml/params_array.yml +5 -5
  55. data/test/resources/yaml/params_boolean.yml +1 -1
  56. data/test/resources/yaml/params_combinations.yml +72 -72
  57. data/test/resources/yaml/params_current_1.yml +4 -4
  58. data/test/resources/yaml/params_current_2.yml +23 -23
  59. data/test/resources/yaml/params_defaults_at_root.yml +1 -1
  60. data/test/resources/yaml/params_defaults_not_at_root.yml +2 -2
  61. data/test/resources/yaml/params_list.yml +2 -2
  62. data/test/resources/yaml/params_numeric_key.yml +3 -3
  63. data/test/resources/yaml/params_simple.yml +1 -1
  64. data/test/resources/yaml/params_system_1.yml +4 -4
  65. data/test/resources/yaml/params_system_2.yml +25 -25
  66. data/test/resources/yaml/params_unix_eol.yml +3 -3
  67. data/test/resources/yaml/params_user_1.yml +4 -4
  68. data/test/resources/yaml/params_user_2.yml +23 -23
  69. data/test/resources/yaml/params_user_nil_values.yml +5 -5
  70. data/test/resources/yaml/params_windows_eol.yml +3 -3
  71. metadata +12 -13
@@ -1,450 +1,450 @@
1
- require 'minitest/autorun'
2
-
3
- require 'nugrant/bag'
4
- require 'nugrant/helper/bag'
5
-
6
- module Nugrant
7
- class TestBag < ::Minitest::Test
8
- def run_test_bag(parameters)
9
- bag = create_bag(parameters)
10
-
11
- assert_bag_equal(parameters, bag)
12
- end
13
-
14
- def test_bag()
15
- run_test_bag({:first => "value1", :second => "value2"})
16
-
17
- run_test_bag({
18
- :first => {
19
- :level1 => "value1",
20
- :level2 => "value2",
21
- },
22
- :second => {
23
- :level1 => "value3",
24
- :level2 => "value4",
25
- },
26
- :third => "value5"
27
- })
28
-
29
- run_test_bag({
30
- :first => {
31
- :level1 => {
32
- :level11 => "value1",
33
- :level12 => "value2",
34
- },
35
- :level2 => {
36
- :level21 => "value3",
37
- :level22 => "value4",
38
- },
39
- :level3 => "value5",
40
- },
41
- :second => {
42
- :level1 => {
43
- :level11 => "value6",
44
- :level12 => "value7",
45
- },
46
- :level2 => {
47
- :level21 => "value8",
48
- :level22 => "value9",
49
- },
50
- :level3 => "value10",
51
- },
52
- :third => "value11"
53
- })
54
- end
55
-
56
- def test_undefined_value()
57
- bag = create_bag({:value => "one"})
58
-
59
- assert_raises(KeyError) do
60
- bag.invalid_value
61
- end
62
-
63
- assert_raises(KeyError) do
64
- bag["invalid_value"]
65
- end
66
-
67
- assert_raises(KeyError) do
68
- bag[:invalid_value]
69
- end
70
- end
71
-
72
- def test_to_hash()
73
- hash = create_bag({}).to_hash()
74
-
75
- assert_is_hash_exclusive(hash)
76
- assert_equal({}, hash)
77
-
78
- hash = create_bag({"value" => {:one => "value", "two" => "value"}}).to_hash()
79
-
80
- assert_is_hash_exclusive(hash)
81
- assert_is_hash_exclusive(hash[:value])
82
- assert_kind_of(String, hash[:value][:one])
83
- assert_kind_of(String, hash[:value][:two])
84
- assert_equal({:value => {:one => "value", :two => "value"}}, hash)
85
- end
86
-
87
- def test_to_hash_array_with_bag()
88
- hash = create_bag({:a => [{:b => "1", :c => [{"d" => "2"}]}]}).to_hash()
89
-
90
- assert_is_hash_exclusive(hash)
91
- assert_kind_of(Array, hash[:a])
92
- assert_is_hash_exclusive(hash[:a][0])
93
- assert_kind_of(String, hash[:a][0][:b])
94
- assert_kind_of(Array, hash[:a][0][:c])
95
- assert_is_hash_exclusive(hash[:a][0][:c][0])
96
- assert_kind_of(String, hash[:a][0][:c][0][:d])
97
-
98
- assert_equal({:a => [{:b => "1", :c => [{:d => "2"}]}]}, hash)
99
- end
100
-
101
- def test_to_hash_array_with_bag_string_key()
102
- hash = create_bag({:a => [{:b => "1", :c => [{"d" => "2"}]}]}).to_hash(use_string_key: true)
103
-
104
- assert_is_hash_exclusive(hash)
105
- assert_kind_of(Array, hash["a"])
106
- assert_is_hash_exclusive(hash["a"][0])
107
- assert_kind_of(String, hash["a"][0]["b"])
108
- assert_kind_of(Array, hash["a"][0]["c"])
109
- assert_is_hash_exclusive(hash["a"][0]["c"][0])
110
- assert_kind_of(String, hash["a"][0]["c"][0]["d"])
111
-
112
- assert_equal({"a" => [{"b" => "1", "c" => [{"d" => "2"}]}]}, hash)
113
- end
114
-
115
- def test_merge_array_replace()
116
- # Replace should be the default case
117
- bag1 = create_bag({"first" => [1, 2]})
118
- bag2 = create_bag({:first => [2, 3]})
119
-
120
- bag1.merge!(bag2);
121
-
122
- assert_equal({:first => [2, 3]}, bag1.to_hash())
123
-
124
- bag1 = create_bag({"first" => [1, 2]})
125
- bag2 = create_bag({:first => "string"})
126
-
127
- bag1.merge!(bag2);
128
-
129
- assert_equal({:first => "string"}, bag1.to_hash())
130
- end
131
-
132
- def test_merge_array_extend()
133
- bag1 = create_bag({"first" => [1, 2]}, :array_merge_strategy => :extend)
134
- bag2 = create_bag({:first => [2, 3]})
135
-
136
- bag1.merge!(bag2);
137
-
138
- assert_equal({:first => [1, 2, 3]}, bag1.to_hash())
139
-
140
- bag1 = create_bag({"first" => [1, 2]}, :array_merge_strategy => :extend)
141
- bag2 = create_bag({:first => "string"})
142
-
143
- bag1.merge!(bag2);
144
-
145
- assert_equal({:first => "string"}, bag1.to_hash())
146
- end
147
-
148
- def test_merge_array_concat()
149
- bag1 = create_bag({"first" => [1, 2]}, :array_merge_strategy => :concat)
150
- bag2 = create_bag({:first => [2, 3]})
151
-
152
- bag1.merge!(bag2);
153
-
154
- assert_equal({:first => [2, 3, 1, 2]}, bag1.to_hash())
155
-
156
- bag1 = create_bag({"first" => [1, 2]}, :array_merge_strategy => :concat)
157
- bag2 = create_bag({:first => "string"})
158
-
159
- bag1.merge!(bag2);
160
-
161
- assert_equal({:first => "string"}, bag1.to_hash())
162
- end
163
-
164
- def test_merge_hash_keeps_indifferent_access
165
- bag1 = create_bag({"first" => {:second => [1, 2]}})
166
- bag1.merge!({:third => "three", "first" => {:second => [3, 4]}})
167
-
168
- assert_equal({:first => {:second => [3, 4]}, :third => "three"}, bag1.to_hash())
169
-
170
- assert_indifferent_access_equal({:second => [3, 4]}, bag1, :first)
171
- assert_indifferent_access_equal([3, 4], bag1["first"], :second)
172
- end
173
-
174
- def test_set_a_slot_with_a_hash_keeps_indifferent_access
175
- bag1 = create_bag({})
176
- bag1["first"] = {:second => [1, 2]}
177
-
178
- assert_indifferent_access_equal({:second => [1, 2]}, bag1, :first)
179
- assert_indifferent_access_equal([1, 2], bag1["first"], :second)
180
- end
181
-
182
- def test_nil_key()
183
- assert_raises(ArgumentError) do
184
- create_bag({nil => "value"})
185
- end
186
-
187
- parameters = create_bag({})
188
-
189
- assert_raises(ArgumentError) do
190
- parameters[nil] = 1
191
- end
192
-
193
- assert_raises(ArgumentError) do
194
- parameters[nil]
195
- end
196
-
197
- assert_raises(ArgumentError) do
198
- parameters.method_missing(nil)
199
- end
200
- end
201
-
202
- def test_restricted_keys_are_still_accessible
203
- keys = Helper::Bag.restricted_keys()
204
- bag = create_bag(Hash[
205
- keys.map do |key|
206
- [key, "#{key.to_s} - value"]
207
- end
208
- ])
209
-
210
- keys.each do |key|
211
- assert_equal("#{key.to_s} - value", bag[key.to_s], "bag[#{key.to_s}]")
212
- assert_equal("#{key.to_s} - value", bag[key.to_sym], "bag[#{key.to_sym}]")
213
- end
214
- end
215
-
216
- def test_numeric_keys_converted_to_string
217
- bag1 = create_bag({1 => "value1"})
218
-
219
- assert_indifferent_access_equal("value1", bag1, :'1')
220
- end
221
-
222
- def test_custom_key_error_handler
223
- bag = create_bag({:value => "one"}, :key_error => Proc.new do |key|
224
- raise IndexError
225
- end)
226
-
227
- assert_raises(IndexError) do
228
- bag.invalid_value
229
- end
230
-
231
- assert_raises(IndexError) do
232
- bag["invalid_value"]
233
- end
234
-
235
- assert_raises(IndexError) do
236
- bag[:invalid_value]
237
- end
238
- end
239
-
240
- def test_custom_key_error_handler_returns_value
241
- bag = create_bag({:value => "one"}, :key_error => Proc.new do |key|
242
- "Some value"
243
- end)
244
-
245
- assert_indifferent_access_equal("Some value", bag, :invalid_value)
246
- end
247
-
248
- def test_walk_bag
249
- bag = create_bag({
250
- :first => {
251
- :level1 => "value1",
252
- :level2 => "value2",
253
- },
254
- :second => {
255
- :level1 => "value3",
256
- :level2 => "value4",
257
- },
258
- :third => "value5"
259
- })
260
-
261
- lines = []
262
- bag.walk do |path, key, value|
263
- lines << "Path (#{path}), Key (#{key}), Value (#{value})"
264
- end
265
-
266
- assert_equal([
267
- "Path ([:first, :level1]), Key (level1), Value (value1)",
268
- "Path ([:first, :level2]), Key (level2), Value (value2)",
269
- "Path ([:second, :level1]), Key (level1), Value (value3)",
270
- "Path ([:second, :level2]), Key (level2), Value (value4)",
271
- "Path ([:third]), Key (third), Value (value5)",
272
- ], lines)
273
- end
274
-
275
- def test_merge
276
- bag1 = create_bag({
277
- :first => {
278
- :level1 => "value1",
279
- :level2 => "value2",
280
- },
281
- :second => {
282
- :level1 => "value3",
283
- :level2 => "value4",
284
- },
285
- :third => "value5"
286
- })
287
-
288
- bag2 = create_bag({
289
- :first => {
290
- :level2 => "overriden2",
291
- },
292
- :second => {
293
- :level1 => "value3",
294
- :level2 => "value4",
295
- },
296
- :third => "overriden5"
297
- })
298
-
299
- bag3 = bag1.merge(bag2)
300
-
301
- refute_same(bag1, bag3)
302
- refute_same(bag2, bag3)
303
-
304
- assert_equal(Nugrant::Bag, bag3.class)
305
-
306
- assert_indifferent_access_equal("value1", bag3['first'], :level1)
307
- assert_indifferent_access_equal("overriden2", bag3['first'], :level2)
308
- assert_indifferent_access_equal("value3", bag3['second'], :level1)
309
- assert_indifferent_access_equal("value4", bag3['second'], :level2)
310
- assert_indifferent_access_equal("overriden5", bag3, :third)
311
- end
312
-
313
- def test_merge!
314
- bag1 = create_bag({
315
- :first => {
316
- :level1 => "value1",
317
- :level2 => "value2",
318
- },
319
- :second => {
320
- :level1 => "value3",
321
- :level2 => "value4",
322
- },
323
- :third => "value5"
324
- })
325
-
326
- bag2 = create_bag({
327
- :first => {
328
- :level2 => "overriden2",
329
- },
330
- :second => {
331
- :level1 => "value3",
332
- :level2 => "value4",
333
- },
334
- :third => "overriden5"
335
- })
336
-
337
- bag3 = bag1.merge!(bag2)
338
-
339
- assert_same(bag1, bag3)
340
- refute_same(bag2, bag3)
341
-
342
- assert_equal(Nugrant::Bag, bag3.class)
343
-
344
- assert_indifferent_access_equal("value1", bag3['first'], :level1)
345
- assert_indifferent_access_equal("overriden2", bag3['first'], :level2)
346
- assert_indifferent_access_equal("value3", bag3['second'], :level1)
347
- assert_indifferent_access_equal("value4", bag3['second'], :level2)
348
- assert_indifferent_access_equal("overriden5", bag3, :third)
349
- end
350
-
351
- def test_merge_hash()
352
- bag1 = create_bag({"first" => {:second => [1, 2]}}, :array_merge_strategy => :extend)
353
-
354
- bag1.merge!({"first" => {:second => [2, 3]}});
355
-
356
- assert_equal({:first => {:second => [1, 2, 3]}}, bag1.to_hash())
357
- end
358
-
359
- def test_merge_custom_array_merge_strategy()
360
- bag1 = create_bag({"first" => {:second => [1, 2]}}, :array_merge_strategy => :extend)
361
-
362
- bag1.merge!({"first" => {:second => [2, 3]}}, :array_merge_strategy => :replace);
363
-
364
- assert_equal({:first => {:second => [2, 3]}}, bag1.to_hash())
365
- end
366
-
367
- def test_merge_custom_invalid_array_merge_strategy()
368
- bag1 = create_bag({"first" => {:second => [1, 2]}}, :array_merge_strategy => :extend)
369
- bag2 = bag1.merge({"first" => {:second => [2, 3]}}, :array_merge_strategy => nil);
370
-
371
- assert_equal({:first => {:second => [1, 2, 3]}}, bag2.to_hash())
372
-
373
- bag2 = bag1.merge({"first" => {:second => [2, 3]}}, :array_merge_strategy => :invalid);
374
-
375
- assert_equal({:first => {:second => [1, 2, 3]}}, bag2.to_hash())
376
- end
377
-
378
- def test_change_config
379
- bag1 = create_bag({"first" => [1, 2]}, :array_merge_strategy => :extend)
380
- bag2 = create_bag({:first => [2, 3]})
381
-
382
- bag3 = bag1.merge!(bag2);
383
- bag3.config = {
384
- :array_merge_strategy => :concat
385
- }
386
-
387
- bag3.merge!({"first" => [1, 2, 3]})
388
-
389
- assert_equal([1, 2, 3, 1, 2, 3], bag3['first'])
390
- end
391
-
392
- def test_indifferent_access_in_array
393
- bag = create_bag({:a => [{:b => 1, :c => [{"d" => 1}]}]})
394
-
395
- assert_indifferent_access_equal(1, bag['a'][0]['c'][0], :d)
396
- end
397
-
398
- ## Helpers & Assertions
399
-
400
- def create_bag(elements, options = {})
401
- return Bag.new(elements, options)
402
- end
403
-
404
- def assert_is_hash_exclusive(input)
405
- assert_equal(true, input.kind_of?(Hash), "#{input} should be a kind of Hash")
406
- assert_equal(false, input.kind_of?(Bag), "#{input} should not be a kind of Bag")
407
- end
408
-
409
- def assert_indifferent_access_equal(expected, bag, key)
410
- assert_symbol_access_equal(expected, bag, key)
411
- assert_string_access_equal(expected, bag, key)
412
- end
413
-
414
- def assert_string_access_equal(expected, bag, key)
415
- assert_equal(expected, bag[key.to_s], "bag[#{key.to_s}]")
416
- end
417
-
418
- def assert_symbol_access_equal(expected, bag, key)
419
- assert_equal(expected, bag.method_missing(key.to_sym), "bag.#{key.to_sym}")
420
- assert_equal(expected, bag[key.to_sym], "bag[#{key.to_sym}]")
421
- end
422
-
423
- def assert_indifferent_access_bag_equal(expected, bag, key)
424
- assert_string_access_bag_equal(expected, bag, key)
425
- assert_symbol_access_bag_equal(expected, bag, key)
426
- end
427
-
428
- def assert_string_access_bag_equal(expected, bag, key)
429
- assert_bag_equal(expected, bag[key.to_s])
430
- end
431
-
432
- def assert_symbol_access_bag_equal(expected, bag, key)
433
- assert_bag_equal(expected, bag.method_missing(key.to_sym))
434
- assert_bag_equal(expected, bag[key.to_sym])
435
- end
436
-
437
- def assert_bag_equal(expected, bag)
438
- assert_kind_of(Bag, bag)
439
-
440
- expected.each do |key, expected_value|
441
- if not expected_value.kind_of?(Hash)
442
- assert_indifferent_access_equal(expected_value, bag, key)
443
- next
444
- end
445
-
446
- assert_indifferent_access_bag_equal(expected_value, bag, key)
447
- end
448
- end
449
- end
450
- end
1
+ require 'minitest/autorun'
2
+
3
+ require 'nugrant/bag'
4
+ require 'nugrant/helper/bag'
5
+
6
+ module Nugrant
7
+ class TestBag < ::Minitest::Test
8
+ def run_test_bag(parameters)
9
+ bag = create_bag(parameters)
10
+
11
+ assert_bag_equal(parameters, bag)
12
+ end
13
+
14
+ def test_bag()
15
+ run_test_bag({:first => "value1", :second => "value2"})
16
+
17
+ run_test_bag({
18
+ :first => {
19
+ :level1 => "value1",
20
+ :level2 => "value2",
21
+ },
22
+ :second => {
23
+ :level1 => "value3",
24
+ :level2 => "value4",
25
+ },
26
+ :third => "value5"
27
+ })
28
+
29
+ run_test_bag({
30
+ :first => {
31
+ :level1 => {
32
+ :level11 => "value1",
33
+ :level12 => "value2",
34
+ },
35
+ :level2 => {
36
+ :level21 => "value3",
37
+ :level22 => "value4",
38
+ },
39
+ :level3 => "value5",
40
+ },
41
+ :second => {
42
+ :level1 => {
43
+ :level11 => "value6",
44
+ :level12 => "value7",
45
+ },
46
+ :level2 => {
47
+ :level21 => "value8",
48
+ :level22 => "value9",
49
+ },
50
+ :level3 => "value10",
51
+ },
52
+ :third => "value11"
53
+ })
54
+ end
55
+
56
+ def test_undefined_value()
57
+ bag = create_bag({:value => "one"})
58
+
59
+ assert_raises(KeyError) do
60
+ bag.invalid_value
61
+ end
62
+
63
+ assert_raises(KeyError) do
64
+ bag["invalid_value"]
65
+ end
66
+
67
+ assert_raises(KeyError) do
68
+ bag[:invalid_value]
69
+ end
70
+ end
71
+
72
+ def test_to_hash()
73
+ hash = create_bag({}).to_hash()
74
+
75
+ assert_is_hash_exclusive(hash)
76
+ assert_equal({}, hash)
77
+
78
+ hash = create_bag({"value" => {:one => "value", "two" => "value"}}).to_hash()
79
+
80
+ assert_is_hash_exclusive(hash)
81
+ assert_is_hash_exclusive(hash[:value])
82
+ assert_kind_of(String, hash[:value][:one])
83
+ assert_kind_of(String, hash[:value][:two])
84
+ assert_equal({:value => {:one => "value", :two => "value"}}, hash)
85
+ end
86
+
87
+ def test_to_hash_array_with_bag()
88
+ hash = create_bag({:a => [{:b => "1", :c => [{"d" => "2"}]}]}).to_hash()
89
+
90
+ assert_is_hash_exclusive(hash)
91
+ assert_kind_of(Array, hash[:a])
92
+ assert_is_hash_exclusive(hash[:a][0])
93
+ assert_kind_of(String, hash[:a][0][:b])
94
+ assert_kind_of(Array, hash[:a][0][:c])
95
+ assert_is_hash_exclusive(hash[:a][0][:c][0])
96
+ assert_kind_of(String, hash[:a][0][:c][0][:d])
97
+
98
+ assert_equal({:a => [{:b => "1", :c => [{:d => "2"}]}]}, hash)
99
+ end
100
+
101
+ def test_to_hash_array_with_bag_string_key()
102
+ hash = create_bag({:a => [{:b => "1", :c => [{"d" => "2"}]}]}).to_hash(use_string_key: true)
103
+
104
+ assert_is_hash_exclusive(hash)
105
+ assert_kind_of(Array, hash["a"])
106
+ assert_is_hash_exclusive(hash["a"][0])
107
+ assert_kind_of(String, hash["a"][0]["b"])
108
+ assert_kind_of(Array, hash["a"][0]["c"])
109
+ assert_is_hash_exclusive(hash["a"][0]["c"][0])
110
+ assert_kind_of(String, hash["a"][0]["c"][0]["d"])
111
+
112
+ assert_equal({"a" => [{"b" => "1", "c" => [{"d" => "2"}]}]}, hash)
113
+ end
114
+
115
+ def test_merge_array_replace()
116
+ # Replace should be the default case
117
+ bag1 = create_bag({"first" => [1, 2]})
118
+ bag2 = create_bag({:first => [2, 3]})
119
+
120
+ bag1.merge!(bag2);
121
+
122
+ assert_equal({:first => [2, 3]}, bag1.to_hash())
123
+
124
+ bag1 = create_bag({"first" => [1, 2]})
125
+ bag2 = create_bag({:first => "string"})
126
+
127
+ bag1.merge!(bag2);
128
+
129
+ assert_equal({:first => "string"}, bag1.to_hash())
130
+ end
131
+
132
+ def test_merge_array_extend()
133
+ bag1 = create_bag({"first" => [1, 2]}, :array_merge_strategy => :extend)
134
+ bag2 = create_bag({:first => [2, 3]})
135
+
136
+ bag1.merge!(bag2);
137
+
138
+ assert_equal({:first => [1, 2, 3]}, bag1.to_hash())
139
+
140
+ bag1 = create_bag({"first" => [1, 2]}, :array_merge_strategy => :extend)
141
+ bag2 = create_bag({:first => "string"})
142
+
143
+ bag1.merge!(bag2);
144
+
145
+ assert_equal({:first => "string"}, bag1.to_hash())
146
+ end
147
+
148
+ def test_merge_array_concat()
149
+ bag1 = create_bag({"first" => [1, 2]}, :array_merge_strategy => :concat)
150
+ bag2 = create_bag({:first => [2, 3]})
151
+
152
+ bag1.merge!(bag2);
153
+
154
+ assert_equal({:first => [2, 3, 1, 2]}, bag1.to_hash())
155
+
156
+ bag1 = create_bag({"first" => [1, 2]}, :array_merge_strategy => :concat)
157
+ bag2 = create_bag({:first => "string"})
158
+
159
+ bag1.merge!(bag2);
160
+
161
+ assert_equal({:first => "string"}, bag1.to_hash())
162
+ end
163
+
164
+ def test_merge_hash_keeps_indifferent_access
165
+ bag1 = create_bag({"first" => {:second => [1, 2]}})
166
+ bag1.merge!({:third => "three", "first" => {:second => [3, 4]}})
167
+
168
+ assert_equal({:first => {:second => [3, 4]}, :third => "three"}, bag1.to_hash())
169
+
170
+ assert_indifferent_access_equal({:second => [3, 4]}, bag1, :first)
171
+ assert_indifferent_access_equal([3, 4], bag1["first"], :second)
172
+ end
173
+
174
+ def test_set_a_slot_with_a_hash_keeps_indifferent_access
175
+ bag1 = create_bag({})
176
+ bag1["first"] = {:second => [1, 2]}
177
+
178
+ assert_indifferent_access_equal({:second => [1, 2]}, bag1, :first)
179
+ assert_indifferent_access_equal([1, 2], bag1["first"], :second)
180
+ end
181
+
182
+ def test_nil_key()
183
+ assert_raises(ArgumentError) do
184
+ create_bag({nil => "value"})
185
+ end
186
+
187
+ parameters = create_bag({})
188
+
189
+ assert_raises(ArgumentError) do
190
+ parameters[nil] = 1
191
+ end
192
+
193
+ assert_raises(ArgumentError) do
194
+ parameters[nil]
195
+ end
196
+
197
+ assert_raises(ArgumentError) do
198
+ parameters.method_missing(nil)
199
+ end
200
+ end
201
+
202
+ def test_restricted_keys_are_still_accessible
203
+ keys = Helper::Bag.restricted_keys()
204
+ bag = create_bag(Hash[
205
+ keys.map do |key|
206
+ [key, "#{key.to_s} - value"]
207
+ end
208
+ ])
209
+
210
+ keys.each do |key|
211
+ assert_equal("#{key.to_s} - value", bag[key.to_s], "bag[#{key.to_s}]")
212
+ assert_equal("#{key.to_s} - value", bag[key.to_sym], "bag[#{key.to_sym}]")
213
+ end
214
+ end
215
+
216
+ def test_numeric_keys_converted_to_string
217
+ bag1 = create_bag({1 => "value1"})
218
+
219
+ assert_indifferent_access_equal("value1", bag1, :'1')
220
+ end
221
+
222
+ def test_custom_key_error_handler
223
+ bag = create_bag({:value => "one"}, :key_error => Proc.new do |key|
224
+ raise IndexError
225
+ end)
226
+
227
+ assert_raises(IndexError) do
228
+ bag.invalid_value
229
+ end
230
+
231
+ assert_raises(IndexError) do
232
+ bag["invalid_value"]
233
+ end
234
+
235
+ assert_raises(IndexError) do
236
+ bag[:invalid_value]
237
+ end
238
+ end
239
+
240
+ def test_custom_key_error_handler_returns_value
241
+ bag = create_bag({:value => "one"}, :key_error => Proc.new do |key|
242
+ "Some value"
243
+ end)
244
+
245
+ assert_indifferent_access_equal("Some value", bag, :invalid_value)
246
+ end
247
+
248
+ def test_walk_bag
249
+ bag = create_bag({
250
+ :first => {
251
+ :level1 => "value1",
252
+ :level2 => "value2",
253
+ },
254
+ :second => {
255
+ :level1 => "value3",
256
+ :level2 => "value4",
257
+ },
258
+ :third => "value5"
259
+ })
260
+
261
+ lines = []
262
+ bag.walk do |path, key, value|
263
+ lines << "Path (#{path}), Key (#{key}), Value (#{value})"
264
+ end
265
+
266
+ assert_equal([
267
+ "Path ([:first, :level1]), Key (level1), Value (value1)",
268
+ "Path ([:first, :level2]), Key (level2), Value (value2)",
269
+ "Path ([:second, :level1]), Key (level1), Value (value3)",
270
+ "Path ([:second, :level2]), Key (level2), Value (value4)",
271
+ "Path ([:third]), Key (third), Value (value5)",
272
+ ], lines)
273
+ end
274
+
275
+ def test_merge
276
+ bag1 = create_bag({
277
+ :first => {
278
+ :level1 => "value1",
279
+ :level2 => "value2",
280
+ },
281
+ :second => {
282
+ :level1 => "value3",
283
+ :level2 => "value4",
284
+ },
285
+ :third => "value5"
286
+ })
287
+
288
+ bag2 = create_bag({
289
+ :first => {
290
+ :level2 => "overriden2",
291
+ },
292
+ :second => {
293
+ :level1 => "value3",
294
+ :level2 => "value4",
295
+ },
296
+ :third => "overriden5"
297
+ })
298
+
299
+ bag3 = bag1.merge(bag2)
300
+
301
+ refute_same(bag1, bag3)
302
+ refute_same(bag2, bag3)
303
+
304
+ assert_equal(Nugrant::Bag, bag3.class)
305
+
306
+ assert_indifferent_access_equal("value1", bag3['first'], :level1)
307
+ assert_indifferent_access_equal("overriden2", bag3['first'], :level2)
308
+ assert_indifferent_access_equal("value3", bag3['second'], :level1)
309
+ assert_indifferent_access_equal("value4", bag3['second'], :level2)
310
+ assert_indifferent_access_equal("overriden5", bag3, :third)
311
+ end
312
+
313
+ def test_merge!
314
+ bag1 = create_bag({
315
+ :first => {
316
+ :level1 => "value1",
317
+ :level2 => "value2",
318
+ },
319
+ :second => {
320
+ :level1 => "value3",
321
+ :level2 => "value4",
322
+ },
323
+ :third => "value5"
324
+ })
325
+
326
+ bag2 = create_bag({
327
+ :first => {
328
+ :level2 => "overriden2",
329
+ },
330
+ :second => {
331
+ :level1 => "value3",
332
+ :level2 => "value4",
333
+ },
334
+ :third => "overriden5"
335
+ })
336
+
337
+ bag3 = bag1.merge!(bag2)
338
+
339
+ assert_same(bag1, bag3)
340
+ refute_same(bag2, bag3)
341
+
342
+ assert_equal(Nugrant::Bag, bag3.class)
343
+
344
+ assert_indifferent_access_equal("value1", bag3['first'], :level1)
345
+ assert_indifferent_access_equal("overriden2", bag3['first'], :level2)
346
+ assert_indifferent_access_equal("value3", bag3['second'], :level1)
347
+ assert_indifferent_access_equal("value4", bag3['second'], :level2)
348
+ assert_indifferent_access_equal("overriden5", bag3, :third)
349
+ end
350
+
351
+ def test_merge_hash()
352
+ bag1 = create_bag({"first" => {:second => [1, 2]}}, :array_merge_strategy => :extend)
353
+
354
+ bag1.merge!({"first" => {:second => [2, 3]}});
355
+
356
+ assert_equal({:first => {:second => [1, 2, 3]}}, bag1.to_hash())
357
+ end
358
+
359
+ def test_merge_custom_array_merge_strategy()
360
+ bag1 = create_bag({"first" => {:second => [1, 2]}}, :array_merge_strategy => :extend)
361
+
362
+ bag1.merge!({"first" => {:second => [2, 3]}}, :array_merge_strategy => :replace);
363
+
364
+ assert_equal({:first => {:second => [2, 3]}}, bag1.to_hash())
365
+ end
366
+
367
+ def test_merge_custom_invalid_array_merge_strategy()
368
+ bag1 = create_bag({"first" => {:second => [1, 2]}}, :array_merge_strategy => :extend)
369
+ bag2 = bag1.merge({"first" => {:second => [2, 3]}}, :array_merge_strategy => nil);
370
+
371
+ assert_equal({:first => {:second => [1, 2, 3]}}, bag2.to_hash())
372
+
373
+ bag2 = bag1.merge({"first" => {:second => [2, 3]}}, :array_merge_strategy => :invalid);
374
+
375
+ assert_equal({:first => {:second => [1, 2, 3]}}, bag2.to_hash())
376
+ end
377
+
378
+ def test_change_config
379
+ bag1 = create_bag({"first" => [1, 2]}, :array_merge_strategy => :extend)
380
+ bag2 = create_bag({:first => [2, 3]})
381
+
382
+ bag3 = bag1.merge!(bag2);
383
+ bag3.config = {
384
+ :array_merge_strategy => :concat
385
+ }
386
+
387
+ bag3.merge!({"first" => [1, 2, 3]})
388
+
389
+ assert_equal([1, 2, 3, 1, 2, 3], bag3['first'])
390
+ end
391
+
392
+ def test_indifferent_access_in_array
393
+ bag = create_bag({:a => [{:b => 1, :c => [{"d" => 1}]}]})
394
+
395
+ assert_indifferent_access_equal(1, bag['a'][0]['c'][0], :d)
396
+ end
397
+
398
+ ## Helpers & Assertions
399
+
400
+ def create_bag(elements, options = {})
401
+ return Bag.new(elements, options)
402
+ end
403
+
404
+ def assert_is_hash_exclusive(input)
405
+ assert_equal(true, input.kind_of?(Hash), "#{input} should be a kind of Hash")
406
+ assert_equal(false, input.kind_of?(Bag), "#{input} should not be a kind of Bag")
407
+ end
408
+
409
+ def assert_indifferent_access_equal(expected, bag, key)
410
+ assert_symbol_access_equal(expected, bag, key)
411
+ assert_string_access_equal(expected, bag, key)
412
+ end
413
+
414
+ def assert_string_access_equal(expected, bag, key)
415
+ assert_equal(expected, bag[key.to_s], "bag[#{key.to_s}]")
416
+ end
417
+
418
+ def assert_symbol_access_equal(expected, bag, key)
419
+ assert_equal(expected, bag.method_missing(key.to_sym), "bag.#{key.to_sym}")
420
+ assert_equal(expected, bag[key.to_sym], "bag[#{key.to_sym}]")
421
+ end
422
+
423
+ def assert_indifferent_access_bag_equal(expected, bag, key)
424
+ assert_string_access_bag_equal(expected, bag, key)
425
+ assert_symbol_access_bag_equal(expected, bag, key)
426
+ end
427
+
428
+ def assert_string_access_bag_equal(expected, bag, key)
429
+ assert_bag_equal(expected, bag[key.to_s])
430
+ end
431
+
432
+ def assert_symbol_access_bag_equal(expected, bag, key)
433
+ assert_bag_equal(expected, bag.method_missing(key.to_sym))
434
+ assert_bag_equal(expected, bag[key.to_sym])
435
+ end
436
+
437
+ def assert_bag_equal(expected, bag)
438
+ assert_kind_of(Bag, bag)
439
+
440
+ expected.each do |key, expected_value|
441
+ if not expected_value.kind_of?(Hash)
442
+ assert_indifferent_access_equal(expected_value, bag, key)
443
+ next
444
+ end
445
+
446
+ assert_indifferent_access_bag_equal(expected_value, bag, key)
447
+ end
448
+ end
449
+ end
450
+ end