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,115 @@
1
+ require 'spec_helper'
2
+ require 'aws/templates/utils/contextualized'
3
+ require 'aws/templates/utils/options'
4
+
5
+ describe Aws::Templates::Utils::Contextualized do
6
+ let(:including_class) do
7
+ Class.new do
8
+ include Aws::Templates::Utils::Contextualized
9
+
10
+ contextualize ->(opts, _) { opts.dup }
11
+ end
12
+ end
13
+
14
+ let(:including_module) do
15
+ Module.new do
16
+ include Aws::Templates::Utils::Contextualized
17
+
18
+ contextualize lambda { |_, memo|
19
+ memo.delete(:z)
20
+ memo
21
+ }
22
+ end
23
+ end
24
+
25
+ describe 'module include' do
26
+ it 'has filter DSL method' do
27
+ expect(including_module).to respond_to(:contextualize)
28
+ end
29
+ end
30
+
31
+ describe 'class include' do
32
+ it 'has parameter DSL method' do
33
+ expect(including_class).to respond_to(:contextualize)
34
+ end
35
+ end
36
+
37
+ context 'Class is inherited and the module is included' do
38
+ let(:parametrized_class) do
39
+ klass = Class.new(including_class)
40
+ klass.send(:include, including_module)
41
+ klass
42
+ end
43
+
44
+ let(:instance) { parametrized_class.new }
45
+
46
+ let(:options) { Aws::Templates::Utils::Options.new(a: 5, z: 10) }
47
+
48
+ it 'returns properly filtered options' do
49
+ expect(options.filter(&instance.context).to_hash).to be == { a: 5 }
50
+ end
51
+ end
52
+
53
+ context 'Class is inherited and extended with filters' do
54
+ let(:parametrized_class) do
55
+ Class.new(including_class) do
56
+ contextualize lambda { |_, memo|
57
+ memo.delete(:r)
58
+ memo
59
+ }
60
+
61
+ contextualize lambda { |_, memo|
62
+ memo[:x] = memo[:a] + 1
63
+ memo
64
+ }
65
+ end
66
+ end
67
+
68
+ let(:options) { Aws::Templates::Utils::Options.new(a: 3, r: 5, z: 7) }
69
+
70
+ describe 'DSL' do
71
+ it 'has filter DSL method' do
72
+ expect(parametrized_class).to respond_to(:contextualize)
73
+ end
74
+ end
75
+
76
+ context 'Instance of the class created' do
77
+ let(:instance) { parametrized_class.new }
78
+
79
+ it 'filters it according to specified parameters' do
80
+ expect(options.filter(&instance.context).to_hash).to be == { a: 3, z: 7, x: 4 }
81
+ end
82
+ end
83
+
84
+ context 'Class is inherited and a filter added' do
85
+ let(:extending_class) do
86
+ Class.new(parametrized_class) do
87
+ contextualize lambda { |_, memo|
88
+ memo[:w] = memo[:z] + memo[:x]
89
+ memo
90
+ }
91
+ end
92
+ end
93
+
94
+ let(:instance) { extending_class.new }
95
+
96
+ it 'filters it according to specified parameters' do
97
+ expect(options.filter(&instance.context).to_hash).to be == { a: 3, z: 7, x: 4, w: 11 }
98
+ end
99
+
100
+ context 'Class inherited and a filtered mixin added' do
101
+ let(:mixing_class) do
102
+ k = Class.new(extending_class)
103
+ k.send(:include, including_module)
104
+ k
105
+ end
106
+
107
+ let(:instance) { mixing_class.new }
108
+
109
+ it 'filters it according to specified parameters' do
110
+ expect(options.filter(&instance.context).to_hash).to be == { a: 3, x: 4, w: 11 }
111
+ end
112
+ end
113
+ end
114
+ end
115
+ end
@@ -0,0 +1,52 @@
1
+ require 'spec_helper'
2
+ require 'aws/templates/utils/late_bound'
3
+
4
+ describe Aws::Templates::Utils::LateBound do
5
+ let(:including_class) do
6
+ Class.new do
7
+ include Aws::Templates::Utils::LateBound
8
+ end
9
+ end
10
+
11
+ let(:instance) { including_class.new }
12
+
13
+ describe 'DSL' do
14
+ it 'has parameter DSL class-level method' do
15
+ expect(including_class).to respond_to(:reference)
16
+ end
17
+
18
+ it 'has parameter DSL instance-level method' do
19
+ expect(including_class.new).to respond_to(:reference)
20
+ end
21
+ end
22
+
23
+ describe 'behavior' do
24
+ context 'class' do
25
+ let(:reference) { including_class.reference(%i[a b c], explosive: true) }
26
+
27
+ let(:evaluated) { instance.instance_exec(&reference) }
28
+
29
+ it 'creates proc for reference' do
30
+ expect(reference).to be_a Proc
31
+ end
32
+
33
+ it 'is evaluated into normal reference' do
34
+ expect(evaluated).to be_a Aws::Templates::Utils::LateBound::Reference
35
+ end
36
+
37
+ it 'contains assigned attributes' do
38
+ expect([evaluated.path, evaluated.arguments, evaluated.instance])
39
+ .to be == [%i[a b c], [{ explosive: true }], instance]
40
+ end
41
+ end
42
+
43
+ context 'instance' do
44
+ let(:reference) { instance.reference(%i[a b c], explosive: true) }
45
+
46
+ it 'is evaluated into normal reference' do
47
+ expect([reference.path, reference.arguments, reference.instance])
48
+ .to be == [%i[a b c], [{ explosive: true }], instance]
49
+ end
50
+ end
51
+ end
52
+ end
@@ -0,0 +1,67 @@
1
+ require 'spec_helper'
2
+ require 'aws/templates/utils/options'
3
+
4
+ describe Aws::Templates::Utils::Options do
5
+ let(:options) do
6
+ described_class.new(
7
+ a: 1,
8
+ b: { c: 2 },
9
+ d: { c: { z: 3 } },
10
+ :* => { c: { :* => 5 } }
11
+ )
12
+ end
13
+
14
+ describe 'merge' do
15
+ let(:merged_options) do
16
+ options.merge(a: 12, b: { w: 30 }, d: { c: { z: 34 } })
17
+ end
18
+
19
+ let(:result) do
20
+ {
21
+ a: 12,
22
+ b: { c: 2, w: 30 },
23
+ d: { c: { z: 34 } },
24
+ :* => { c: { :* => 5 } }
25
+ }
26
+ end
27
+
28
+ it 'has correct class' do
29
+ expect(merged_options).to be_a_kind_of(described_class)
30
+ end
31
+
32
+ it 'merges according to the algorithm' do
33
+ expect(merged_options.to_hash).to be == result
34
+ end
35
+ end
36
+
37
+ describe 'lookup' do
38
+ it 'returns value when simple path is specified' do
39
+ expect(options[:b, :c]).to be == 2
40
+ end
41
+
42
+ it 'return nil when value is not found' do
43
+ expect(options[:b, :d, :z]).to be_nil
44
+ end
45
+
46
+ it 'wildcard lookup works' do
47
+ expect(options[:q, :c, :e]).to be == 5
48
+ end
49
+ end
50
+
51
+ describe 'assignment' do
52
+ it 'existing path assignment works' do
53
+ options[:b, :c] = 3
54
+ expect(options[:b, :c]).to be == 3
55
+ end
56
+
57
+ it 'new path assignment works' do
58
+ options[:b, :z, :y, :d] = 10
59
+ expect(options[:b, :z, :y, :d]).to be == 10
60
+ end
61
+
62
+ it 'throws an exception when value is not hash' do
63
+ options[:b, :c, :y, :d] = 13
64
+ expect(options[:b, :c, :y, :d]).to be == 13
65
+ end
66
+ end
67
+ end
@@ -0,0 +1,175 @@
1
+ require 'spec_helper'
2
+ require 'aws/templates/utils/parametrized'
3
+ require 'aws/templates/utils/parametrized/constraints'
4
+ require 'aws/templates/utils/parametrized/getters'
5
+
6
+ module Constraints
7
+ include Aws::Templates::Utils::Parametrized
8
+ end
9
+
10
+ describe Aws::Templates::Utils::Parametrized::Constraint do
11
+ let(:constraint) {}
12
+
13
+ let(:parametrized_class) do
14
+ Class.new do
15
+ include Aws::Templates::Utils::Parametrized
16
+
17
+ attr_reader :options
18
+
19
+ def self.getter
20
+ as_is
21
+ end
22
+
23
+ def initialize(options)
24
+ @options = options
25
+ end
26
+ end
27
+ end
28
+
29
+ let(:test_class) do
30
+ k = Class.new(parametrized_class)
31
+ k.parameter(:something, constraint: constraint)
32
+ k
33
+ end
34
+
35
+ describe 'not_nil' do
36
+ let(:constraint) { Constraints.not_nil }
37
+
38
+ it 'passes when non-nil value is specified' do
39
+ expect(test_class.new(something: 1).something).to be == 1
40
+ end
41
+
42
+ it 'throws error when parameter is not specified' do
43
+ expect { test_class.new(something_else: 1).something }
44
+ .to raise_error Aws::Templates::ParameterValueInvalid
45
+ end
46
+ end
47
+
48
+ describe 'enum works as expected' do
49
+ let(:constraint) { Constraints.enum(1, 2, 3) }
50
+
51
+ it 'passes when a value from the list is specifed' do
52
+ expect(test_class.new(something: 2).something).to be == 2
53
+ end
54
+
55
+ it 'passes when value is not specified' do
56
+ expect(test_class.new(something_else: 2).something).to be_nil
57
+ end
58
+
59
+ it 'throws an error when a value is specified which is not a member of the enumeration' do
60
+ expect { test_class.new(something: 5).something }
61
+ .to raise_error Aws::Templates::ParameterValueInvalid
62
+ end
63
+ end
64
+
65
+ describe 'all_of' do
66
+ let(:constraint) { Constraints.all_of(Constraints.not_nil, Constraints.enum(1, 2, 3)) }
67
+
68
+ it 'passes if all constraints are met' do
69
+ expect(test_class.new(something: 2).something).to be == 2
70
+ end
71
+
72
+ it 'throws an error if one of the constraints are failed (not_nil)' do
73
+ expect { test_class.new(something_else: 2).something }
74
+ .to raise_error Aws::Templates::ParameterValueInvalid
75
+ end
76
+
77
+ it 'throws an error if one of the constraints are failed (enum)' do
78
+ expect { test_class.new(something: 5).something }
79
+ .to raise_error Aws::Templates::ParameterValueInvalid
80
+ end
81
+ end
82
+
83
+ describe 'requires' do
84
+ let(:test_class) do
85
+ Class.new(parametrized_class) do
86
+ parameter :something, constraint: requires(:requirement)
87
+ parameter :requirement, description: 'Nothing'
88
+ end
89
+ end
90
+
91
+ it 'passes when requirement is satisfied' do
92
+ expect(test_class.new(something: 2, requirement: 1).something).to be == 2
93
+ end
94
+
95
+ it 'passes if value is nil so no requirements are enforced' do
96
+ expect(test_class.new({}).something).to be_nil
97
+ end
98
+
99
+ it 'throws an error when requirement is not satisfied' do
100
+ expect { test_class.new(something: 5).something }
101
+ .to raise_error Aws::Templates::ParameterValueInvalid
102
+ end
103
+ end
104
+
105
+ describe 'depends_on_value' do
106
+ let(:test_class) do
107
+ Class.new(parametrized_class) do
108
+ parameter :something,
109
+ constraint: depends_on_value(
110
+ requirement: requires(:requirement),
111
+ condition: requires(:condition)
112
+ )
113
+ parameter :requirement, description: 'Nothing'
114
+ parameter :condition, description: 'Nothing'
115
+ end
116
+ end
117
+
118
+ it 'passes when nil' do
119
+ expect(test_class.new({}).something).to be_nil
120
+ end
121
+
122
+ it 'passes when value is not one of the conditions' do
123
+ expect(test_class.new(something: 2).something).to be == 2
124
+ end
125
+
126
+ it 'passes when conditional constraint is met' do
127
+ expect(test_class.new(something: :condition, condition: 2).something)
128
+ .to be == :condition
129
+ end
130
+
131
+ it 'throws an error when conditional constraint is not met' do
132
+ expect { test_class.new(something: :condition, requirement: 2).something }
133
+ .to raise_error Aws::Templates::ParameterValueInvalid
134
+ end
135
+
136
+ it 'passes when other conditional constraint is met' do
137
+ expect(test_class.new(something: :requirement, requirement: 2).something)
138
+ .to be == :requirement
139
+ end
140
+ end
141
+
142
+ describe 'satisfies' do
143
+ let(:constraint) { Constraints.satisfies('some interesting case') { |v| v > 3 } }
144
+
145
+ it 'passes when nil' do
146
+ expect(test_class.new({}).something).to be_nil
147
+ end
148
+
149
+ it 'passes when condition is satisfied' do
150
+ expect(test_class.new(something: 4).something).to be == 4
151
+ end
152
+
153
+ it 'throws an error when condition is not satisfied' do
154
+ expect { test_class.new(something: 1).something }
155
+ .to raise_error Aws::Templates::ParameterValueInvalid
156
+ end
157
+ end
158
+
159
+ describe 'matches' do
160
+ let(:constraint) { Constraints.matches('[Tt]$') }
161
+
162
+ it 'passes when nil' do
163
+ expect(test_class.new({}).something).to be_nil
164
+ end
165
+
166
+ it 'passes when condition is satisfied' do
167
+ expect(test_class.new(something: 'rest').something).to be == 'rest'
168
+ end
169
+
170
+ it 'throws an error when condition is not satisfied' do
171
+ expect { test_class.new(something: 'rooster').something }
172
+ .to raise_error Aws::Templates::ParameterValueInvalid
173
+ end
174
+ end
175
+ end
@@ -0,0 +1,139 @@
1
+ require 'spec_helper'
2
+ require 'aws/templates/utils/parametrized'
3
+ require 'aws/templates/utils/parametrized/getters'
4
+
5
+ module Getters
6
+ include Aws::Templates::Utils::Parametrized
7
+ end
8
+
9
+ describe Aws::Templates::Utils::Parametrized::Getter do
10
+ let(:parametrized_class) do
11
+ Class.new do
12
+ include Aws::Templates::Utils::Parametrized
13
+
14
+ attr_reader :options
15
+
16
+ def initialize(options)
17
+ @options = options
18
+ end
19
+ end
20
+ end
21
+
22
+ let(:options_hash) {}
23
+
24
+ let(:getter) {}
25
+
26
+ let(:test_class) do
27
+ k = Class.new(parametrized_class)
28
+ k.parameter(:something, getter: getter)
29
+ k
30
+ end
31
+
32
+ let(:instance) { test_class.new(options_hash) }
33
+
34
+ describe 'as_instance_variable' do
35
+ let(:parametrized_class) do
36
+ Class.new do
37
+ include Aws::Templates::Utils::Parametrized
38
+
39
+ def initialize(something)
40
+ @something = something
41
+ end
42
+ end
43
+ end
44
+
45
+ let(:options_hash) { 'a' }
46
+
47
+ let(:getter) { Getters.as_instance_variable }
48
+
49
+ it 'returns the value from hash by parameter name' do
50
+ expect(instance.something).to be == 'a'
51
+ end
52
+ end
53
+
54
+ describe 'as_is' do
55
+ let(:options_hash) { { something: 'a' } }
56
+
57
+ let(:getter) { Getters.as_is }
58
+
59
+ it 'returns the value from hash by parameter name' do
60
+ expect(instance.something).to be == 'a'
61
+ end
62
+ end
63
+
64
+ describe 'path' do
65
+ let(:options_hash) do
66
+ hash = { object: { something: 'a' } }
67
+
68
+ class << hash
69
+ def [](*path)
70
+ if path.size == 1
71
+ super(path[0])
72
+ else
73
+ path.inject(self) { |acc, elem| acc[elem] }
74
+ end
75
+ end
76
+ end
77
+
78
+ hash
79
+ end
80
+
81
+ context 'static path is specified' do
82
+ let(:getter) { Getters.path(:object, :something) }
83
+
84
+ it 'returns value correctly' do
85
+ expect(instance.something).to be == 'a'
86
+ end
87
+ end
88
+
89
+ context 'dynamic path is specified' do
90
+ let(:getter) { Getters.path { %i[object something] } }
91
+
92
+ it 'returns value correctly' do
93
+ expect(instance.something).to be == 'a'
94
+ end
95
+ end
96
+ end
97
+
98
+ describe 'value' do
99
+ let(:options_hash) { { something: 3 } }
100
+
101
+ context 'static value is specified' do
102
+ let(:getter) { Getters.value(1) }
103
+
104
+ it 'returns value correctly' do
105
+ expect(instance.something).to be == 1
106
+ end
107
+ end
108
+
109
+ context 'dynamic calculation is specified' do
110
+ let(:getter) { Getters.value { options[:something] + 2 } }
111
+
112
+ it 'returns value correctly' do
113
+ expect(instance.something).to be == 5
114
+ end
115
+ end
116
+ end
117
+
118
+ describe 'one_of' do
119
+ let(:getter) do
120
+ Getters.one_of(->(p) { options[p.name] }, ->(_) { options[:default] })
121
+ end
122
+
123
+ context 'first option value is specified' do
124
+ let(:options_hash) { { something: 'a' } }
125
+
126
+ it 'returns the value' do
127
+ expect(instance.something).to be == 'a'
128
+ end
129
+ end
130
+
131
+ context 'another options value is specified' do
132
+ let(:options_hash) { { default: 'a' } }
133
+
134
+ it 'returns the value' do
135
+ expect(instance.something).to be == 'a'
136
+ end
137
+ end
138
+ end
139
+ end