puppet 3.7.5-x64-mingw32 → 3.8.1-x64-mingw32
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/ext/build_defaults.yaml +5 -5
- data/lib/hiera/puppet_function.rb +15 -4
- data/lib/puppet.rb +5 -2
- data/lib/puppet/application/agent.rb +5 -0
- data/lib/puppet/application/apply.rb +5 -0
- data/lib/puppet/application/device.rb +8 -3
- data/lib/puppet/application/master.rb +5 -0
- data/lib/puppet/defaults.rb +8 -0
- data/lib/puppet/error.rb +27 -1
- data/lib/puppet/file_system.rb +13 -0
- data/lib/puppet/file_system/file19windows.rb +8 -0
- data/lib/puppet/file_system/file_impl.rb +4 -0
- data/lib/puppet/file_system/memory_impl.rb +4 -0
- data/lib/puppet/functions.rb +25 -3
- data/lib/puppet/functions/defined.rb +130 -0
- data/lib/puppet/functions/hiera_include.rb +1 -1
- data/lib/puppet/node/environment.rb +4 -0
- data/lib/puppet/parser/compiler.rb +5 -2
- data/lib/puppet/parser/functions/defined.rb +26 -1
- data/lib/puppet/parser/functions/file.rb +3 -1
- data/lib/puppet/parser/templatewrapper.rb +2 -1
- data/lib/puppet/pops.rb +5 -0
- data/lib/puppet/pops/evaluator/access_operator.rb +25 -5
- data/lib/puppet/pops/evaluator/collector_transformer.rb +1 -11
- data/lib/puppet/pops/evaluator/compare_operator.rb +43 -0
- data/lib/puppet/pops/evaluator/evaluator_impl.rb +43 -28
- data/lib/puppet/pops/evaluator/runtime3_support.rb +9 -5
- data/lib/puppet/pops/functions/dispatch.rb +6 -1
- data/lib/puppet/pops/issue_reporter.rb +42 -16
- data/lib/puppet/pops/issues.rb +96 -0
- data/lib/puppet/pops/loader/module_loaders.rb +3 -1
- data/lib/puppet/pops/loaders.rb +6 -4
- data/lib/puppet/pops/migration/migration_checker.rb +45 -0
- data/lib/puppet/pops/model/factory.rb +1 -1
- data/lib/puppet/pops/model/model_meta.rb +1 -1
- data/lib/puppet/pops/parser/egrammar.ra +1 -1
- data/lib/puppet/pops/parser/eparser.rb +1 -1
- data/lib/puppet/pops/parser/epp_support.rb +18 -9
- data/lib/puppet/pops/parser/evaluating_parser.rb +7 -1
- data/lib/puppet/pops/parser/heredoc_support.rb +12 -11
- data/lib/puppet/pops/parser/interpolation_support.rb +7 -1
- data/lib/puppet/pops/parser/lexer2.rb +8 -8
- data/lib/puppet/pops/parser/lexer_support.rb +46 -20
- data/lib/puppet/pops/parser/parser_support.rb +11 -14
- data/lib/puppet/pops/parser/slurp_support.rb +22 -6
- data/lib/puppet/pops/types/type_calculator.rb +156 -55
- data/lib/puppet/pops/types/type_factory.rb +67 -14
- data/lib/puppet/pops/types/type_parser.rb +22 -13
- data/lib/puppet/pops/types/types.rb +21 -3
- data/lib/puppet/pops/types/types_meta.rb +13 -2
- data/lib/puppet/pops/validation.rb +25 -2
- data/lib/puppet/pops/validation/checker4_0.rb +25 -5
- data/lib/puppet/provider/group/windows_adsi.rb +18 -6
- data/lib/puppet/provider/mount/parsed.rb +145 -2
- data/lib/puppet/provider/package/pip.rb +4 -5
- data/lib/puppet/provider/package/zypper.rb +17 -7
- data/lib/puppet/provider/scheduled_task/win32_taskscheduler.rb +35 -10
- data/lib/puppet/provider/service/init.rb +7 -0
- data/lib/puppet/provider/user/windows_adsi.rb +8 -1
- data/lib/puppet/provider/zpool/zpool.rb +7 -2
- data/lib/puppet/resource.rb +1 -1
- data/lib/puppet/type/group.rb +1 -1
- data/lib/puppet/type/mount.rb +14 -3
- data/lib/puppet/type/scheduled_task.rb +21 -6
- data/lib/puppet/util/log.rb +50 -8
- data/lib/puppet/util/log/destinations.rb +23 -2
- data/lib/puppet/util/logging.rb +37 -1
- data/lib/puppet/util/windows/adsi.rb +36 -11
- data/lib/puppet/version.rb +1 -1
- data/spec/fixtures/unit/provider/mount/parsed/aix.filesystems +93 -85
- data/spec/fixtures/unit/provider/mount/parsed/aix.mount +11 -7
- data/spec/integration/parser/collector_spec.rb +7 -0
- data/spec/integration/parser/future_compiler_spec.rb +9 -0
- data/spec/integration/parser/resource_expressions_spec.rb +3 -0
- data/spec/unit/file_system_spec.rb +38 -0
- data/spec/unit/functions/defined_spec.rb +291 -0
- data/spec/unit/functions/hiera_spec.rb +8 -6
- data/spec/unit/functions4_spec.rb +97 -2
- data/spec/unit/parser/functions/file_spec.rb +8 -2
- data/spec/unit/parser/functions/template_spec.rb +1 -1
- data/spec/unit/parser/templatewrapper_spec.rb +1 -1
- data/spec/unit/pops/evaluator/access_ops_spec.rb +19 -0
- data/spec/unit/pops/evaluator/evaluating_parser_spec.rb +61 -8
- data/spec/unit/pops/issues_spec.rb +16 -16
- data/spec/unit/pops/loaders/module_loaders_spec.rb +5 -0
- data/spec/unit/pops/migration_spec.rb +180 -0
- data/spec/unit/pops/parser/lexer2_spec.rb +152 -1
- data/spec/unit/pops/parser/parse_heredoc_spec.rb +26 -0
- data/spec/unit/pops/transformer/transform_calls_spec.rb +1 -1
- data/spec/unit/pops/types/type_calculator_spec.rb +204 -11
- data/spec/unit/pops/validation_spec.rb +66 -0
- data/spec/unit/provider/group/windows_adsi_spec.rb +65 -1
- data/spec/unit/provider/mount/parsed_spec.rb +31 -5
- data/spec/unit/provider/package/pip_spec.rb +19 -7
- data/spec/unit/provider/package/zypper_spec.rb +25 -14
- data/spec/unit/provider/scheduled_task/win32_taskscheduler_spec.rb +312 -70
- data/spec/unit/provider/service/base_spec.rb +42 -31
- data/spec/unit/provider/service/freebsd_spec.rb +1 -0
- data/spec/unit/provider/service/gentoo_spec.rb +1 -0
- data/spec/unit/provider/service/init_spec.rb +18 -0
- data/spec/unit/provider/service/openbsd_spec.rb +1 -0
- data/spec/unit/provider/service/redhat_spec.rb +1 -0
- data/spec/unit/provider/user/windows_adsi_spec.rb +21 -0
- data/spec/unit/provider/zpool/zpool_spec.rb +47 -10
- data/spec/unit/util/log_spec.rb +113 -0
- data/spec/unit/util/windows/adsi_spec.rb +106 -26
- metadata +10 -2
@@ -234,6 +234,19 @@ describe 'Lexer2' do
|
|
234
234
|
'"a${y::_x}"' => [[:DQPRE, 'a', {:line => 1, :pos=>1, :length=>4 }],
|
235
235
|
[:VARIABLE, 'y::_x', {:line => 1, :pos=>5, :length=>5 }],
|
236
236
|
[:DQPOST, '', {:line => 1, :pos=>11, :length=>1 }]],
|
237
|
+
|
238
|
+
'"a${_x[1]}"' => [[:DQPRE, 'a', {:line => 1, :pos=>1, :length=>4 }],
|
239
|
+
[:VARIABLE, '_x', {:line => 1, :pos=>5, :length=>2 }],
|
240
|
+
[:LBRACK, '[', {:line => 1, :pos=>7, :length=>1 }],
|
241
|
+
[:NUMBER, '1', {:line => 1, :pos=>8, :length=>1 }],
|
242
|
+
[:RBRACK, ']', {:line => 1, :pos=>9, :length=>1 }],
|
243
|
+
[:DQPOST, '', {:line => 1, :pos=>11, :length=>1 }]],
|
244
|
+
|
245
|
+
'"a${_x.foo}"'=> [[:DQPRE, 'a', {:line => 1, :pos=>1, :length=>4 }],
|
246
|
+
[:VARIABLE, '_x', {:line => 1, :pos=>5, :length=>2 }],
|
247
|
+
[:DOT, '.', {:line => 1, :pos=>7, :length=>1 }],
|
248
|
+
[:NAME, 'foo', {:line => 1, :pos=>8, :length=>3 }],
|
249
|
+
[:DQPOST, '', {:line => 1, :pos=>12, :length=>1 }]],
|
237
250
|
}.each do |source, expected|
|
238
251
|
it "should lex an interpolated variable 'x' from #{source}" do
|
239
252
|
tokens_scanned_from(source).should match_tokens2(*expected)
|
@@ -361,6 +374,63 @@ describe 'Lexer2' do
|
|
361
374
|
[:DQPOST, " After"]
|
362
375
|
)
|
363
376
|
end
|
377
|
+
|
378
|
+
context 'with bad syntax' do
|
379
|
+
def expect_issue(code, issue)
|
380
|
+
expect { tokens_scanned_from(code) }.to raise_error(Puppet::ParseErrorWithIssue) { |e|
|
381
|
+
expect(e.issue_code).to be(issue.issue_code)
|
382
|
+
}
|
383
|
+
end
|
384
|
+
|
385
|
+
it 'detects and reports HEREDOC_UNCLOSED_PARENTHESIS' do
|
386
|
+
code = <<-CODE
|
387
|
+
@(END:syntax/t
|
388
|
+
Text
|
389
|
+
|- END
|
390
|
+
CODE
|
391
|
+
expect_issue(code, Puppet::Pops::Issues::HEREDOC_UNCLOSED_PARENTHESIS)
|
392
|
+
end
|
393
|
+
|
394
|
+
it 'detects and reports HEREDOC_WITHOUT_END_TAGGED_LINE' do
|
395
|
+
code = <<-CODE
|
396
|
+
@(END:syntax/t)
|
397
|
+
Text
|
398
|
+
CODE
|
399
|
+
expect_issue(code, Puppet::Pops::Issues::HEREDOC_WITHOUT_END_TAGGED_LINE)
|
400
|
+
end
|
401
|
+
|
402
|
+
it 'detects and reports HEREDOC_INVALID_ESCAPE' do
|
403
|
+
code = <<-CODE
|
404
|
+
@(END:syntax/x)
|
405
|
+
Text
|
406
|
+
|- END
|
407
|
+
CODE
|
408
|
+
expect_issue(code, Puppet::Pops::Issues::HEREDOC_INVALID_ESCAPE)
|
409
|
+
end
|
410
|
+
|
411
|
+
it 'detects and reports HEREDOC_INVALID_SYNTAX' do
|
412
|
+
code = <<-CODE
|
413
|
+
@(END:syntax/t/p)
|
414
|
+
Text
|
415
|
+
|- END
|
416
|
+
CODE
|
417
|
+
expect_issue(code, Puppet::Pops::Issues::HEREDOC_INVALID_SYNTAX)
|
418
|
+
end
|
419
|
+
|
420
|
+
it 'detects and reports HEREDOC_WITHOUT_TEXT' do
|
421
|
+
code = '@(END:syntax/t)'
|
422
|
+
expect_issue(code, Puppet::Pops::Issues::HEREDOC_WITHOUT_TEXT)
|
423
|
+
end
|
424
|
+
|
425
|
+
it 'detects and reports HEREDOC_MULTIPLE_AT_ESCAPES' do
|
426
|
+
code = <<-CODE
|
427
|
+
@(END:syntax/tst)
|
428
|
+
Tex\\tt\\n
|
429
|
+
|- END
|
430
|
+
CODE
|
431
|
+
expect_issue(code, Puppet::Pops::Issues::HEREDOC_MULTIPLE_AT_ESCAPES)
|
432
|
+
end
|
433
|
+
end
|
364
434
|
end
|
365
435
|
|
366
436
|
context 'when dealing with multi byte characters' do
|
@@ -376,6 +446,18 @@ describe 'Lexer2' do
|
|
376
446
|
tokens_scanned_from(code).should match_tokens2([:STRING, "x\u2713y"])
|
377
447
|
end
|
378
448
|
end
|
449
|
+
it 'should support unicode characters in long form' do
|
450
|
+
code = <<-CODE
|
451
|
+
"x\\u{1f452}y"
|
452
|
+
CODE
|
453
|
+
if Puppet::Pops::Parser::Locator::RUBYVER < Puppet::Pops::Parser::Locator::RUBY_1_9_3
|
454
|
+
# Ruby 1.8.7 reports the multibyte char as several octal characters
|
455
|
+
tokens_scanned_from(code).should match_tokens2([:STRING, "x\360\237\221\222y"])
|
456
|
+
else
|
457
|
+
# >= Ruby 1.9.3 reports \u
|
458
|
+
tokens_scanned_from(code).should match_tokens2([:STRING, "x\u{1f452}y"])
|
459
|
+
end
|
460
|
+
end
|
379
461
|
|
380
462
|
it 'should not select LISTSTART token when preceded by multibyte chars' do
|
381
463
|
# This test is sensitive to the number of multibyte characters and position of the expressions
|
@@ -487,6 +569,75 @@ describe 'Lexer2' do
|
|
487
569
|
[:RENDER_STRING, "<% this is escaped epp %>\n"]
|
488
570
|
)
|
489
571
|
end
|
572
|
+
|
573
|
+
context 'with bad epp syntax' do
|
574
|
+
def expect_issue(code, issue)
|
575
|
+
expect { epp_tokens_scanned_from(code) }.to raise_error(Puppet::ParseErrorWithIssue) { |e|
|
576
|
+
expect(e.issue_code).to be(issue.issue_code)
|
577
|
+
}
|
578
|
+
end
|
579
|
+
|
580
|
+
it 'detects and reports EPP_UNBALANCED_TAG' do
|
581
|
+
expect_issue('<% asf', Puppet::Pops::Issues::EPP_UNBALANCED_TAG)
|
582
|
+
end
|
583
|
+
|
584
|
+
it 'detects and reports EPP_UNBALANCED_COMMENT' do
|
585
|
+
expect_issue('<%# asf', Puppet::Pops::Issues::EPP_UNBALANCED_COMMENT)
|
586
|
+
end
|
587
|
+
|
588
|
+
it 'detects and reports EPP_UNBALANCED_EXPRESSION' do
|
589
|
+
expect_issue('asf <%', Puppet::Pops::Issues::EPP_UNBALANCED_EXPRESSION)
|
590
|
+
end
|
591
|
+
end
|
490
592
|
end
|
491
|
-
end
|
492
593
|
|
594
|
+
context 'when parsing bad code' do
|
595
|
+
def expect_issue(code, issue)
|
596
|
+
expect { tokens_scanned_from(code) }.to raise_error(Puppet::ParseErrorWithIssue) do |e|
|
597
|
+
expect(e.issue_code).to be(issue.issue_code)
|
598
|
+
end
|
599
|
+
end
|
600
|
+
|
601
|
+
it 'detects and reports issue ILLEGAL_CLASS_REFERENCE' do
|
602
|
+
expect_issue('A::3', Puppet::Pops::Issues::ILLEGAL_CLASS_REFERENCE)
|
603
|
+
end
|
604
|
+
|
605
|
+
it 'detects and reports issue ILLEGAL_FULLY_QUALIFIED_CLASS_REFERENCE' do
|
606
|
+
expect_issue('::A::3', Puppet::Pops::Issues::ILLEGAL_FULLY_QUALIFIED_CLASS_REFERENCE)
|
607
|
+
end
|
608
|
+
|
609
|
+
it 'detects and reports issue ILLEGAL_FULLY_QUALIFIED_NAME' do
|
610
|
+
expect_issue('::a::3', Puppet::Pops::Issues::ILLEGAL_FULLY_QUALIFIED_NAME)
|
611
|
+
end
|
612
|
+
|
613
|
+
it 'detects and reports issue ILLEGAL_NAME_OR_BARE_WORD' do
|
614
|
+
expect_issue('a::3', Puppet::Pops::Issues::ILLEGAL_NAME_OR_BARE_WORD)
|
615
|
+
end
|
616
|
+
|
617
|
+
it 'detects and reports issue ILLEGAL_NUMBER' do
|
618
|
+
expect_issue('3g', Puppet::Pops::Issues::ILLEGAL_NUMBER)
|
619
|
+
end
|
620
|
+
|
621
|
+
it 'detects and reports issue INVALID_HEX_NUMBER' do
|
622
|
+
expect_issue('0x3g', Puppet::Pops::Issues::INVALID_HEX_NUMBER)
|
623
|
+
end
|
624
|
+
|
625
|
+
it 'detects and reports issue INVALID_OCTAL_NUMBER' do
|
626
|
+
expect_issue('038', Puppet::Pops::Issues::INVALID_OCTAL_NUMBER)
|
627
|
+
end
|
628
|
+
|
629
|
+
it 'detects and reports issue INVALID_DECIMAL_NUMBER' do
|
630
|
+
expect_issue('4.3g', Puppet::Pops::Issues::INVALID_DECIMAL_NUMBER)
|
631
|
+
end
|
632
|
+
|
633
|
+
it 'detects and reports issue NO_INPUT_TO_LEXER' do
|
634
|
+
expect { Puppet::Pops::Parser::Lexer2.new.fullscan }.to raise_error(Puppet::ParseErrorWithIssue) { |e|
|
635
|
+
expect(e.issue_code).to be(Puppet::Pops::Issues::NO_INPUT_TO_LEXER.issue_code)
|
636
|
+
}
|
637
|
+
end
|
638
|
+
|
639
|
+
it 'detects and reports issue UNCLOSED_QUOTE' do
|
640
|
+
expect_issue('"asd', Puppet::Pops::Issues::UNCLOSED_QUOTE)
|
641
|
+
end
|
642
|
+
end
|
643
|
+
end
|
@@ -71,6 +71,32 @@ describe "egrammar parsing heredoc" do
|
|
71
71
|
].join("\n")
|
72
72
|
end
|
73
73
|
|
74
|
+
it "parses interpolated heredoc expression containing escapes" do
|
75
|
+
src = <<-CODE
|
76
|
+
@("END")
|
77
|
+
Hello \\$name
|
78
|
+
|- END
|
79
|
+
CODE
|
80
|
+
dump(parse(src)).should == [
|
81
|
+
"(@()",
|
82
|
+
" (sublocated (cat 'Hello \\' (str $name) ''))",
|
83
|
+
")"
|
84
|
+
].join("\n")
|
85
|
+
end
|
86
|
+
|
87
|
+
it "parses interpolated heredoc expression containing escapes when escaping other things than $" do
|
88
|
+
src = <<-CODE
|
89
|
+
@("END"/t)
|
90
|
+
Hello \\$name
|
91
|
+
|- END
|
92
|
+
CODE
|
93
|
+
dump(parse(src)).should == [
|
94
|
+
"(@()",
|
95
|
+
" (sublocated (cat 'Hello \\' (str $name) ''))",
|
96
|
+
")"
|
97
|
+
].join("\n")
|
98
|
+
end
|
99
|
+
|
74
100
|
it "parses with escaped newlines without preceding whitespace" do
|
75
101
|
src = <<-CODE
|
76
102
|
@(END/L)
|
@@ -38,7 +38,7 @@ describe "transformation to Puppet AST for function calls" do
|
|
38
38
|
|
39
39
|
"info bar" => '(invoke info bar)',
|
40
40
|
"notice bar" => '(invoke notice bar)',
|
41
|
-
"
|
41
|
+
"err bar" => '(invoke err bar)',
|
42
42
|
"warning bar" => '(invoke warning bar)',
|
43
43
|
"debug bar" => '(invoke debug bar)',
|
44
44
|
|
@@ -89,6 +89,10 @@ describe 'The type calculator' do
|
|
89
89
|
Puppet::Pops::Types::TypeFactory.optional(t)
|
90
90
|
end
|
91
91
|
|
92
|
+
def not_undef_t(t = nil)
|
93
|
+
Puppet::Pops::Types::TypeFactory.not_undef(t)
|
94
|
+
end
|
95
|
+
|
92
96
|
def undef_t
|
93
97
|
Puppet::Pops::Types::TypeFactory.undef
|
94
98
|
end
|
@@ -108,6 +112,7 @@ describe 'The type calculator' do
|
|
108
112
|
def all_types
|
109
113
|
[ Puppet::Pops::Types::PAnyType,
|
110
114
|
Puppet::Pops::Types::PUndefType,
|
115
|
+
Puppet::Pops::Types::PNotUndefType,
|
111
116
|
Puppet::Pops::Types::PDataType,
|
112
117
|
Puppet::Pops::Types::PScalarType,
|
113
118
|
Puppet::Pops::Types::PStringType,
|
@@ -184,6 +189,7 @@ describe 'The type calculator' do
|
|
184
189
|
result << array_t(types::PDataType.new)
|
185
190
|
result << types::TypeFactory.hash_of_data
|
186
191
|
result << Puppet::Pops::Types::PUndefType
|
192
|
+
result << not_undef_t(types::PDataType.new)
|
187
193
|
tmp = tuple_t(types::PDataType.new)
|
188
194
|
result << (tmp)
|
189
195
|
tmp.size_type = range_t(0, nil)
|
@@ -389,7 +395,7 @@ describe 'The type calculator' do
|
|
389
395
|
t = calculator.infer_set({ 'mode' => 'read', 'path' => ['foo', 'fee' ] })
|
390
396
|
expect(t.class).to eq(Puppet::Pops::Types::PStructType)
|
391
397
|
expect(t.elements.size).to eq(2)
|
392
|
-
els = t.elements.map { |e| e.
|
398
|
+
els = t.elements.map { |e| e.value_type }.sort {|a,b| a.to_s <=> b.to_s }
|
393
399
|
els[0].class.should == Puppet::Pops::Types::PStringType
|
394
400
|
els[1].class.should == Puppet::Pops::Types::PTupleType
|
395
401
|
end
|
@@ -471,6 +477,45 @@ describe 'The type calculator' do
|
|
471
477
|
calculator.string(calculator.common_type(r1, r2)).should == "Class"
|
472
478
|
end
|
473
479
|
|
480
|
+
context 'of strings' do
|
481
|
+
it 'computes commonality' do
|
482
|
+
t1 = string_t('abc')
|
483
|
+
t2 = string_t('xyz')
|
484
|
+
common_t = calculator.common_type(t1,t2)
|
485
|
+
expect(common_t.class).to eq(Puppet::Pops::Types::PStringType)
|
486
|
+
expect(common_t.values).to eq(['abc', 'xyz'])
|
487
|
+
end
|
488
|
+
|
489
|
+
it 'computes common size_type' do
|
490
|
+
t1 = string_t
|
491
|
+
t1.size_type = range_t(3,6)
|
492
|
+
t2 = string_t
|
493
|
+
t2.size_type = range_t(2,4)
|
494
|
+
common_t = calculator.common_type(t1,t2)
|
495
|
+
expect(common_t.class).to eq(Puppet::Pops::Types::PStringType)
|
496
|
+
expect(common_t.size_type).to eq(range_t(2,6))
|
497
|
+
end
|
498
|
+
|
499
|
+
it 'computes common size_type to be undef when one of the types has no size_type' do
|
500
|
+
t1 = string_t
|
501
|
+
t2 = string_t
|
502
|
+
t2.size_type = range_t(2,4)
|
503
|
+
common_t = calculator.common_type(t1,t2)
|
504
|
+
expect(common_t.class).to eq(Puppet::Pops::Types::PStringType)
|
505
|
+
expect(common_t.size_type).to be_nil
|
506
|
+
end
|
507
|
+
|
508
|
+
it 'computes values to be empty if the one has empty values' do
|
509
|
+
t1 = string_t('apa')
|
510
|
+
t1.size_type = range_t(3,6)
|
511
|
+
t2 = string_t
|
512
|
+
t2.size_type = range_t(2,4)
|
513
|
+
common_t = calculator.common_type(t1,t2)
|
514
|
+
expect(common_t.class).to eq(Puppet::Pops::Types::PStringType)
|
515
|
+
expect(common_t.values).to be_empty
|
516
|
+
end
|
517
|
+
end
|
518
|
+
|
474
519
|
it 'computes pattern commonality' do
|
475
520
|
t1 = pattern_t('abc')
|
476
521
|
t2 = pattern_t('xyz')
|
@@ -553,6 +598,13 @@ describe 'The type calculator' do
|
|
553
598
|
context 'computes assignability' do
|
554
599
|
include_context "types_setup"
|
555
600
|
|
601
|
+
it 'such that all types are assignable to themselves' do
|
602
|
+
all_types.each do |tc|
|
603
|
+
t = tc.new
|
604
|
+
expect(t).to be_assignable_to(t)
|
605
|
+
end
|
606
|
+
end
|
607
|
+
|
556
608
|
context 'for Unit, such that' do
|
557
609
|
it 'all types are assignable to Unit' do
|
558
610
|
t = Puppet::Pops::Types::PUnitType.new()
|
@@ -577,13 +629,55 @@ describe 'The type calculator' do
|
|
577
629
|
all_types.each { |t2| t2.new.should be_assignable_to(t) }
|
578
630
|
end
|
579
631
|
|
580
|
-
it 'Any is not assignable to anything but Any' do
|
581
|
-
tested_types = all_types() - [Puppet::Pops::Types::PAnyType]
|
632
|
+
it 'Any is not assignable to anything but Any and Optional (implied Optional[Any])' do
|
633
|
+
tested_types = all_types() - [Puppet::Pops::Types::PAnyType, Puppet::Pops::Types::POptionalType]
|
582
634
|
t = Puppet::Pops::Types::PAnyType.new()
|
583
635
|
tested_types.each { |t2| t.should_not be_assignable_to(t2.new) }
|
584
636
|
end
|
585
637
|
end
|
586
638
|
|
639
|
+
context "for NotUndef, such that" do
|
640
|
+
it 'all types except types assignable from Undef are assignable to NotUndef' do
|
641
|
+
t = not_undef_t
|
642
|
+
tc = Puppet::Pops::Types::TypeCalculator.singleton
|
643
|
+
undef_t = Puppet::Pops::Types::PUndefType.new()
|
644
|
+
all_types().each do |c|
|
645
|
+
t2 = c.new
|
646
|
+
if tc.assignable?(t2, undef_t)
|
647
|
+
expect(t2).not_to be_assignable_to(t)
|
648
|
+
else
|
649
|
+
expect(t2).to be_assignable_to(t)
|
650
|
+
end
|
651
|
+
end
|
652
|
+
end
|
653
|
+
|
654
|
+
it 'type NotUndef[T] is assignable from T unless T is assignable from Undef ' do
|
655
|
+
tc = Puppet::Pops::Types::TypeCalculator.singleton
|
656
|
+
undef_t = Puppet::Pops::Types::PUndefType.new()
|
657
|
+
all_types().select do |c|
|
658
|
+
t2 = c.new
|
659
|
+
not_undef_t = not_undef_t(t2)
|
660
|
+
if tc.assignable?(t2, undef_t)
|
661
|
+
expect(t2).not_to be_assignable_to(not_undef_t)
|
662
|
+
else
|
663
|
+
expect(t2).to be_assignable_to(not_undef_t)
|
664
|
+
end
|
665
|
+
end
|
666
|
+
end
|
667
|
+
|
668
|
+
it 'type T is assignable from NotUndef[T] unless T is assignable from Undef' do
|
669
|
+
tc = Puppet::Pops::Types::TypeCalculator.singleton
|
670
|
+
undef_t = Puppet::Pops::Types::PUndefType.new()
|
671
|
+
all_types().select do |c|
|
672
|
+
t2 = c.new
|
673
|
+
not_undef_t = not_undef_t(t2)
|
674
|
+
unless tc.assignable?(t2, undef_t)
|
675
|
+
expect(not_undef_t).to be_assignable_to(t2)
|
676
|
+
end
|
677
|
+
end
|
678
|
+
end
|
679
|
+
end
|
680
|
+
|
587
681
|
context "for Data, such that" do
|
588
682
|
it 'all scalars + array and hash are assignable to Data' do
|
589
683
|
t = Puppet::Pops::Types::PDataType.new()
|
@@ -610,7 +704,7 @@ describe 'The type calculator' do
|
|
610
704
|
end
|
611
705
|
|
612
706
|
it 'Data is not assignable to any disjunct type' do
|
613
|
-
tested_types = all_types - [Puppet::Pops::Types::PAnyType, Puppet::Pops::Types::PDataType] - scalar_types
|
707
|
+
tested_types = all_types - [Puppet::Pops::Types::PAnyType, Puppet::Pops::Types::POptionalType, Puppet::Pops::Types::PDataType] - scalar_types
|
614
708
|
t = Puppet::Pops::Types::PDataType.new()
|
615
709
|
tested_types.each {|t2| t.should_not be_assignable_to(t2.new) }
|
616
710
|
end
|
@@ -647,7 +741,7 @@ describe 'The type calculator' do
|
|
647
741
|
end
|
648
742
|
|
649
743
|
it 'Scalar is not assignable to any disjunct type' do
|
650
|
-
tested_types = all_types - [Puppet::Pops::Types::PAnyType, Puppet::Pops::Types::PDataType] - scalar_types
|
744
|
+
tested_types = all_types - [Puppet::Pops::Types::PAnyType, Puppet::Pops::Types::POptionalType, Puppet::Pops::Types::PNotUndefType, Puppet::Pops::Types::PDataType] - scalar_types
|
651
745
|
t = Puppet::Pops::Types::PScalarType.new()
|
652
746
|
tested_types.each {|t2| t.should_not be_assignable_to(t2.new) }
|
653
747
|
end
|
@@ -668,6 +762,8 @@ describe 'The type calculator' do
|
|
668
762
|
it 'Numeric is not assignable to any disjunct type' do
|
669
763
|
tested_types = all_types - [
|
670
764
|
Puppet::Pops::Types::PAnyType,
|
765
|
+
Puppet::Pops::Types::POptionalType,
|
766
|
+
Puppet::Pops::Types::PNotUndefType,
|
671
767
|
Puppet::Pops::Types::PDataType,
|
672
768
|
Puppet::Pops::Types::PScalarType,
|
673
769
|
] - numeric_types
|
@@ -689,7 +785,7 @@ describe 'The type calculator' do
|
|
689
785
|
end
|
690
786
|
|
691
787
|
it 'Collection is not assignable to any disjunct type' do
|
692
|
-
tested_types = all_types - [Puppet::Pops::Types::PAnyType] - collection_types
|
788
|
+
tested_types = all_types - [Puppet::Pops::Types::PAnyType, Puppet::Pops::Types::POptionalType, Puppet::Pops::Types::PNotUndefType] - collection_types
|
693
789
|
t = Puppet::Pops::Types::PCollectionType.new()
|
694
790
|
tested_types.each {|t2| t.should_not be_assignable_to(t2.new) }
|
695
791
|
end
|
@@ -700,6 +796,7 @@ describe 'The type calculator' do
|
|
700
796
|
t = Puppet::Pops::Types::PArrayType.new()
|
701
797
|
tested_types = collection_types - [
|
702
798
|
Puppet::Pops::Types::PCollectionType,
|
799
|
+
Puppet::Pops::Types::PNotUndefType,
|
703
800
|
Puppet::Pops::Types::PArrayType,
|
704
801
|
Puppet::Pops::Types::PTupleType]
|
705
802
|
tested_types.each {|t2| t.should_not be_assignable_to(t2.new) }
|
@@ -708,6 +805,8 @@ describe 'The type calculator' do
|
|
708
805
|
it 'Array is not assignable to any disjunct type' do
|
709
806
|
tested_types = all_types - [
|
710
807
|
Puppet::Pops::Types::PAnyType,
|
808
|
+
Puppet::Pops::Types::POptionalType,
|
809
|
+
Puppet::Pops::Types::PNotUndefType,
|
711
810
|
Puppet::Pops::Types::PDataType] - collection_types
|
712
811
|
t = Puppet::Pops::Types::PArrayType.new()
|
713
812
|
tested_types.each {|t2| t.should_not be_assignable_to(t2.new) }
|
@@ -727,6 +826,8 @@ describe 'The type calculator' do
|
|
727
826
|
it 'Hash is not assignable to any disjunct type' do
|
728
827
|
tested_types = all_types - [
|
729
828
|
Puppet::Pops::Types::PAnyType,
|
829
|
+
Puppet::Pops::Types::POptionalType,
|
830
|
+
Puppet::Pops::Types::PNotUndefType,
|
730
831
|
Puppet::Pops::Types::PDataType] - collection_types
|
731
832
|
t = Puppet::Pops::Types::PHashType.new()
|
732
833
|
tested_types.each {|t2| t.should_not be_assignable_to(t2.new) }
|
@@ -762,6 +863,8 @@ describe 'The type calculator' do
|
|
762
863
|
it 'Tuple is not assignable to any disjunct type' do
|
763
864
|
tested_types = all_types - [
|
764
865
|
Puppet::Pops::Types::PAnyType,
|
866
|
+
Puppet::Pops::Types::POptionalType,
|
867
|
+
Puppet::Pops::Types::PNotUndefType,
|
765
868
|
Puppet::Pops::Types::PDataType] - collection_types
|
766
869
|
t = Puppet::Pops::Types::PTupleType.new()
|
767
870
|
tested_types.each {|t2| t.should_not be_assignable_to(t2.new) }
|
@@ -781,10 +884,41 @@ describe 'The type calculator' do
|
|
781
884
|
it 'Struct is not assignable to any disjunct type' do
|
782
885
|
tested_types = all_types - [
|
783
886
|
Puppet::Pops::Types::PAnyType,
|
887
|
+
Puppet::Pops::Types::POptionalType,
|
888
|
+
Puppet::Pops::Types::PNotUndefType,
|
784
889
|
Puppet::Pops::Types::PDataType] - collection_types
|
785
890
|
t = Puppet::Pops::Types::PStructType.new()
|
786
891
|
tested_types.each {|t2| t.should_not be_assignable_to(t2.new) }
|
787
892
|
end
|
893
|
+
|
894
|
+
it 'Default key optionality is controlled by value assignability to undef' do
|
895
|
+
t1 = struct_t({'member' => string_t})
|
896
|
+
expect(t1.elements[0].key_type).to eq(string_t('member'))
|
897
|
+
t1 = struct_t({'member' => object_t})
|
898
|
+
expect(t1.elements[0].key_type).to eq(optional_t(string_t('member')))
|
899
|
+
end
|
900
|
+
|
901
|
+
it "NotUndef['key'] becomes String['key'] (since its implied that String is required)" do
|
902
|
+
t1 = struct_t({not_undef_t('member') => string_t})
|
903
|
+
expect(t1.elements[0].key_type).to eq(string_t('member'))
|
904
|
+
end
|
905
|
+
|
906
|
+
it "Optional['key'] becomes Optional[String['key']]" do
|
907
|
+
t1 = struct_t({optional_t('member') => string_t})
|
908
|
+
expect(t1.elements[0].key_type).to eq(optional_t(string_t('member')))
|
909
|
+
end
|
910
|
+
|
911
|
+
it 'Optional members are not required' do
|
912
|
+
t1 = struct_t({optional_t('optional_member') => string_t, not_undef_t('other_member') => string_t})
|
913
|
+
t2 = struct_t({not_undef_t('other_member') => string_t})
|
914
|
+
expect(t2).to be_assignable_to(t1)
|
915
|
+
end
|
916
|
+
|
917
|
+
it 'Required members not optional even when value is' do
|
918
|
+
t1 = struct_t({not_undef_t('required_member') => object_t, not_undef_t('other_member') => string_t})
|
919
|
+
t2 = struct_t({not_undef_t('other_member') => string_t})
|
920
|
+
expect(t2).not_to be_assignable_to(t1)
|
921
|
+
end
|
788
922
|
end
|
789
923
|
|
790
924
|
context "for Callable, such that" do
|
@@ -792,7 +926,9 @@ describe 'The type calculator' do
|
|
792
926
|
t = Puppet::Pops::Types::PCallableType.new()
|
793
927
|
tested_types = all_types - [
|
794
928
|
Puppet::Pops::Types::PCallableType,
|
795
|
-
Puppet::Pops::Types::PAnyType
|
929
|
+
Puppet::Pops::Types::PAnyType,
|
930
|
+
Puppet::Pops::Types::POptionalType,
|
931
|
+
Puppet::Pops::Types::PNotUndefType]
|
796
932
|
tested_types.each {|t2| t.should_not be_assignable_to(t2.new) }
|
797
933
|
end
|
798
934
|
end
|
@@ -1231,7 +1367,7 @@ describe 'The type calculator' do
|
|
1231
1367
|
calculator.instance?(Puppet::Pops::Types::POptionalType.new(), :undef).should == true
|
1232
1368
|
end
|
1233
1369
|
|
1234
|
-
it 'should not consider undef to be an instance of any other type than Any,
|
1370
|
+
it 'should not consider undef to be an instance of any other type than Any, UndefType and Data' do
|
1235
1371
|
types_to_test = all_types - [
|
1236
1372
|
Puppet::Pops::Types::PAnyType,
|
1237
1373
|
Puppet::Pops::Types::PUndefType,
|
@@ -1248,9 +1384,10 @@ describe 'The type calculator' do
|
|
1248
1384
|
calculator.instance?(Puppet::Pops::Types::PAnyType.new(), :default).should == true
|
1249
1385
|
end
|
1250
1386
|
|
1251
|
-
it 'should not consider "default" to be an instance of anything but Default, and Any' do
|
1387
|
+
it 'should not consider "default" to be an instance of anything but Default, NotUndef, and Any' do
|
1252
1388
|
types_to_test = all_types - [
|
1253
1389
|
Puppet::Pops::Types::PAnyType,
|
1390
|
+
Puppet::Pops::Types::PNotUndefType,
|
1254
1391
|
Puppet::Pops::Types::PDefaultType,
|
1255
1392
|
]
|
1256
1393
|
|
@@ -1281,6 +1418,13 @@ describe 'The type calculator' do
|
|
1281
1418
|
calculator.instance?(range, 'abcd').should == false
|
1282
1419
|
end
|
1283
1420
|
|
1421
|
+
it 'should consider string values' do
|
1422
|
+
string = string_t('a', 'b')
|
1423
|
+
expect(calculator.instance?(string, 'a')).to eq(true)
|
1424
|
+
expect(calculator.instance?(string, 'b')).to eq(true)
|
1425
|
+
expect(calculator.instance?(string, 'c')).to eq(false)
|
1426
|
+
end
|
1427
|
+
|
1284
1428
|
it 'should consider array in length range' do
|
1285
1429
|
range = factory.constrain_size(array_t(integer_t), 1,3)
|
1286
1430
|
calculator.instance?(range, [1]).should == true
|
@@ -1380,6 +1524,26 @@ describe 'The type calculator' do
|
|
1380
1524
|
struct = struct_t({'a'=>Integer, 'b'=>String, 'c'=>optional_t(Float)})
|
1381
1525
|
calculator.instance?(struct, {'a'=>1, 'b'=>'a', 'c'=>'x'}).should == false
|
1382
1526
|
end
|
1527
|
+
|
1528
|
+
it 'should consider nil to be a valid element value' do
|
1529
|
+
struct = struct_t({not_undef_t('a') => object_t, 'b'=>String})
|
1530
|
+
expect(calculator.instance?(struct, {'a'=>nil , 'b'=>'a'})).to eq(true)
|
1531
|
+
end
|
1532
|
+
|
1533
|
+
it 'should consider nil to be a valid element value but subject to value type' do
|
1534
|
+
struct = struct_t({not_undef_t('a') => String, 'b'=>String})
|
1535
|
+
expect(calculator.instance?(struct, {'a'=>nil , 'b'=>'a'})).to eq(false)
|
1536
|
+
end
|
1537
|
+
|
1538
|
+
it 'should consider nil to be a valid element value but subject to value type even when key is optional' do
|
1539
|
+
struct = struct_t({optional_t('a') => String, 'b'=>String})
|
1540
|
+
expect(calculator.instance?(struct, {'a'=>nil , 'b'=>'a'})).to eq(false)
|
1541
|
+
end
|
1542
|
+
|
1543
|
+
it 'should consider a hash where optional key is missing as assignable even if value of optional key is required' do
|
1544
|
+
struct = struct_t({optional_t('a') => String, 'b'=>String})
|
1545
|
+
expect(calculator.instance?(struct, {'b'=>'a'})).to eq(true)
|
1546
|
+
end
|
1383
1547
|
end
|
1384
1548
|
|
1385
1549
|
context 'and t is Data' do
|
@@ -1724,6 +1888,21 @@ describe 'The type calculator' do
|
|
1724
1888
|
it "should yield Unit for a Unit type" do
|
1725
1889
|
expect(calculator.string(unit_t)).to eql('Unit')
|
1726
1890
|
end
|
1891
|
+
|
1892
|
+
it "should yield 'NotUndef' for a PNotUndefType" do
|
1893
|
+
t = not_undef_t
|
1894
|
+
expect(calculator.string(t)).to eq('NotUndef')
|
1895
|
+
end
|
1896
|
+
|
1897
|
+
it "should yield 'NotUndef[T]' for a PNotUndefType[T]" do
|
1898
|
+
t = not_undef_t(data_t)
|
1899
|
+
expect(calculator.string(t)).to eq('NotUndef[Data]')
|
1900
|
+
end
|
1901
|
+
|
1902
|
+
it "should yield 'NotUndef['string']' for a PNotUndefType['string']" do
|
1903
|
+
t = not_undef_t('hey')
|
1904
|
+
expect(calculator.string(t)).to eq("NotUndef['hey']")
|
1905
|
+
end
|
1727
1906
|
end
|
1728
1907
|
|
1729
1908
|
context 'when processing meta type' do
|
@@ -1867,7 +2046,7 @@ describe 'The type calculator' do
|
|
1867
2046
|
generic.element_type.values.should == []
|
1868
2047
|
end
|
1869
2048
|
|
1870
|
-
it
|
2049
|
+
it 'a generic result is created by generalize! given an instance specific result for a Hash' do
|
1871
2050
|
generic = calculator.infer({'a' =>1,'b' => 2})
|
1872
2051
|
generic.key_type.values.sort.should == ['a', 'b']
|
1873
2052
|
generic.element_type.from.should == 1
|
@@ -1878,6 +2057,20 @@ describe 'The type calculator' do
|
|
1878
2057
|
generic.element_type.to.should == nil
|
1879
2058
|
end
|
1880
2059
|
|
2060
|
+
it 'ensures that Struct key types are not generalized' do
|
2061
|
+
generic = calculator.generalize!(struct_t({'a' => object_t}))
|
2062
|
+
expect(calculator.string(generic)).to eq("Struct[{'a'=>Any}]")
|
2063
|
+
generic = calculator.generalize!(struct_t({not_undef_t('a') => object_t}))
|
2064
|
+
expect(calculator.string(generic)).to eq("Struct[{NotUndef['a']=>Any}]")
|
2065
|
+
generic = calculator.generalize!(struct_t({optional_t('a') => string_t}))
|
2066
|
+
expect(calculator.string(generic)).to eq("Struct[{Optional['a']=>String}]")
|
2067
|
+
end
|
2068
|
+
|
2069
|
+
it 'ensures that Struct value types are generalized' do
|
2070
|
+
generic = calculator.generalize!(struct_t({'a' => range_t(1, 3)}))
|
2071
|
+
expect(calculator.string(generic)).to eq("Struct[{'a'=>Integer}]")
|
2072
|
+
end
|
2073
|
+
|
1881
2074
|
it "does not reduce by combining types when using infer_set" do
|
1882
2075
|
element_type = calculator.infer(['a','b',1,2]).element_type
|
1883
2076
|
element_type.class.should == Puppet::Pops::Types::PScalarType
|
@@ -1983,7 +2176,7 @@ describe 'The type calculator' do
|
|
1983
2176
|
end
|
1984
2177
|
|
1985
2178
|
matcher :be_assignable_to do |type|
|
1986
|
-
calc = Puppet::Pops::Types::TypeCalculator.
|
2179
|
+
calc = Puppet::Pops::Types::TypeCalculator.singleton
|
1987
2180
|
|
1988
2181
|
match do |actual|
|
1989
2182
|
calc.assignable?(type, actual)
|