cloud-templates 0.1.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.
Files changed (86) hide show
  1. checksums.yaml +7 -0
  2. data/.rubocop.yml +29 -0
  3. data/.simplecov +6 -0
  4. data/Gemfile +2 -0
  5. data/LICENSE +201 -0
  6. data/NOTICE +13 -0
  7. data/README.md +124 -0
  8. data/Rakefile +27 -0
  9. data/cloud-templates.gemspec +27 -0
  10. data/examples/lib/user_directory/artifacts/catalogized.rb +11 -0
  11. data/examples/lib/user_directory/artifacts/group.rb +37 -0
  12. data/examples/lib/user_directory/artifacts/ided.rb +11 -0
  13. data/examples/lib/user_directory/artifacts/organization.rb +17 -0
  14. data/examples/lib/user_directory/artifacts/pathed.rb +22 -0
  15. data/examples/lib/user_directory/artifacts/person.rb +20 -0
  16. data/examples/lib/user_directory/artifacts/team.rb +31 -0
  17. data/examples/lib/user_directory/artifacts/unit.rb +24 -0
  18. data/examples/lib/user_directory/artifacts/user.rb +29 -0
  19. data/examples/lib/user_directory/render/etc/artifact_view.rb +15 -0
  20. data/examples/lib/user_directory/render/etc/composite_view.rb +26 -0
  21. data/examples/lib/user_directory/render/etc/group_view.rb +23 -0
  22. data/examples/lib/user_directory/render/etc/person_view.rb +19 -0
  23. data/examples/lib/user_directory/render/etc/registry.rb +33 -0
  24. data/examples/lib/user_directory/render/etc/user_view.rb +35 -0
  25. data/examples/lib/user_directory/render/etc.rb +3 -0
  26. data/examples/lib/user_directory/render/ldap/artifact_view.rb +27 -0
  27. data/examples/lib/user_directory/render/ldap/composite_view.rb +32 -0
  28. data/examples/lib/user_directory/render/ldap/group_view.rb +28 -0
  29. data/examples/lib/user_directory/render/ldap/organization_view.rb +26 -0
  30. data/examples/lib/user_directory/render/ldap/person_view.rb +39 -0
  31. data/examples/lib/user_directory/render/ldap/registry.rb +16 -0
  32. data/examples/lib/user_directory/render/ldap/unit_view.rb +26 -0
  33. data/examples/lib/user_directory/render/ldap/user_view.rb +39 -0
  34. data/examples/lib/user_directory/render/ldap.rb +3 -0
  35. data/examples/lib/user_directory/utils.rb +18 -0
  36. data/examples/lib/user_directory.rb +23 -0
  37. data/examples/lib_path.rb +2 -0
  38. data/examples/spec/spec_helper.rb +1 -0
  39. data/examples/spec/user_directory_spec.rb +568 -0
  40. data/lib/aws/templates/artifact.rb +140 -0
  41. data/lib/aws/templates/composite.rb +178 -0
  42. data/lib/aws/templates/exceptions.rb +221 -0
  43. data/lib/aws/templates/render/registry.rb +60 -0
  44. data/lib/aws/templates/render/utils/base_type_views.rb +131 -0
  45. data/lib/aws/templates/render/view.rb +127 -0
  46. data/lib/aws/templates/render.rb +72 -0
  47. data/lib/aws/templates/utils/artifact_storage.rb +141 -0
  48. data/lib/aws/templates/utils/contextualized/filters.rb +437 -0
  49. data/lib/aws/templates/utils/contextualized/hash.rb +13 -0
  50. data/lib/aws/templates/utils/contextualized/nil.rb +13 -0
  51. data/lib/aws/templates/utils/contextualized/proc.rb +13 -0
  52. data/lib/aws/templates/utils/contextualized.rb +113 -0
  53. data/lib/aws/templates/utils/default.rb +185 -0
  54. data/lib/aws/templates/utils/dependency/enumerable.rb +13 -0
  55. data/lib/aws/templates/utils/dependency/object.rb +46 -0
  56. data/lib/aws/templates/utils/dependency.rb +121 -0
  57. data/lib/aws/templates/utils/dependent.rb +28 -0
  58. data/lib/aws/templates/utils/inheritable.rb +52 -0
  59. data/lib/aws/templates/utils/late_bound.rb +89 -0
  60. data/lib/aws/templates/utils/memoized.rb +27 -0
  61. data/lib/aws/templates/utils/named.rb +19 -0
  62. data/lib/aws/templates/utils/options.rb +279 -0
  63. data/lib/aws/templates/utils/parametrized/constraints.rb +423 -0
  64. data/lib/aws/templates/utils/parametrized/getters.rb +293 -0
  65. data/lib/aws/templates/utils/parametrized/guarded.rb +32 -0
  66. data/lib/aws/templates/utils/parametrized/mapper.rb +73 -0
  67. data/lib/aws/templates/utils/parametrized/nested.rb +72 -0
  68. data/lib/aws/templates/utils/parametrized/transformations.rb +660 -0
  69. data/lib/aws/templates/utils/parametrized.rb +240 -0
  70. data/lib/aws/templates/utils.rb +219 -0
  71. data/lib/aws/templates.rb +16 -0
  72. data/spec/aws/templates/artifact_spec.rb +161 -0
  73. data/spec/aws/templates/composite_spec.rb +361 -0
  74. data/spec/aws/templates/render/utils/base_type_views_spec.rb +104 -0
  75. data/spec/aws/templates/render_spec.rb +62 -0
  76. data/spec/aws/templates/utils/as_named_spec.rb +31 -0
  77. data/spec/aws/templates/utils/contextualized/filters_spec.rb +108 -0
  78. data/spec/aws/templates/utils/contextualized_spec.rb +115 -0
  79. data/spec/aws/templates/utils/late_bound_spec.rb +52 -0
  80. data/spec/aws/templates/utils/options_spec.rb +67 -0
  81. data/spec/aws/templates/utils/parametrized/constraint_spec.rb +175 -0
  82. data/spec/aws/templates/utils/parametrized/getters_spec.rb +139 -0
  83. data/spec/aws/templates/utils/parametrized/transformation_spec.rb +314 -0
  84. data/spec/aws/templates/utils/parametrized_spec.rb +241 -0
  85. data/spec/spec_helper.rb +6 -0
  86. metadata +244 -0
@@ -0,0 +1,361 @@
1
+ require 'spec_helper'
2
+ require 'aws/templates/composite'
3
+
4
+ class A
5
+ attr_reader :params
6
+
7
+ def label
8
+ @params[:label]
9
+ end
10
+
11
+ def initialize(p)
12
+ @params = p
13
+ end
14
+
15
+ def eql?(other)
16
+ (self.class == other.class) && (params.to_hash == other.params.to_hash)
17
+ end
18
+
19
+ def ==(other)
20
+ eql?(other)
21
+ end
22
+
23
+ def !=(other)
24
+ !eql?(other)
25
+ end
26
+ end
27
+
28
+ describe Aws::Templates::Composite do
29
+ let(:composite_class) do
30
+ Class.new(Aws::Templates::Composite) do
31
+ default rocket: 'spacehawk'
32
+ default spaceship: 'martyr'
33
+
34
+ contextualize filter(:copy) &
35
+ { erased: 'forever' } &
36
+ (filter(:override) { { root: self } })
37
+
38
+ components do
39
+ artifact A, label: 'b'
40
+ artifact A, label: 'a', w: artifact(A, label: 'z')
41
+ artifact A, label: 'y', w: artifact(A, label: 'x').not_a_dependency
42
+ artifact(
43
+ A,
44
+ filter(:override) { { boomer: options[:rocket].upcase, vehicle: options[:spaceship] } } &
45
+ { label: 'c' }
46
+ )
47
+ end
48
+ end
49
+ end
50
+
51
+ let(:parameters) { { label: 'q' } }
52
+
53
+ let(:artifacts) do
54
+ instance.artifacts.each_with_object({}) { |(k, v), memo| memo[k] = v.params.to_hash }
55
+ end
56
+
57
+ context 'a parameter is overriden' do
58
+ let(:instance) { composite_class.new(parameters) }
59
+
60
+ let(:result) do
61
+ {
62
+ 'z' => {
63
+ label: 'z',
64
+ rocket: 'serenity',
65
+ spaceship: 'martyr',
66
+ erased: 'forever',
67
+ root: instance,
68
+ parent: instance
69
+ },
70
+ 'x' => {
71
+ label: 'x',
72
+ rocket: 'serenity',
73
+ spaceship: 'martyr',
74
+ erased: 'forever',
75
+ root: instance,
76
+ parent: instance
77
+ },
78
+ 'b' => {
79
+ label: 'b',
80
+ rocket: 'serenity',
81
+ spaceship: 'martyr',
82
+ erased: 'forever',
83
+ root: instance,
84
+ parent: instance
85
+ },
86
+ 'a' => {
87
+ label: 'a',
88
+ rocket: 'serenity',
89
+ spaceship: 'martyr',
90
+ erased: 'forever',
91
+ w: Aws::Templates::Utils::Dependency.new(
92
+ A.new(
93
+ label: 'z',
94
+ rocket: 'serenity',
95
+ spaceship: 'martyr',
96
+ erased: 'forever',
97
+ root: instance,
98
+ parent: instance
99
+ )
100
+ ),
101
+ root: instance,
102
+ parent: instance
103
+ },
104
+ 'y' => {
105
+ label: 'y',
106
+ rocket: 'serenity',
107
+ spaceship: 'martyr',
108
+ erased: 'forever',
109
+ w: A.new(
110
+ label: 'x',
111
+ rocket: 'serenity',
112
+ spaceship: 'martyr',
113
+ erased: 'forever',
114
+ root: instance,
115
+ parent: instance
116
+ ),
117
+ root: instance,
118
+ parent: instance
119
+ },
120
+ 'c' => {
121
+ label: 'y',
122
+ rocket: 'serenity',
123
+ spaceship: 'martyr',
124
+ boomer: 'SERENITY',
125
+ vehicle: 'martyr',
126
+ erased: 'forever',
127
+ root: instance,
128
+ parent: instance
129
+ }
130
+ }
131
+ end
132
+
133
+ before { parameters[:rocket] = 'serenity' }
134
+
135
+ it 'has predictable parameters distribution' do
136
+ v = instance['b'].params.to_hash
137
+ expect(v).to be == result['b']
138
+ end
139
+
140
+ it 'throws exception when unknown artifact is being extracted' do
141
+ expect { instance['w'] }.to raise_error RuntimeError, /There is no artifact/
142
+ end
143
+
144
+ it 'has all expected artifacts' do
145
+ expect(artifacts['a']).to be == result['a']
146
+ end
147
+ end
148
+
149
+ describe 'search' do
150
+ let(:instance) do
151
+ artifact_class = Class.new(Aws::Templates::Artifact) { parameter :yoke }
152
+ nested_class = composite_class
153
+ composite_class.new(parameters).components do
154
+ artifact artifact_class,
155
+ label: 'w',
156
+ yoke: Struct.new(:one, :two).new('fruit', 'veggie')
157
+ artifact nested_class, label: 'r'
158
+ end
159
+ end
160
+
161
+ describe 'search by label' do
162
+ let(:found_artifacts) { instance.search(label: 'c') }
163
+
164
+ it 'is only one artifact labeled c' do
165
+ expect(found_artifacts.size).to be == 1
166
+ end
167
+
168
+ it 'finds correct artifact' do
169
+ expect(found_artifacts.first.params[:boomer]).to be == 'SPACEHAWK'
170
+ end
171
+ end
172
+
173
+ describe 'search by field' do
174
+ let(:found_artifacts) { instance.search(parameters: { yoke: { two: 'veggie' } }) }
175
+
176
+ it 'is only one artifact which has field set' do
177
+ expect(found_artifacts.size).to be == 1
178
+ end
179
+
180
+ it 'finds correct artifact' do
181
+ v = found_artifacts.first
182
+ expect(v.yoke.two).to be == 'veggie'
183
+ end
184
+ end
185
+
186
+ describe 'search by class' do
187
+ let(:found_artifacts) { instance.search(klass: A) }
188
+
189
+ it 'has 3 found artifacts' do
190
+ expect(found_artifacts.size).to be == 6
191
+ end
192
+
193
+ it 'finds correct artifacts' do
194
+ expect(found_artifacts.map(&:label).sort).to be == %w[a b c x y z]
195
+ end
196
+ end
197
+
198
+ describe 'search recursively' do
199
+ let(:found_artifacts) { instance.search(klass: A, recursive: true) }
200
+
201
+ it 'has 6 found artifacts' do
202
+ expect(found_artifacts.size).to be == 12
203
+ end
204
+
205
+ it 'finds correct artifacts' do
206
+ expect(found_artifacts.map(&:label).sort).to be == %w[a a b b c c x x y y z z]
207
+ end
208
+ end
209
+ end
210
+
211
+ describe 'adding artifacts' do
212
+ shared_examples 'an artifact storage' do
213
+ it 'contains artifact t' do
214
+ expect(instance['t'].params.to_hash).to be == result['t']
215
+ end
216
+
217
+ it 'contains expected artifacts' do
218
+ expect(artifacts).to be == result
219
+ end
220
+ end
221
+
222
+ before { parameters[:postfix] = 'X' }
223
+
224
+ let(:result) do
225
+ {
226
+ 'z' => {
227
+ label: 'z',
228
+ rocket: 'spacehawk',
229
+ spaceship: 'martyr',
230
+ erased: 'forever',
231
+ postfix: 'X',
232
+ root: instance,
233
+ parent: instance
234
+ },
235
+ 'x' => {
236
+ label: 'x',
237
+ rocket: 'spacehawk',
238
+ spaceship: 'martyr',
239
+ erased: 'forever',
240
+ postfix: 'X',
241
+ root: instance,
242
+ parent: instance
243
+ },
244
+ 'b' => {
245
+ label: 'b',
246
+ rocket: 'spacehawk',
247
+ spaceship: 'martyr',
248
+ erased: 'forever',
249
+ postfix: 'X',
250
+ root: instance,
251
+ parent: instance
252
+ },
253
+ 'a' => {
254
+ label: 'a',
255
+ rocket: 'spacehawk',
256
+ spaceship: 'martyr',
257
+ erased: 'forever',
258
+ postfix: 'X',
259
+ w: Aws::Templates::Utils::Dependency.new(
260
+ A.new(
261
+ label: 'z',
262
+ rocket: 'spacehawk',
263
+ spaceship: 'martyr',
264
+ erased: 'forever',
265
+ postfix: 'X',
266
+ root: instance,
267
+ parent: instance
268
+ )
269
+ ),
270
+ root: instance,
271
+ parent: instance
272
+ },
273
+ 'y' => {
274
+ label: 'y',
275
+ rocket: 'spacehawk',
276
+ spaceship: 'martyr',
277
+ erased: 'forever',
278
+ postfix: 'X',
279
+ w: A.new(
280
+ label: 'x',
281
+ rocket: 'spacehawk',
282
+ spaceship: 'martyr',
283
+ erased: 'forever',
284
+ postfix: 'X',
285
+ root: instance,
286
+ parent: instance
287
+ ),
288
+ root: instance,
289
+ parent: instance
290
+ },
291
+ 'c' => {
292
+ label: 'c',
293
+ rocket: 'spacehawk',
294
+ spaceship: 'martyr',
295
+ boomer: 'SPACEHAWK',
296
+ vehicle: 'martyr',
297
+ erased: 'forever',
298
+ postfix: 'X',
299
+ root: instance,
300
+ parent: instance
301
+ },
302
+ 't' => {
303
+ label: 't',
304
+ rocket: 'spacehawk',
305
+ spaceship: 'martyr',
306
+ rumba: 'SPACEHAWKX',
307
+ postfix: 'X',
308
+ erased: 'forever',
309
+ root: instance,
310
+ parent: instance
311
+ }
312
+ }
313
+ end
314
+
315
+ context 'using constructor block' do
316
+ let(:instance) do
317
+ composite_class.new(parameters) do
318
+ artifact(
319
+ A,
320
+ filter(:override) { { rumba: artifacts['c'].params[:boomer] + options[:postfix] } } &
321
+ { label: 't' }
322
+ )
323
+ end
324
+ end
325
+
326
+ it_behaves_like 'an artifact storage'
327
+ end
328
+
329
+ context 'using instance components method' do
330
+ let(:instance) do
331
+ composite_class.new(parameters).components do
332
+ artifact(
333
+ A,
334
+ filter(:override) { { rumba: artifacts['c'].params[:boomer] + options[:postfix] } } &
335
+ { label: 't' }
336
+ )
337
+ end
338
+ end
339
+
340
+ it_behaves_like 'an artifact storage'
341
+ end
342
+
343
+ context 'using subclass' do
344
+ let(:subclass) do
345
+ Class.new(composite_class) do
346
+ components do
347
+ artifact(
348
+ A,
349
+ filter(:override) { { rumba: artifacts['c'].params[:boomer] + options[:postfix] } } &
350
+ { label: 't' }
351
+ )
352
+ end
353
+ end
354
+ end
355
+
356
+ let(:instance) { subclass.new(parameters) }
357
+
358
+ it_behaves_like 'an artifact storage'
359
+ end
360
+ end
361
+ end
@@ -0,0 +1,104 @@
1
+ require 'spec_helper'
2
+ require 'aws/templates/render/utils/base_type_views'
3
+ require 'aws/templates/render'
4
+
5
+ include Aws::Templates::Render::Utils::BaseTypeViews
6
+
7
+ describe Aws::Templates::Render::Utils::BaseTypeViews do
8
+ let(:render) do
9
+ Module.new do
10
+ extend Aws::Templates::Render
11
+ end
12
+ end
13
+
14
+ describe 'AsIs' do
15
+ before { render.define_view(Object, AsIs) }
16
+
17
+ it 'renders string' do
18
+ expect(render.view_for('123').to_rendered).to be == '123'
19
+ end
20
+
21
+ it 'renders random object' do
22
+ expect(render.view_for([123]).to_rendered).to be == [123]
23
+ end
24
+ end
25
+
26
+ describe 'ToString' do
27
+ before { render.define_view(Object, ToString) }
28
+
29
+ it 'renders string' do
30
+ expect(render.view_for('123').to_rendered).to be == '123'
31
+ end
32
+
33
+ it 'renders number' do
34
+ expect(render.view_for(123).to_rendered).to be == '123'
35
+ end
36
+ end
37
+
38
+ describe 'ToArray' do
39
+ before do
40
+ render.define_view(Array, ToArray)
41
+ render.define_view(Object, ToString)
42
+ end
43
+
44
+ it 'renders array' do
45
+ expect(render.view_for([[1, 2, 3], '123']).to_rendered).to be == [%w[1 2 3], '123']
46
+ end
47
+ end
48
+
49
+ describe 'ToHash' do
50
+ before do
51
+ render.define_view(Object, ToString)
52
+ render.define_view(Hash, ToHash)
53
+ end
54
+
55
+ it 'renders hash' do
56
+ expect(render.view_for(q: 1, w: { e: 2, r: 3 }).to_rendered)
57
+ .to be == { 'q' => '1', 'w' => { 'e' => '2', 'r' => '3' } }
58
+ end
59
+ end
60
+
61
+ describe 'ToFloat' do
62
+ before { render.define_view(Object, ToFloat) }
63
+
64
+ it 'renders integer' do
65
+ expect(render.view_for(1).to_rendered).to be == 1.0
66
+ end
67
+
68
+ it 'renders string' do
69
+ expect(render.view_for('1.3').to_rendered).to be == 1.3
70
+ end
71
+ end
72
+
73
+ describe 'ToInteger' do
74
+ before { render.define_view(Object, ToInteger) }
75
+
76
+ it 'renders float' do
77
+ expect(render.view_for(1.3).to_rendered).to be == 1
78
+ end
79
+
80
+ it 'renders string' do
81
+ expect(render.view_for('23').to_rendered).to be == 23
82
+ end
83
+ end
84
+
85
+ describe 'ToBoolean' do
86
+ before { render.define_view(Object, ToBoolean) }
87
+
88
+ it 'renders random object' do
89
+ expect(render.view_for([]).to_rendered).to be == true
90
+ end
91
+
92
+ it 'renders false' do
93
+ expect(render.view_for(false).to_rendered).to be == false
94
+ end
95
+
96
+ it 'renders false as a string' do
97
+ expect(render.view_for('false').to_rendered).to be == false
98
+ end
99
+
100
+ it 'renders true' do
101
+ expect(render.view_for(true).to_rendered).to be == true
102
+ end
103
+ end
104
+ end
@@ -0,0 +1,62 @@
1
+ require 'spec_helper'
2
+ require 'aws/templates/render'
3
+
4
+ describe Aws::Templates::Render do
5
+ let(:render) do
6
+ Module.new { extend Aws::Templates::Render }
7
+ end
8
+
9
+ let(:artifact_class) { Class.new }
10
+
11
+ let(:child_artifact_class1) { Class.new(artifact_class) }
12
+
13
+ let(:child_artifact_class2) { Class.new(artifact_class) }
14
+
15
+ let(:unknown_artifact) { Class.new }
16
+
17
+ let(:view1) do
18
+ k = Class.new(Aws::Templates::Render::View) do
19
+ def initialize(arg, params); end
20
+
21
+ def to_rendered
22
+ 'Render 1'
23
+ end
24
+ end
25
+
26
+ k.register_in(render).artifact(artifact_class)
27
+ end
28
+
29
+ let(:view2) do
30
+ k = Class.new(view1) do
31
+ def to_rendered
32
+ 'Render 2'
33
+ end
34
+ end
35
+
36
+ k.artifact(child_artifact_class1)
37
+ end
38
+
39
+ before do
40
+ view1
41
+ view2
42
+ end
43
+
44
+ it 'renders class correctly' do
45
+ expect(render.view_for(artifact_class.new).to_rendered).to be == 'Render 1'
46
+ end
47
+
48
+ it 'renders child class correctly' do
49
+ expect(render.view_for(child_artifact_class1.new).to_rendered)
50
+ .to be == 'Render 2'
51
+ end
52
+
53
+ it 'renders yet another child class correctly' do
54
+ expect(render.view_for(child_artifact_class2.new).to_rendered)
55
+ .to be == 'Render 1'
56
+ end
57
+
58
+ it 'throws an error once no classes are found' do
59
+ expect { render.view_for(unknown_artifact.new).to_rendered }
60
+ .to raise_error Aws::Templates::ViewNotFound
61
+ end
62
+ end
@@ -0,0 +1,31 @@
1
+ require 'spec_helper'
2
+ require 'aws/templates/utils/named'
3
+ require 'aws/templates/utils/parametrized/getters'
4
+
5
+ describe Aws::Templates::Utils::AsNamed do
6
+ let(:named_class) do
7
+ Class.new do
8
+ include Aws::Templates::Utils::Parametrized
9
+
10
+ include Aws::Templates::Utils::AsNamed
11
+
12
+ attr_reader :options
13
+
14
+ def self.getter
15
+ as_is
16
+ end
17
+
18
+ def initialize(hsh)
19
+ @options = hsh
20
+ end
21
+ end
22
+ end
23
+
24
+ it 'returns name' do
25
+ expect(named_class.new(name: 'orugva').name).to be == 'orugva'
26
+ end
27
+
28
+ it 'fails when name is not provided' do
29
+ expect { named_class.new({}).name }.to raise_error(/Name of the object/)
30
+ end
31
+ end
@@ -0,0 +1,108 @@
1
+ require 'spec_helper'
2
+ require 'aws/templates/utils/contextualized'
3
+ require 'aws/templates/utils/options'
4
+
5
+ describe Aws::Templates::Utils::Contextualized::Filter do
6
+ let(:filtered_class) do
7
+ Class.new do
8
+ include Aws::Templates::Utils::Contextualized
9
+ end
10
+ end
11
+
12
+ let(:test_class) {}
13
+
14
+ let(:instance) { test_class.new }
15
+
16
+ describe 'override' do
17
+ let(:test_class) do
18
+ Class.new(filtered_class) do
19
+ contextualize a: 'awesome'
20
+ end
21
+ end
22
+
23
+ it 'adds element into hash' do
24
+ opts = Aws::Templates::Utils::Options.new(b: 2, c: 3)
25
+ expect(opts.filter(&instance.context).to_hash).to be == { a: 'awesome' }
26
+ end
27
+
28
+ context 'when full context copied' do
29
+ let(:test_class) do
30
+ Class.new(filtered_class) do
31
+ contextualize filter(:copy) & { a: 'awesome' }
32
+ end
33
+ end
34
+
35
+ it 'overrides element in the hash' do
36
+ opts = Aws::Templates::Utils::Options.new(a: 1, b: 2, c: 3)
37
+ expect(opts.filter(&instance.context).to_hash).to be == { a: 'awesome', b: 2, c: 3 }
38
+ end
39
+ end
40
+ end
41
+
42
+ describe 'remove' do
43
+ let(:test_class) do
44
+ Class.new(filtered_class) do
45
+ contextualize filter(:copy) & filter(:remove, :a, r: [:x])
46
+ end
47
+ end
48
+
49
+ it 'does nothing to hash without elements to remove' do
50
+ opts = Aws::Templates::Utils::Options.new(b: 2, c: 3)
51
+ expect(opts.filter(&instance.context).to_hash).to be == { b: 2, c: 3 }
52
+ end
53
+
54
+ it 'removes specified key from hash' do
55
+ opts = Aws::Templates::Utils::Options.new(a: 1, b: 2, c: 3, r: { x: 1, z: 0 })
56
+ expect(opts.filter(&instance.context).to_hash).to be == { b: 2, c: 3, r: { z: 0 } }
57
+ end
58
+ end
59
+
60
+ describe 'add' do
61
+ let(:test_class) do
62
+ Class.new(filtered_class) do
63
+ contextualize filter(:add, :a, r: [:x])
64
+ end
65
+ end
66
+
67
+ it 'adds the only key found' do
68
+ opts = Aws::Templates::Utils::Options.new(a: 1, b: 2, c: 3)
69
+ expect(opts.filter(&instance.context).to_hash).to be == { a: 1 }
70
+ end
71
+
72
+ it 'adds specified keys from hash' do
73
+ opts = Aws::Templates::Utils::Options.new(a: 1, b: 2, c: 3, r: { x: 1, z: 0 })
74
+ expect(opts.filter(&instance.context).to_hash).to be == { a: 1, r: { x: 1 } }
75
+ end
76
+ end
77
+
78
+ describe 'chain' do
79
+ let(:test_class) do
80
+ Class.new(filtered_class) do
81
+ contextualize filter(:copy) & filter(:remove, :a) & filter(:override, f: 10)
82
+ end
83
+ end
84
+
85
+ it 'does nothing to hash without elements to remove' do
86
+ opts = Aws::Templates::Utils::Options.new(b: 2, c: 3)
87
+ expect(opts.filter(&instance.context).to_hash).to be == { b: 2, c: 3, f: 10 }
88
+ end
89
+
90
+ it 'removes specified key from hash' do
91
+ opts = Aws::Templates::Utils::Options.new(a: 1, b: 2, c: 3)
92
+ expect(opts.filter(&instance.context).to_hash).to be == { b: 2, c: 3, f: 10 }
93
+ end
94
+ end
95
+
96
+ describe 'identity' do
97
+ let(:test_class) do
98
+ Class.new(filtered_class) do
99
+ contextualize filter(:copy) & filter(:identity)
100
+ end
101
+ end
102
+
103
+ it 'adds element into hash' do
104
+ opts = Aws::Templates::Utils::Options.new(b: 2, c: 3)
105
+ expect(opts.filter(&instance.context).to_hash).to be == { b: 2, c: 3 }
106
+ end
107
+ end
108
+ end