puppet 5.0.1 → 5.1.0
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of puppet might be problematic. Click here for more details.
- checksums.yaml +4 -4
- data/lib/puppet/agent.rb +1 -0
- data/lib/puppet/defaults.rb +1 -1
- data/lib/puppet/functions.rb +6 -7
- data/lib/puppet/functions/all.rb +100 -0
- data/lib/puppet/functions/any.rb +105 -0
- data/lib/puppet/functions/defined.rb +3 -3
- data/lib/puppet/functions/new.rb +2 -1
- data/lib/puppet/functions/reduce.rb +31 -0
- data/lib/puppet/functions/tree_each.rb +200 -0
- data/lib/puppet/module.rb +30 -0
- data/lib/puppet/parser/functions/new.rb +67 -0
- data/lib/puppet/parser/functions/reduce.rb +31 -0
- data/lib/puppet/parser/relationship.rb +2 -2
- data/lib/puppet/parser/resource.rb +39 -10
- data/lib/puppet/parser/scope.rb +1 -1
- data/lib/puppet/pops/evaluator/access_operator.rb +11 -4
- data/lib/puppet/pops/evaluator/collector_transformer.rb +1 -1
- data/lib/puppet/pops/evaluator/evaluator_impl.rb +4 -4
- data/lib/puppet/pops/evaluator/relationship_operator.rb +1 -1
- data/lib/puppet/pops/evaluator/runtime3_converter.rb +3 -3
- data/lib/puppet/pops/evaluator/runtime3_resource_support.rb +1 -1
- data/lib/puppet/pops/loader/module_loaders.rb +1 -1
- data/lib/puppet/pops/loader/static_loader.rb +1 -2
- data/lib/puppet/pops/loaders.rb +1 -2
- data/lib/puppet/pops/lookup/context.rb +1 -1
- data/lib/puppet/pops/lookup/lookup_adapter.rb +2 -1
- data/lib/puppet/pops/model/ast.rb +440 -436
- data/lib/puppet/pops/model/factory.rb +140 -140
- data/lib/puppet/pops/pcore.rb +1 -2
- data/lib/puppet/pops/resource/param.rb +1 -1
- data/lib/puppet/pops/resource/resource_type_impl.rb +1 -1
- data/lib/puppet/pops/serialization/from_data_converter.rb +0 -12
- data/lib/puppet/pops/time/timestamp.rb +29 -17
- data/lib/puppet/pops/types/annotatable.rb +2 -2
- data/lib/puppet/pops/types/annotation.rb +8 -8
- data/lib/puppet/pops/types/class_loader.rb +3 -3
- data/lib/puppet/pops/types/implementation_registry.rb +1 -1
- data/lib/puppet/pops/types/iterable.rb +2 -2
- data/lib/puppet/pops/types/p_binary_type.rb +2 -2
- data/lib/puppet/pops/types/p_init_type.rb +238 -0
- data/lib/puppet/pops/types/p_meta_type.rb +14 -11
- data/lib/puppet/pops/types/p_object_type.rb +15 -15
- data/lib/puppet/pops/types/p_sem_ver_range_type.rb +2 -2
- data/lib/puppet/pops/types/p_sem_ver_type.rb +2 -2
- data/lib/puppet/pops/types/p_sensitive_type.rb +2 -2
- data/lib/puppet/pops/types/p_timespan_type.rb +6 -6
- data/lib/puppet/pops/types/p_timestamp_type.rb +6 -2
- data/lib/puppet/pops/types/p_type_set_type.rb +10 -9
- data/lib/puppet/pops/types/ruby_generator.rb +6 -5
- data/lib/puppet/pops/types/ruby_method.rb +2 -2
- data/lib/puppet/pops/types/string_converter.rb +1 -1
- data/lib/puppet/pops/types/tree_iterators.rb +250 -0
- data/lib/puppet/pops/types/type_calculator.rb +13 -13
- data/lib/puppet/pops/types/type_factory.rb +26 -7
- data/lib/puppet/pops/types/type_formatter.rb +9 -4
- data/lib/puppet/pops/types/type_parser.rb +8 -3
- data/lib/puppet/pops/types/type_set_reference.rb +2 -2
- data/lib/puppet/pops/types/types.rb +168 -109
- data/lib/puppet/provider/package/gem.rb +10 -9
- data/lib/puppet/provider/package/pip.rb +12 -3
- data/lib/puppet/provider/package/yum.rb +9 -1
- data/lib/puppet/resource/capability_finder.rb +30 -11
- data/lib/puppet/type/file.rb +21 -13
- data/lib/puppet/util/execution.rb +67 -14
- data/lib/puppet/util/suidmanager.rb +1 -0
- data/lib/puppet/version.rb +1 -1
- data/locales/puppet.pot +130 -66
- data/man/man5/puppet.conf.5 +1 -1
- data/spec/fixtures/unit/provider/package/yum/yum-check-update-simple.txt +1 -0
- data/spec/integration/parser/collection_spec.rb +40 -1
- data/spec/shared_contexts/types_setup.rb +41 -2
- data/spec/unit/agent_spec.rb +11 -0
- data/spec/unit/file_bucket/dipper_spec.rb +13 -4
- data/spec/unit/functions/all_spec.rb +97 -0
- data/spec/unit/functions/any_spec.rb +109 -0
- data/spec/unit/functions/hiera_spec.rb +5 -0
- data/spec/unit/functions/new_spec.rb +66 -0
- data/spec/unit/functions/tree_each_spec.rb +444 -0
- data/spec/unit/module_spec.rb +29 -0
- data/spec/unit/pops/serialization/serialization_spec.rb +2 -2
- data/spec/unit/pops/serialization/to_from_hr_spec.rb +2 -2
- data/spec/unit/pops/types/iterable_spec.rb +9 -9
- data/spec/unit/pops/types/p_init_type_spec.rb +285 -0
- data/spec/unit/pops/types/p_object_type_spec.rb +8 -8
- data/spec/unit/pops/types/p_sensitive_type_spec.rb +4 -0
- data/spec/unit/pops/types/p_timespan_type_spec.rb +14 -0
- data/spec/unit/pops/types/p_timestamp_type_spec.rb +19 -1
- data/spec/unit/pops/types/p_type_set_type_spec.rb +2 -2
- data/spec/unit/pops/types/ruby_generator_spec.rb +9 -22
- data/spec/unit/pops/types/string_converter_spec.rb +2 -2
- data/spec/unit/pops/types/type_acceptor_spec.rb +2 -2
- data/spec/unit/pops/types/type_calculator_spec.rb +43 -38
- data/spec/unit/pops/types/type_factory_spec.rb +6 -6
- data/spec/unit/pops/types/type_formatter_spec.rb +6 -6
- data/spec/unit/pops/types/types_spec.rb +16 -4
- data/spec/unit/provider/package/gem_spec.rb +6 -6
- data/spec/unit/provider/package/pip_spec.rb +44 -23
- data/spec/unit/provider/package/puppet_gem_spec.rb +1 -1
- data/spec/unit/provider/package/yum_spec.rb +8 -0
- data/spec/unit/resource/capability_finder_spec.rb +4 -5
- data/spec/unit/type/file_spec.rb +19 -14
- data/spec/unit/util/execution_spec.rb +216 -82
- data/tasks/generate_ast_model.rake +10 -2
- metadata +15 -2
@@ -295,7 +295,7 @@ module Serialization
|
|
295
295
|
|
296
296
|
def self.register_ptype(loader, ir)
|
297
297
|
@type = Pcore.create_object_type(loader, ir, DerivedArray, 'DerivedArray', nil, 'values' => Types::PArrayType::DEFAULT)
|
298
|
-
.resolve(
|
298
|
+
.resolve(loader)
|
299
299
|
end
|
300
300
|
|
301
301
|
def initialize(values)
|
@@ -316,7 +316,7 @@ module Serialization
|
|
316
316
|
|
317
317
|
def self.register_ptype(loader, ir)
|
318
318
|
@type = Pcore.create_object_type(loader, ir, DerivedHash, 'DerivedHash', nil, '_pcore_init_hash' => Types::PHashType::DEFAULT)
|
319
|
-
.resolve(
|
319
|
+
.resolve(loader)
|
320
320
|
end
|
321
321
|
|
322
322
|
def initialize(_pcore_init_hash)
|
@@ -321,7 +321,7 @@ module Serialization
|
|
321
321
|
|
322
322
|
def self.register_ptype(loader, ir)
|
323
323
|
@type = Pcore.create_object_type(loader, ir, DerivedArray, 'DerivedArray', nil, 'values' => Types::PArrayType::DEFAULT)
|
324
|
-
.resolve(
|
324
|
+
.resolve(loader)
|
325
325
|
end
|
326
326
|
|
327
327
|
def initialize(values)
|
@@ -342,7 +342,7 @@ module Serialization
|
|
342
342
|
|
343
343
|
def self.register_ptype(loader, ir)
|
344
344
|
@type = Pcore.create_object_type(loader, ir, DerivedHash, 'DerivedHash', nil, '_pcore_init_hash' => Types::PHashType::DEFAULT)
|
345
|
-
.resolve(
|
345
|
+
.resolve(loader)
|
346
346
|
end
|
347
347
|
|
348
348
|
def initialize(_pcore_init_hash)
|
@@ -50,8 +50,8 @@ describe 'The iterable support' do
|
|
50
50
|
PStructType::DEFAULT,
|
51
51
|
PUnitType::DEFAULT
|
52
52
|
]
|
53
|
-
iterable_types <<
|
54
|
-
iterable_types <<
|
53
|
+
iterable_types << PTypeType.new(PIntegerType.new(0, 10))
|
54
|
+
iterable_types << PTypeType.new(PEnumType.new(%w(yes no)))
|
55
55
|
iterable_types << PRuntimeType.new(:ruby, 'Puppet::Pops::Types::Iterator')
|
56
56
|
iterable_types << PVariantType.new(iterable_types.clone)
|
57
57
|
|
@@ -62,7 +62,7 @@ describe 'The iterable support' do
|
|
62
62
|
PCatalogEntryType::DEFAULT,
|
63
63
|
PDefaultType::DEFAULT,
|
64
64
|
PFloatType::DEFAULT,
|
65
|
-
|
65
|
+
PClassType::DEFAULT,
|
66
66
|
PNotUndefType::DEFAULT,
|
67
67
|
PNumericType::DEFAULT,
|
68
68
|
POptionalType::DEFAULT,
|
@@ -72,10 +72,10 @@ describe 'The iterable support' do
|
|
72
72
|
PRuntimeType::DEFAULT,
|
73
73
|
PScalarType::DEFAULT,
|
74
74
|
PScalarDataType::DEFAULT,
|
75
|
-
|
75
|
+
PTypeType::DEFAULT,
|
76
76
|
PUndefType::DEFAULT
|
77
77
|
]
|
78
|
-
not_iterable_types <<
|
78
|
+
not_iterable_types << PTypeType.new(PIntegerType::DEFAULT)
|
79
79
|
not_iterable_types << PVariantType.new([iterable_types[0], not_iterable_types[0]])
|
80
80
|
|
81
81
|
iterable_types.each do |type|
|
@@ -91,19 +91,19 @@ describe 'The iterable support' do
|
|
91
91
|
end
|
92
92
|
|
93
93
|
it "should consider Type[Integer[0,5]] to be assignable to Iterable[Integer[0,5]]" do
|
94
|
-
expect(PIterableType.new(PIntegerType.new(0,5)).assignable?(
|
94
|
+
expect(PIterableType.new(PIntegerType.new(0,5)).assignable?(PTypeType.new(PIntegerType.new(0,5)))).to eq(true)
|
95
95
|
end
|
96
96
|
|
97
97
|
it "should consider Type[Enum[yes,no]] to be assignable to Iterable[Enum[yes,no]]" do
|
98
|
-
expect(PIterableType.new(PEnumType.new(%w(yes no))).assignable?(
|
98
|
+
expect(PIterableType.new(PEnumType.new(%w(yes no))).assignable?(PTypeType.new(PEnumType.new(%w(yes no))))).to eq(true)
|
99
99
|
end
|
100
100
|
|
101
101
|
it "should not consider Type[Enum[ok,fail]] to be assignable to Iterable[Enum[yes,no]]" do
|
102
|
-
expect(PIterableType.new(PEnumType.new(%w(ok fail))).assignable?(
|
102
|
+
expect(PIterableType.new(PEnumType.new(%w(ok fail))).assignable?(PTypeType.new(PEnumType.new(%w(yes no))))).to eq(false)
|
103
103
|
end
|
104
104
|
|
105
105
|
it "should not consider Type[String] to be assignable to Iterable[String]" do
|
106
|
-
expect(PIterableType.new(PStringType::DEFAULT).assignable?(
|
106
|
+
expect(PIterableType.new(PStringType::DEFAULT).assignable?(PTypeType.new(PStringType::DEFAULT))).to eq(false)
|
107
107
|
end
|
108
108
|
end
|
109
109
|
|
@@ -0,0 +1,285 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'puppet/pops'
|
3
|
+
require 'puppet_spec/compiler'
|
4
|
+
|
5
|
+
module Puppet::Pops
|
6
|
+
module Types
|
7
|
+
describe 'The Init Type' do
|
8
|
+
include PuppetSpec::Compiler
|
9
|
+
include_context 'types_setup'
|
10
|
+
|
11
|
+
context 'when used in Puppet expressions' do
|
12
|
+
it 'an unparameterized type can be used' do
|
13
|
+
code = <<-CODE
|
14
|
+
notice(type(Init))
|
15
|
+
CODE
|
16
|
+
expect(eval_and_collect_notices(code)).to eql(['Type[Init]'])
|
17
|
+
end
|
18
|
+
|
19
|
+
it 'a parameterized type can be used' do
|
20
|
+
code = <<-CODE
|
21
|
+
notice(type(Init[Integer]))
|
22
|
+
CODE
|
23
|
+
expect(eval_and_collect_notices(code)).to eql(['Type[Init[Integer]]'])
|
24
|
+
end
|
25
|
+
|
26
|
+
it 'a parameterized type can have additional arguments' do
|
27
|
+
code = <<-CODE
|
28
|
+
notice(type(Init[Integer, 16]))
|
29
|
+
CODE
|
30
|
+
expect(eval_and_collect_notices(code)).to eql(['Type[Init[Integer, 16]]'])
|
31
|
+
end
|
32
|
+
|
33
|
+
(all_types - abstract_types - internal_types).map { |tc| tc::DEFAULT.name }.each do |type_name|
|
34
|
+
it "can be created on a #{type_name}" do
|
35
|
+
code = <<-CODE
|
36
|
+
notice(type(Init[#{type_name}]))
|
37
|
+
CODE
|
38
|
+
expect(eval_and_collect_notices(code)).to eql(["Type[Init[#{type_name}]]"])
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
(abstract_types - internal_types).map { |tc| tc::DEFAULT.name }.each do |type_name|
|
43
|
+
it "cannot be created on a #{type_name}" do
|
44
|
+
code = <<-CODE
|
45
|
+
type(Init[#{type_name}]('x'))
|
46
|
+
CODE
|
47
|
+
expect { eval_and_collect_notices(code) }.to raise_error(/Creation of new instance of type '#{type_name}' is not supported/)
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
it 'an Init[Integer, 16] can create an instance from a String' do
|
52
|
+
code = <<-CODE
|
53
|
+
notice(Init[Integer, 16]('100'))
|
54
|
+
CODE
|
55
|
+
expect(eval_and_collect_notices(code)).to eql(['256'])
|
56
|
+
end
|
57
|
+
|
58
|
+
it "an Init[String,'%x'] can create an instance from an Integer" do
|
59
|
+
code = <<-CODE
|
60
|
+
notice(Init[String,'%x'](128))
|
61
|
+
CODE
|
62
|
+
expect(eval_and_collect_notices(code)).to eql(['80'])
|
63
|
+
end
|
64
|
+
|
65
|
+
it "an Init[String,23] raises an error because no available dispatcher exists" do
|
66
|
+
code = <<-CODE
|
67
|
+
notice(Init[String,23](128))
|
68
|
+
CODE
|
69
|
+
expect { eval_and_collect_notices(code) }.to raise_error(
|
70
|
+
/The type 'Init\[String, 23\]' does not represent a valid set of parameters for String\.new\(\)/)
|
71
|
+
end
|
72
|
+
|
73
|
+
it 'an Init[String] can create an instance from an Integer' do
|
74
|
+
code = <<-CODE
|
75
|
+
notice(Init[String](128))
|
76
|
+
CODE
|
77
|
+
expect(eval_and_collect_notices(code)).to eql(['128'])
|
78
|
+
end
|
79
|
+
|
80
|
+
it 'an Init[String] can create an instance from an array with an Integer' do
|
81
|
+
code = <<-CODE
|
82
|
+
notice(Init[String]([128]))
|
83
|
+
CODE
|
84
|
+
expect(eval_and_collect_notices(code)).to eql(['128'])
|
85
|
+
end
|
86
|
+
|
87
|
+
it 'an Init[String] can create an instance from an array with an Integer and a format' do
|
88
|
+
code = <<-CODE
|
89
|
+
notice(Init[String]([128, '%x']))
|
90
|
+
CODE
|
91
|
+
expect(eval_and_collect_notices(code)).to eql(['80'])
|
92
|
+
end
|
93
|
+
|
94
|
+
it 'an Init[String] can create an instance from an array with an array' do
|
95
|
+
code = <<-CODE
|
96
|
+
notice(Init[String]([[128, '%x']]))
|
97
|
+
CODE
|
98
|
+
expect(eval_and_collect_notices(code)).to eql(["[128, '%x']"])
|
99
|
+
end
|
100
|
+
|
101
|
+
it 'an Init[Binary] can create an instance from a string' do
|
102
|
+
code = <<-CODE
|
103
|
+
notice(Init[Binary]('b25lIHR3byB0aHJlZQ=='))
|
104
|
+
CODE
|
105
|
+
expect(eval_and_collect_notices(code)).to eql(['b25lIHR3byB0aHJlZQ=='])
|
106
|
+
end
|
107
|
+
|
108
|
+
it 'an Init[String] can not create an instance from an Integer and a format unless given as an array argument' do
|
109
|
+
code = <<-CODE
|
110
|
+
notice(Init[String](128, '%x'))
|
111
|
+
CODE
|
112
|
+
expect { eval_and_collect_notices(code) }.to raise_error(/'new_Init' expects 1 argument, got 2/)
|
113
|
+
end
|
114
|
+
|
115
|
+
it 'the array [128] is an instance of Init[String]' do
|
116
|
+
code = <<-CODE
|
117
|
+
notice(assert_type(Init[String], [128]))
|
118
|
+
CODE
|
119
|
+
expect(eval_and_collect_notices(code)).to eql(['[128]'])
|
120
|
+
end
|
121
|
+
|
122
|
+
it 'the value 128 is an instance of Init[String]' do
|
123
|
+
code = <<-CODE
|
124
|
+
notice(assert_type(Init[String], 128))
|
125
|
+
CODE
|
126
|
+
expect(eval_and_collect_notices(code)).to eql(['128'])
|
127
|
+
end
|
128
|
+
|
129
|
+
it "the array [128] is an instance of Init[String]" do
|
130
|
+
code = <<-CODE
|
131
|
+
notice(assert_type(Init[String], [128]))
|
132
|
+
CODE
|
133
|
+
expect(eval_and_collect_notices(code)).to eql(['[128]'])
|
134
|
+
end
|
135
|
+
|
136
|
+
it "the array [128, '%x'] is an instance of Init[String]" do
|
137
|
+
code = <<-CODE
|
138
|
+
notice(assert_type(Init[String], [128, '%x']))
|
139
|
+
CODE
|
140
|
+
expect(eval_and_collect_notices(code)).to eql(['[128, %x]'])
|
141
|
+
end
|
142
|
+
|
143
|
+
it "the array [[128, '%x']] is an instance of Init[String]" do
|
144
|
+
code = <<-CODE
|
145
|
+
notice(assert_type(Init[String], [[128, '%x']]))
|
146
|
+
CODE
|
147
|
+
expect(eval_and_collect_notices(code)).to eql(['[[128, %x]]'])
|
148
|
+
end
|
149
|
+
|
150
|
+
it 'RichData is assignable to Init' do
|
151
|
+
code = <<-CODE
|
152
|
+
notice(Init > RichData)
|
153
|
+
CODE
|
154
|
+
expect(eval_and_collect_notices(code)).to eql(['true'])
|
155
|
+
end
|
156
|
+
|
157
|
+
it 'Runtime is not assignable to Init' do
|
158
|
+
code = <<-CODE
|
159
|
+
notice(Init > Runtime['ruby', 'Time'])
|
160
|
+
CODE
|
161
|
+
expect(eval_and_collect_notices(code)).to eql(['false'])
|
162
|
+
end
|
163
|
+
|
164
|
+
it 'Init is not assignable to RichData' do
|
165
|
+
code = <<-CODE
|
166
|
+
notice(Init < RichData)
|
167
|
+
CODE
|
168
|
+
expect(eval_and_collect_notices(code)).to eql(['false'])
|
169
|
+
end
|
170
|
+
|
171
|
+
it 'Init[T1] is assignable to Init[T2] when T1 is assignable to T2' do
|
172
|
+
code = <<-CODE
|
173
|
+
notice(Init[Integer] < Init[Numeric])
|
174
|
+
notice(Init[Tuple[Integer]] < Init[Array[Integer]])
|
175
|
+
CODE
|
176
|
+
expect(eval_and_collect_notices(code)).to eql(['true', 'true'])
|
177
|
+
end
|
178
|
+
|
179
|
+
it 'Init[T1] is not assignable to Init[T2] unless T1 is assignable to T2' do
|
180
|
+
code = <<-CODE
|
181
|
+
notice(Init[Integer] > Init[Numeric])
|
182
|
+
notice(Init[Tuple[Integer]] > Init[Array[Integer]])
|
183
|
+
CODE
|
184
|
+
expect(eval_and_collect_notices(code)).to eql(['false', 'false'])
|
185
|
+
end
|
186
|
+
|
187
|
+
it 'T is assignable to Init[T]' do
|
188
|
+
code = <<-CODE
|
189
|
+
notice(Integer < Init[Integer])
|
190
|
+
CODE
|
191
|
+
expect(eval_and_collect_notices(code)).to eql(['true'])
|
192
|
+
end
|
193
|
+
|
194
|
+
it 'T1 is assignable to Init[T2] if T2 can be created from instance of T1 is valid' do
|
195
|
+
code = <<-CODE
|
196
|
+
notice(Integer < Init[String])
|
197
|
+
CODE
|
198
|
+
expect(eval_and_collect_notices(code)).to eql(['true'])
|
199
|
+
end
|
200
|
+
|
201
|
+
it 'a RichData value is an instance of Init' do
|
202
|
+
code = <<-CODE
|
203
|
+
notice(
|
204
|
+
String(assert_type(Init, { 'a' => [ 1, 2, Sensitive(3) ], 2 => Timestamp('2014-12-01T13:15:00') }),
|
205
|
+
{ Any => { format => '%s', string_formats => { Any => '%s' }}}))
|
206
|
+
CODE
|
207
|
+
expect(eval_and_collect_notices(code)).to eql(['{a => [1, 2, Sensitive [value redacted]], 2 => 2014-12-01T13:15:00.000000000 UTC}'])
|
208
|
+
end
|
209
|
+
|
210
|
+
it 'an Init[Sensitive[String]] can create an instance from a String' do
|
211
|
+
code = <<-CODE
|
212
|
+
notice(Init[Sensitive[String]]('256'))
|
213
|
+
CODE
|
214
|
+
expect(eval_and_collect_notices(code)).to eql(['Sensitive [value redacted]'])
|
215
|
+
end
|
216
|
+
|
217
|
+
it 'an Init[Type] can create an instance from a String' do
|
218
|
+
code = <<-CODE
|
219
|
+
notice(Init[Type]('Integer[2,3]'))
|
220
|
+
CODE
|
221
|
+
expect(eval_and_collect_notices(code)).to eql(['Integer[2, 3]'])
|
222
|
+
end
|
223
|
+
|
224
|
+
it 'an Init[Type[Numeric]] can not create an unassignable type from a String' do
|
225
|
+
code = <<-CODE
|
226
|
+
notice(Init[Type[Numeric]]('String'))
|
227
|
+
CODE
|
228
|
+
expect { eval_and_collect_notices(code) }.to raise_error(
|
229
|
+
/Converted value from Type\[Numeric\]\.new\(\) has wrong type, expects a Type\[Numeric\] value, got Type\[String\]/)
|
230
|
+
end
|
231
|
+
|
232
|
+
it 'an Init with a custom object type can create an instance from a Hash' do
|
233
|
+
code = <<-CODE
|
234
|
+
type MyType = Object[{
|
235
|
+
attributes => {
|
236
|
+
granularity => String,
|
237
|
+
price => String,
|
238
|
+
category => Integer
|
239
|
+
}
|
240
|
+
}]
|
241
|
+
notice(Init[MyType]({ granularity => 'fine', price => '$10', category => 23 }))
|
242
|
+
CODE
|
243
|
+
expect(eval_and_collect_notices(code)).to eql(["MyType({'granularity' => 'fine', 'price' => '$10', 'category' => 23})"])
|
244
|
+
end
|
245
|
+
|
246
|
+
it 'an Init with a custom object type and additional parameters can create an instance from a value' do
|
247
|
+
code = <<-CODE
|
248
|
+
type MyType = Object[{
|
249
|
+
attributes => {
|
250
|
+
granularity => String,
|
251
|
+
price => String,
|
252
|
+
category => Integer
|
253
|
+
}
|
254
|
+
}]
|
255
|
+
notice(Init[MyType,'$5',20]('coarse'))
|
256
|
+
CODE
|
257
|
+
expect(eval_and_collect_notices(code)).to eql(["MyType({'granularity' => 'coarse', 'price' => '$5', 'category' => 20})"])
|
258
|
+
end
|
259
|
+
|
260
|
+
it 'an Init with a custom object with one Array parameter, can be created from an Array' do
|
261
|
+
code = <<-CODE
|
262
|
+
type MyType = Object[{
|
263
|
+
attributes => { array => Array[String] }
|
264
|
+
}]
|
265
|
+
notice(Init[MyType](['a']))
|
266
|
+
CODE
|
267
|
+
expect(eval_and_collect_notices(code)).to eql(["MyType({'array' => ['a']})"])
|
268
|
+
end
|
269
|
+
|
270
|
+
it 'an Init type can be used recursively' do
|
271
|
+
# Even if it doesn't make sense, it should not crash
|
272
|
+
code = <<-CODE
|
273
|
+
type One = Object[{
|
274
|
+
attributes => {
|
275
|
+
init_one => Variant[Init[One],String]
|
276
|
+
}
|
277
|
+
}]
|
278
|
+
notice(Init[One]('w'))
|
279
|
+
CODE
|
280
|
+
expect(eval_and_collect_notices(code)).to eql(["One({'init_one' => 'w'})"])
|
281
|
+
end
|
282
|
+
end
|
283
|
+
end
|
284
|
+
end
|
285
|
+
end
|
@@ -26,7 +26,7 @@ describe 'The Object Type' do
|
|
26
26
|
|
27
27
|
def parse_object(name, body_string)
|
28
28
|
type_object_t(name, body_string)
|
29
|
-
parser.parse(name, loader)
|
29
|
+
parser.parse(name, loader).resolve(loader)
|
30
30
|
end
|
31
31
|
|
32
32
|
context 'when dealing with attributes' do
|
@@ -597,7 +597,7 @@ describe 'The Object Type' do
|
|
597
597
|
end
|
598
598
|
end
|
599
599
|
|
600
|
-
context 'when producing an
|
600
|
+
context 'when producing an init_hash_type' do
|
601
601
|
it 'produces a struct of all attributes that are not derived or constant' do
|
602
602
|
t = parse_object('MyObject', <<-OBJECT)
|
603
603
|
attributes => {
|
@@ -607,7 +607,7 @@ describe 'The Object Type' do
|
|
607
607
|
d => { type => Integer, kind => constant, value => 4 }
|
608
608
|
}
|
609
609
|
OBJECT
|
610
|
-
expect(t.
|
610
|
+
expect(t.init_hash_type).to eql(factory.struct({
|
611
611
|
'a' => factory.integer,
|
612
612
|
'b' => factory.integer
|
613
613
|
}))
|
@@ -620,7 +620,7 @@ describe 'The Object Type' do
|
|
620
620
|
b => { type => Integer, value => 4 }
|
621
621
|
}
|
622
622
|
OBJECT
|
623
|
-
expect(t.
|
623
|
+
expect(t.init_hash_type).to eql(factory.struct({
|
624
624
|
'a' => factory.integer,
|
625
625
|
factory.optional('b') => factory.integer
|
626
626
|
}))
|
@@ -638,8 +638,8 @@ describe 'The Object Type' do
|
|
638
638
|
b => { type => Integer }
|
639
639
|
}
|
640
640
|
OBJECT
|
641
|
-
expect(t1.
|
642
|
-
expect(t2.
|
641
|
+
expect(t1.init_hash_type).to eql(factory.struct({ 'a' => factory.integer }))
|
642
|
+
expect(t2.init_hash_type).to eql(factory.struct({ 'a' => factory.integer, 'b' => factory.integer }))
|
643
643
|
end
|
644
644
|
|
645
645
|
it 'produces a struct that reflects overrides made in derived type' do
|
@@ -655,8 +655,8 @@ describe 'The Object Type' do
|
|
655
655
|
b => { type => Integer, override => true, value => 5 }
|
656
656
|
}
|
657
657
|
OBJECT
|
658
|
-
expect(t1.
|
659
|
-
expect(t2.
|
658
|
+
expect(t1.init_hash_type).to eql(factory.struct({ 'a' => factory.integer, 'b' => factory.integer }))
|
659
|
+
expect(t2.init_hash_type).to eql(factory.struct({ 'a' => factory.integer, factory.optional('b') => factory.integer }))
|
660
660
|
end
|
661
661
|
end
|
662
662
|
|
@@ -20,6 +20,10 @@ describe 'Sensitive Type' do
|
|
20
20
|
expect(t.type).to eql(PIntegerType::DEFAULT)
|
21
21
|
end
|
22
22
|
|
23
|
+
it 'string representation of unparameterized instance is "Sensitive"' do
|
24
|
+
expect(PSensitiveType::DEFAULT.to_s).to eql('Sensitive')
|
25
|
+
end
|
26
|
+
|
23
27
|
context 'when used in Puppet expressions' do
|
24
28
|
it 'is equal to itself only' do
|
25
29
|
code = <<-CODE
|
@@ -24,6 +24,20 @@ describe 'Timespan type' do
|
|
24
24
|
expect(eval_and_collect_notices(code)).to eq(%w(true true false false))
|
25
25
|
end
|
26
26
|
|
27
|
+
it 'does not consider an Integer to be an instance' do
|
28
|
+
code = <<-CODE
|
29
|
+
notice(assert_type(Timespan, 1234))
|
30
|
+
CODE
|
31
|
+
expect { eval_and_collect_notices(code) }.to raise_error(/expects a Timespan value, got Integer/)
|
32
|
+
end
|
33
|
+
|
34
|
+
it 'does not consider a Float to be an instance' do
|
35
|
+
code = <<-CODE
|
36
|
+
notice(assert_type(Timespan, 1.234))
|
37
|
+
CODE
|
38
|
+
expect { eval_and_collect_notices(code) }.to raise_error(/expects a Timespan value, got Float/)
|
39
|
+
end
|
40
|
+
|
27
41
|
context "when parameterized" do
|
28
42
|
it 'is equal other types with the same parameterization' do
|
29
43
|
code = <<-CODE
|