cloud-templates 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
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