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,314 @@
1
+ require 'spec_helper'
2
+ require 'aws/templates/utils/parametrized'
3
+ require 'aws/templates/utils/parametrized/transformations'
4
+ require 'aws/templates/utils/parametrized/constraints'
5
+ require 'aws/templates/utils/parametrized/getters'
6
+ require 'aws/templates/render'
7
+
8
+ module TestRender
9
+ extend Aws::Templates::Render
10
+ StringView = Class.new(Aws::Templates::Render::BasicView) do
11
+ def to_rendered
12
+ _stringify(instance)
13
+ end
14
+
15
+ def _stringify(obj)
16
+ return obj.to_s unless obj.respond_to?(:to_hash)
17
+ obj.to_hash.map { |k, v| [_stringify(k), _stringify(v)] }.to_h
18
+ end
19
+ end
20
+ StringView.register_in self
21
+ StringView.artifact ::Object
22
+ end
23
+
24
+ describe Aws::Templates::Utils::Parametrized::Transformation do
25
+ let(:parametrized_class) do
26
+ Class.new do
27
+ include Aws::Templates::Utils::Parametrized
28
+
29
+ def self.getter
30
+ as_is
31
+ end
32
+
33
+ attr_reader :options
34
+
35
+ def initialize(options)
36
+ @options = options
37
+ end
38
+ end
39
+ end
40
+
41
+ describe 'as_object' do
42
+ let(:test_class) do
43
+ Class.new(parametrized_class) do
44
+ parameter :something,
45
+ transform: as_object {
46
+ parameter :a, description: 'Parameter A'
47
+ parameter :b, description: 'Parameter B'
48
+ parameter :c, description: 'Parameter C', constraint: not_nil
49
+ }
50
+ end
51
+ end
52
+
53
+ it 'transforms hash into object correctly' do
54
+ i = test_class.new(something: { a: 1, b: 2, c: 3 })
55
+ expect([i.something.a, i.something.b, i.something.c])
56
+ .to be == [1, 2, 3]
57
+ end
58
+
59
+ it 'allows nil values in sub-fields if no constraint is specified' do
60
+ i = test_class.new(something: { a: 1, b: nil, c: 3 })
61
+ expect([i.something.a, i.something.b, i.something.c])
62
+ .to be == [1, nil, 3]
63
+ end
64
+
65
+ it 'throws an error if sub-parameter constraint is not satisfied' do
66
+ i = test_class.new(something: { a: 1, b: 2, c: nil })
67
+ expect { [i.something.a, i.something.b, i.something.c] }
68
+ .to raise_error Aws::Templates::ParameterValueInvalid
69
+ end
70
+ end
71
+
72
+ describe 'as_list' do
73
+ let(:test_class) do
74
+ Class.new(parametrized_class) do
75
+ parameter :something,
76
+ description: 'Something misterious',
77
+ transform: as_list(
78
+ name: :element,
79
+ description: 'Force of nature'
80
+ )
81
+ parameter :something_else,
82
+ description: 'Absolutely incomprehensible',
83
+ transform: as_list(
84
+ name: :element,
85
+ description: 'Celestial image',
86
+ constraint: not_nil
87
+ )
88
+ end
89
+ end
90
+
91
+ it 'handles nil values' do
92
+ expect(test_class.new({}).something).to be_nil
93
+ end
94
+
95
+ it 'handles list value' do
96
+ expect(test_class.new(something: [1, 2, 3]).something).to be == [1, 2, 3]
97
+ end
98
+
99
+ it 'allows nil values if no constraints are specified' do
100
+ expect(test_class.new(something: [1, nil, 3]).something).to be == [1, nil, 3]
101
+ end
102
+
103
+ it 'works with any kind of object' do
104
+ expect(test_class.new(something: 'abc'.each_char).something).to be == %w[a b c]
105
+ end
106
+
107
+ it 'fails if the value can be transformed to an array' do
108
+ expect { test_class.new(something: 'abc').something }
109
+ .to raise_error Aws::Templates::NestedParameterException
110
+ end
111
+
112
+ it 'returns correct value if sub-constraints are satisfied' do
113
+ expect(test_class.new(something_else: [1, 2, 3]).something_else).to be == [1, 2, 3]
114
+ end
115
+
116
+ it 'throws an exception if one or more elements don\'t satisfy sub-constraint' do
117
+ expect { test_class.new(something_else: [1, nil, 3]).something_else }
118
+ .to raise_error(/Celestial image/)
119
+ end
120
+ end
121
+
122
+ describe 'as_rendered' do
123
+ let(:render) { TestRender }
124
+
125
+ let(:test_class) do
126
+ klass = Class.new(parametrized_class)
127
+ klass.parameter :something, transform: klass.as_rendered(render)
128
+ klass
129
+ end
130
+
131
+ it 'transforms hash into stringified hash correctly' do
132
+ i = test_class.new(something: { a: 1, b: 2, c: 3 })
133
+ expect(i.something).to be == { 'a' => '1', 'b' => '2', 'c' => '3' }
134
+ end
135
+
136
+ it 'allows nil value' do
137
+ i = test_class.new({})
138
+ expect(i.something).to be_nil
139
+ end
140
+ end
141
+
142
+ describe 'as_integer' do
143
+ let(:test_class) do
144
+ Class.new(parametrized_class) do
145
+ parameter :something, transform: as_integer
146
+ end
147
+ end
148
+
149
+ it 'transforms string into integer correctly' do
150
+ i = test_class.new(something: '23')
151
+ expect(i.something).to be == 23
152
+ end
153
+
154
+ it 'allows nil value' do
155
+ i = test_class.new({})
156
+ expect(i.something).to be_nil
157
+ end
158
+
159
+ it 'fails on wrong value' do
160
+ i = test_class.new(something: [])
161
+ expect { i.something }.to raise_error Aws::Templates::NestedParameterException
162
+ end
163
+ end
164
+
165
+ describe 'as_string' do
166
+ let(:test_class) do
167
+ Class.new(parametrized_class) do
168
+ parameter :something, transform: as_string
169
+ end
170
+ end
171
+
172
+ it 'transforms integer into string correctly' do
173
+ i = test_class.new(something: 23)
174
+ expect(i.something).to be == '23'
175
+ end
176
+
177
+ it 'allows nil value' do
178
+ i = test_class.new({})
179
+ expect(i.something).to be_nil
180
+ end
181
+ end
182
+
183
+ describe 'as_boolean' do
184
+ let(:test_class) do
185
+ Class.new(parametrized_class) do
186
+ parameter :something, transform: as_boolean
187
+ end
188
+ end
189
+
190
+ it 'transforms string into boolean correctly' do
191
+ i = test_class.new(something: 23)
192
+ expect(i.something).to be == true
193
+ end
194
+
195
+ it 'transforms false correctly' do
196
+ i = test_class.new(something: false)
197
+ expect(i.something).to be == false
198
+ end
199
+
200
+ it 'transforms true correctly' do
201
+ i = test_class.new(something: true)
202
+ expect(i.something).to be == true
203
+ end
204
+
205
+ it 'transforms false string correctly' do
206
+ i = test_class.new(something: 'false')
207
+ expect(i.something).to be == false
208
+ end
209
+
210
+ it 'allows nil value' do
211
+ i = test_class.new({})
212
+ expect(i.something).to be_nil
213
+ end
214
+ end
215
+
216
+ describe 'as_hash' do
217
+ let(:test_class) do
218
+ Class.new(parametrized_class) do
219
+ parameter :something, transform: as_hash
220
+ parameter :something2,
221
+ transform: as_hash {
222
+ key name: :key,
223
+ description: 'String key',
224
+ constraint: not_nil,
225
+ transform: as_string
226
+ value name: :number,
227
+ description: 'Just a number',
228
+ constraint: not_nil,
229
+ transform: as_integer
230
+ }
231
+ end
232
+ end
233
+
234
+ let(:hashable) do
235
+ Class.new do
236
+ def to_hash
237
+ { w: 'qwe' }
238
+ end
239
+ end
240
+ end
241
+
242
+ it 'transforms hash correctly' do
243
+ i = test_class.new(something: { q: 3 })
244
+ expect(i.something).to be == { q: 3 }
245
+ end
246
+
247
+ it 'transforms array into hash correctly' do
248
+ i = test_class.new(something: [[:q, 3]])
249
+ expect(i.something).to be == { q: 3 }
250
+ end
251
+
252
+ it 'transforms an object into hash correctly' do
253
+ i = test_class.new(something: hashable.new)
254
+ expect(i.something).to be == { w: 'qwe' }
255
+ end
256
+
257
+ it 'allows nil value' do
258
+ i = test_class.new({})
259
+ expect(i.something).to be_nil
260
+ end
261
+
262
+ it 'understands internal structure' do
263
+ i = test_class.new(something2: { q: '3' })
264
+ expect(i.something2).to be == { 'q' => 3 }
265
+ end
266
+
267
+ it 'performs internal constraint check' do
268
+ i = test_class.new(something2: { q: nil })
269
+ expect { i.something2 }.to raise_error(/Just a number/)
270
+ end
271
+ end
272
+
273
+ describe 'as_module' do
274
+ let(:test_class) do
275
+ Class.new(parametrized_class) do
276
+ parameter :something, transform: as_module
277
+ end
278
+ end
279
+
280
+ it 'passes a class as is' do
281
+ i = test_class.new(something: Object)
282
+ expect(i.something).to be == Object
283
+ end
284
+
285
+ it 'looks up class name' do
286
+ i = test_class.new(something: 'Object')
287
+ expect(i.something).to be == Object
288
+ end
289
+
290
+ it 'is able to work with paths' do
291
+ i = test_class.new(something: 'Object::Object::Object::Array')
292
+ expect(i.something).to be == Array
293
+ end
294
+
295
+ it 'accepts different path specifications' do
296
+ i = test_class.new(something: 'Object/Object/Object/Array')
297
+ expect(i.something).to be == Array
298
+ end
299
+ end
300
+
301
+ describe 'as_chain' do
302
+ let(:test_class) do
303
+ Class.new(parametrized_class) do
304
+ parameter :something,
305
+ transform: as_chain(as_hash, as_object { parameter :rule })
306
+ end
307
+ end
308
+
309
+ it 'applies all transformations' do
310
+ i = test_class.new(something: [[:rule, 1]])
311
+ expect(i.something.rule).to be == 1
312
+ end
313
+ end
314
+ end
@@ -0,0 +1,241 @@
1
+ require 'spec_helper'
2
+ require 'aws/templates/utils/parametrized'
3
+ require 'aws/templates/utils/parametrized/getters'
4
+
5
+ describe Aws::Templates::Utils::Parametrized do
6
+ let(:including_class) do
7
+ Class.new do
8
+ include Aws::Templates::Utils::Parametrized
9
+
10
+ attr_reader :options
11
+
12
+ def self.getter
13
+ as_is
14
+ end
15
+
16
+ def initialize(options)
17
+ @options = options
18
+ end
19
+ end
20
+ end
21
+
22
+ let(:including_module) do
23
+ Module.new do
24
+ include Aws::Templates::Utils::Parametrized
25
+
26
+ parameter :mixed_parameter,
27
+ description: 'Just a parameter which will be added ' \
28
+ 'into including modules/classes',
29
+ transform: ->(_, v) { v.to_s }
30
+ end
31
+ end
32
+
33
+ describe 'module include' do
34
+ it 'has parameter DSL method' do
35
+ expect(including_module).to respond_to(:parameter)
36
+ end
37
+
38
+ it 'has accessor defined with the DSL' do
39
+ expect(including_module.method_defined?(:mixed_parameter))
40
+ .to be == true
41
+ end
42
+
43
+ it 'has parameter object defined with appropriate name' do
44
+ expect(including_module.get_parameter(:mixed_parameter).name)
45
+ .to be == :mixed_parameter
46
+ end
47
+ end
48
+
49
+ describe 'class include' do
50
+ it 'has parameter DSL method' do
51
+ expect(including_class).to respond_to(:parameter)
52
+ end
53
+ end
54
+
55
+ context 'Class is inherited and the module is included' do
56
+ let(:parametrized_class) do
57
+ INCLUDING_MODULE = including_module
58
+
59
+ Class.new(including_class) do
60
+ include INCLUDING_MODULE
61
+ end
62
+ end
63
+
64
+ let(:create_parameters) { { mixed_parameter: 5 } }
65
+
66
+ let(:instance) do
67
+ parametrized_class.new(create_parameters)
68
+ end
69
+
70
+ it 'returns value of module parameter' do
71
+ expect(instance.mixed_parameter).to be == '5'
72
+ end
73
+ end
74
+
75
+ context 'Class is inherited and extended with parameters' do
76
+ let(:parametrized_class) do
77
+ Class.new(including_class) do
78
+ parameter :all_properties_parameter,
79
+ description: 'Made to test the situation when all ' \
80
+ 'properties are specified',
81
+ getter: lambda { |p|
82
+ options[p.name.to_s.sub('parameter', 'option').to_sym]
83
+ },
84
+ transform: ->(_, v) { v + 1 },
85
+ constraint: ->(_, v) { raise "it's > 3!" if v > 3 }
86
+
87
+ parameter :bare_minimum,
88
+ description: '"Do defaults" type of parameter'
89
+ end
90
+ end
91
+
92
+ it 'parameter objects have correct attributes' do
93
+ expect(parametrized_class.get_parameter(:all_properties_parameter).name)
94
+ .to be == :all_properties_parameter
95
+ end
96
+
97
+ describe 'DSL' do
98
+ it 'has parameter DSL method' do
99
+ expect(parametrized_class).to respond_to(:parameter)
100
+ end
101
+ end
102
+
103
+ context 'Instance of the class created' do
104
+ let(:create_parameters) {}
105
+
106
+ let(:instance) do
107
+ parametrized_class.new(create_parameters)
108
+ end
109
+
110
+ it 'contains all_properties_parameter as accessor' do
111
+ expect(instance).to respond_to(:all_properties_parameter)
112
+ end
113
+
114
+ it 'contains bare_minimum as accessor' do
115
+ expect(instance).to respond_to(:bare_minimum)
116
+ end
117
+
118
+ context 'with compliant parameters' do
119
+ let(:create_parameters) do
120
+ {
121
+ all_properties_option: 2,
122
+ bare_minimum: 5
123
+ }
124
+ end
125
+
126
+ it 'returns all_properties_parameter correctly' do
127
+ expect(instance.all_properties_parameter).to be == 3
128
+ end
129
+
130
+ it 'returns bare_minimum correctly' do
131
+ expect(instance.bare_minimum).to be == 5
132
+ end
133
+ end
134
+
135
+ context 'with parameters violating the constraint' do
136
+ let(:create_parameters) do
137
+ {
138
+ all_properties_option: 3,
139
+ bare_minimum: 5
140
+ }
141
+ end
142
+
143
+ it 'raises an exception' do
144
+ expect { instance.all_properties_parameter }.to raise_error RuntimeError
145
+ end
146
+ end
147
+ end
148
+
149
+ context 'Class is inherited and a parameter added' do
150
+ let(:extending_class) do
151
+ Class.new(parametrized_class) do
152
+ parameter :just_addition,
153
+ description: 'Trying to add parameter to the ' \
154
+ 'parent\'s parameter list'
155
+ end
156
+ end
157
+
158
+ %i[just_addition all_properties_parameter bare_minimum].each do |name|
159
+ it "has accessor #{name} inherited from parent" do
160
+ expect(extending_class.method_defined?(name)).to be == true
161
+ end
162
+
163
+ it "has parameter #{name} inherited from parent" do
164
+ expect(extending_class.get_parameter(name).name).to be == name
165
+ end
166
+ end
167
+
168
+ context 'Instance of the class created' do
169
+ let(:create_parameters) do
170
+ {
171
+ all_properties_option: 2,
172
+ bare_minimum: 5,
173
+ just_addition: 'bonus'
174
+ }
175
+ end
176
+
177
+ let(:instance) do
178
+ extending_class.new(create_parameters)
179
+ end
180
+
181
+ {
182
+ all_properties_parameter: 3,
183
+ bare_minimum: 5,
184
+ just_addition: 'bonus'
185
+ }.each_pair do |name, value|
186
+ it "returns #{name} attributes correctly" do
187
+ expect(instance.send(name)).to be == value
188
+ end
189
+ end
190
+ end
191
+
192
+ context 'Class inherited and parameter mixin added' do
193
+ let(:mixing_class) do
194
+ k = Class.new(extending_class)
195
+ k.send(:include, including_module)
196
+ k
197
+ end
198
+
199
+ %i[just_addition all_properties_parameter bare_minimum].each do |name|
200
+ it "has accessor #{name} inherited from parent" do
201
+ expect(mixing_class.method_defined?(name)).to be == true
202
+ end
203
+
204
+ it "has parameter #{name} inherited from parent" do
205
+ expect(mixing_class.get_parameter(name).name).to be == name
206
+ end
207
+ end
208
+
209
+ it 'has accessor mixed_parameter derived from mixin' do
210
+ expect(mixing_class.method_defined?(:mixed_parameter)).to be == true
211
+ end
212
+
213
+ it 'has parameter mixed_parameter derived from mixin' do
214
+ expect(mixing_class.get_parameter(:mixed_parameter).name)
215
+ .to be == :mixed_parameter
216
+ end
217
+ end
218
+ end
219
+
220
+ it 'fails when trying to add existing parameter' do
221
+ expect do
222
+ Class.new(parametrized_class) do
223
+ parameter :bare_minimum, description: 'Something existing'
224
+ end
225
+ end.to raise_error Aws::Templates::ParameterAlreadyExist
226
+ end
227
+
228
+ context 'method is defined' do
229
+ let(:failing_class) do
230
+ Class.new(parametrized_class) do
231
+ def a; end
232
+ end
233
+ end
234
+
235
+ it 'fails when adding a parameter with the same name as a method' do
236
+ expect { failing_class.parameter(:a, description: 'Unexpected') }
237
+ .to raise_error Aws::Templates::ParameterMethodNameConflict
238
+ end
239
+ end
240
+ end
241
+ end
@@ -0,0 +1,6 @@
1
+ require 'simplecov'
2
+
3
+ RSpec.configure do |config|
4
+ config.run_all_when_everything_filtered = true
5
+ config.filter_run :focus
6
+ end