puppet 4.0.0 → 4.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.

Files changed (219) hide show
  1. checksums.yaml +4 -4
  2. data/ext/build_defaults.yaml +8 -35
  3. data/ext/debian/puppet.default +0 -5
  4. data/ext/debian/puppet.init +1 -15
  5. data/lib/hiera/puppet_function.rb +15 -4
  6. data/lib/puppet/application/agent.rb +5 -0
  7. data/lib/puppet/application/apply.rb +23 -2
  8. data/lib/puppet/application/device.rb +8 -3
  9. data/lib/puppet/application/master.rb +16 -5
  10. data/lib/puppet/configurer.rb +7 -5
  11. data/lib/puppet/defaults.rb +18 -0
  12. data/lib/puppet/environments.rb +1 -1
  13. data/lib/puppet/error.rb +27 -1
  14. data/lib/puppet/file_serving/metadata.rb +13 -8
  15. data/lib/puppet/file_serving/terminus_helper.rb +7 -8
  16. data/lib/puppet/file_system.rb +13 -0
  17. data/lib/puppet/file_system/file_impl.rb +4 -0
  18. data/lib/puppet/file_system/memory_impl.rb +4 -0
  19. data/lib/puppet/file_system/windows.rb +8 -0
  20. data/lib/puppet/functions.rb +33 -3
  21. data/lib/puppet/functions/defined.rb +130 -0
  22. data/lib/puppet/functions/regsubst.rb +1 -1
  23. data/lib/puppet/functions/split.rb +1 -1
  24. data/lib/puppet/indirector/catalog/compiler.rb +1 -1
  25. data/lib/puppet/indirector/facts/facter.rb +11 -0
  26. data/lib/puppet/loaders.rb +1 -0
  27. data/lib/puppet/node.rb +17 -1
  28. data/lib/puppet/node/environment.rb +4 -0
  29. data/lib/puppet/parser/ast/pops_bridge.rb +4 -0
  30. data/lib/puppet/parser/compiler.rb +9 -0
  31. data/lib/puppet/parser/functions/defined.rb +25 -1
  32. data/lib/puppet/parser/functions/file.rb +3 -1
  33. data/lib/puppet/parser/scope.rb +11 -2
  34. data/lib/puppet/parser/templatewrapper.rb +2 -1
  35. data/lib/puppet/pops.rb +4 -0
  36. data/lib/puppet/pops/evaluator/access_operator.rb +25 -5
  37. data/lib/puppet/pops/evaluator/closure.rb +28 -2
  38. data/lib/puppet/pops/evaluator/collector_transformer.rb +1 -11
  39. data/lib/puppet/pops/evaluator/collectors/catalog_collector.rb +4 -0
  40. data/lib/puppet/pops/evaluator/collectors/exported_collector.rb +4 -0
  41. data/lib/puppet/pops/evaluator/compare_operator.rb +43 -0
  42. data/lib/puppet/pops/evaluator/epp_evaluator.rb +7 -2
  43. data/lib/puppet/pops/evaluator/evaluator_impl.rb +48 -14
  44. data/lib/puppet/pops/evaluator/runtime3_support.rb +10 -5
  45. data/lib/puppet/pops/functions/dispatch.rb +6 -1
  46. data/lib/puppet/pops/functions/dispatcher.rb +7 -1
  47. data/lib/puppet/pops/issue_reporter.rb +42 -16
  48. data/lib/puppet/pops/issues.rb +116 -2
  49. data/lib/puppet/pops/loader/loader.rb +11 -0
  50. data/lib/puppet/pops/loader/loader_paths.rb +67 -6
  51. data/lib/puppet/pops/loader/module_loaders.rb +19 -8
  52. data/lib/puppet/pops/loader/puppet_function_instantiator.rb +78 -0
  53. data/lib/puppet/pops/loaders.rb +6 -4
  54. data/lib/puppet/pops/migration/migration_checker.rb +54 -0
  55. data/lib/puppet/pops/model/factory.rb +5 -1
  56. data/lib/puppet/pops/model/model_label_provider.rb +2 -0
  57. data/lib/puppet/pops/model/model_meta.rb +5 -1
  58. data/lib/puppet/pops/parser/egrammar.ra +9 -10
  59. data/lib/puppet/pops/parser/eparser.rb +1061 -1047
  60. data/lib/puppet/pops/parser/epp_support.rb +18 -9
  61. data/lib/puppet/pops/parser/evaluating_parser.rb +7 -1
  62. data/lib/puppet/pops/parser/heredoc_support.rb +12 -11
  63. data/lib/puppet/pops/parser/interpolation_support.rb +7 -1
  64. data/lib/puppet/pops/parser/lexer2.rb +29 -12
  65. data/lib/puppet/pops/parser/lexer_support.rb +52 -23
  66. data/lib/puppet/pops/parser/parser_support.rb +11 -14
  67. data/lib/puppet/pops/parser/slurp_support.rb +22 -6
  68. data/lib/puppet/pops/types/type_calculator.rb +156 -55
  69. data/lib/puppet/pops/types/type_factory.rb +66 -13
  70. data/lib/puppet/pops/types/type_parser.rb +22 -13
  71. data/lib/puppet/pops/types/types.rb +23 -4
  72. data/lib/puppet/pops/types/types_meta.rb +13 -2
  73. data/lib/puppet/pops/validation.rb +25 -2
  74. data/lib/puppet/pops/validation/checker4_0.rb +63 -31
  75. data/lib/puppet/provider/group/windows_adsi.rb +8 -4
  76. data/lib/puppet/provider/mount/parsed.rb +145 -2
  77. data/lib/puppet/provider/package/apt.rb +1 -1
  78. data/lib/puppet/provider/package/pip.rb +11 -2
  79. data/lib/puppet/provider/package/pkgng.rb +134 -0
  80. data/lib/puppet/provider/package/portage.rb +1 -1
  81. data/lib/puppet/provider/package/ports.rb +0 -3
  82. data/lib/puppet/provider/package/windows/exe_package.rb +0 -1
  83. data/lib/puppet/provider/package/windows/msi_package.rb +0 -1
  84. data/lib/puppet/provider/package/zypper.rb +50 -15
  85. data/lib/puppet/provider/scheduled_task/win32_taskscheduler.rb +32 -7
  86. data/lib/puppet/provider/service/debian.rb +1 -1
  87. data/lib/puppet/provider/service/init.rb +7 -0
  88. data/lib/puppet/provider/user/openbsd.rb +1 -0
  89. data/lib/puppet/provider/user/windows_adsi.rb +45 -2
  90. data/lib/puppet/reference/indirection.rb +1 -1
  91. data/lib/puppet/resource.rb +1 -1
  92. data/lib/puppet/resource/catalog.rb +0 -4
  93. data/lib/puppet/settings.rb +19 -0
  94. data/lib/puppet/type/file.rb +1 -0
  95. data/lib/puppet/type/file/ensure.rb +1 -1
  96. data/lib/puppet/type/mount.rb +9 -1
  97. data/lib/puppet/type/scheduled_task.rb +13 -0
  98. data/lib/puppet/type/tidy.rb +3 -1
  99. data/lib/puppet/type/user.rb +32 -0
  100. data/lib/puppet/type/yumrepo.rb +5 -5
  101. data/lib/puppet/util/log.rb +50 -8
  102. data/lib/puppet/util/log/destinations.rb +23 -2
  103. data/lib/puppet/util/logging.rb +37 -1
  104. data/lib/puppet/util/run_mode.rb +1 -14
  105. data/lib/puppet/util/windows/adsi.rb +130 -58
  106. data/lib/puppet/version.rb +1 -1
  107. data/man/man5/puppet.conf.5 +48 -6
  108. data/man/man8/extlookup2hiera.8 +1 -1
  109. data/man/man8/puppet-agent.8 +4 -1
  110. data/man/man8/puppet-apply.8 +4 -1
  111. data/man/man8/puppet-ca.8 +1 -1
  112. data/man/man8/puppet-catalog.8 +1 -1
  113. data/man/man8/puppet-cert.8 +1 -1
  114. data/man/man8/puppet-certificate.8 +1 -1
  115. data/man/man8/puppet-certificate_request.8 +1 -1
  116. data/man/man8/puppet-certificate_revocation_list.8 +1 -1
  117. data/man/man8/puppet-config.8 +1 -1
  118. data/man/man8/puppet-describe.8 +1 -1
  119. data/man/man8/puppet-device.8 +6 -3
  120. data/man/man8/puppet-doc.8 +1 -1
  121. data/man/man8/puppet-epp.8 +1 -1
  122. data/man/man8/puppet-facts.8 +1 -1
  123. data/man/man8/puppet-file.8 +1 -1
  124. data/man/man8/puppet-filebucket.8 +1 -1
  125. data/man/man8/puppet-help.8 +1 -1
  126. data/man/man8/puppet-inspect.8 +1 -1
  127. data/man/man8/puppet-key.8 +1 -1
  128. data/man/man8/puppet-man.8 +1 -1
  129. data/man/man8/puppet-master.8 +4 -1
  130. data/man/man8/puppet-module.8 +1 -1
  131. data/man/man8/puppet-node.8 +1 -1
  132. data/man/man8/puppet-parser.8 +1 -1
  133. data/man/man8/puppet-plugin.8 +1 -1
  134. data/man/man8/puppet-report.8 +1 -1
  135. data/man/man8/puppet-resource.8 +1 -1
  136. data/man/man8/puppet-resource_type.8 +1 -1
  137. data/man/man8/puppet-status.8 +1 -1
  138. data/man/man8/puppet.8 +1 -1
  139. data/spec/fixtures/unit/data_providers/environments/production/lib/puppet/functions/environment/data.rb +3 -1
  140. data/spec/fixtures/unit/data_providers/environments/production/modules/xyz/functions/data.pp +6 -0
  141. data/spec/fixtures/unit/data_providers/environments/production/modules/xyz/lib/puppet/bindings/xyz/default.rb +9 -0
  142. data/spec/fixtures/unit/data_providers/environments/production/modules/xyz/manifests/init.pp +9 -0
  143. data/spec/fixtures/unit/pops/loaders/loaders/mix_4x_and_3x_functions/user/functions/puppetcalled.pp +3 -0
  144. data/spec/fixtures/unit/pops/loaders/loaders/mix_4x_and_3x_functions/user/functions/puppetcaller.pp +3 -0
  145. data/spec/fixtures/unit/pops/loaders/loaders/mix_4x_and_3x_functions/user/functions/puppetcaller4.pp +3 -0
  146. data/spec/fixtures/unit/pops/loaders/loaders/mix_4x_and_3x_functions/user/lib/puppet/functions/user/callingpuppet.rb +5 -0
  147. data/spec/fixtures/unit/pops/loaders/loaders/module_no_lib/modules/modulea/functions/hello.pp +3 -0
  148. data/spec/fixtures/unit/pops/loaders/loaders/module_no_lib/modules/modulea/manifests/init.pp +3 -0
  149. data/spec/fixtures/unit/pops/loaders/loaders/module_no_lib/modules/modulea/metadata.json +10 -0
  150. data/spec/fixtures/unit/pops/loaders/loaders/single_module/modules/modulea/functions/hello.pp +3 -0
  151. data/spec/fixtures/unit/pops/loaders/loaders/single_module/modules/modulea/functions/subspace/hello.pp +3 -0
  152. data/spec/fixtures/unit/pops/loaders/loaders/single_module/modules/modulea/metadata.json +1 -10
  153. data/spec/fixtures/unit/provider/mount/parsed/aix.filesystems +93 -85
  154. data/spec/fixtures/unit/provider/mount/parsed/aix.mount +11 -7
  155. data/spec/fixtures/unit/provider/package/pkgng/pkg.info +8 -0
  156. data/spec/fixtures/unit/provider/package/pkgng/pkg.query +1 -0
  157. data/spec/fixtures/unit/provider/package/pkgng/pkg.query_absent +1 -0
  158. data/spec/fixtures/unit/provider/package/pkgng/pkg.version +3 -0
  159. data/spec/fixtures/unit/provider/package/zypper/zypper-list-updates-empty.out +3 -0
  160. data/spec/integration/application/apply_spec.rb +49 -0
  161. data/spec/integration/faces/plugin_spec.rb +0 -4
  162. data/spec/integration/indirector/facts/facter_spec.rb +59 -0
  163. data/spec/integration/parser/compiler_spec.rb +850 -0
  164. data/spec/integration/parser/resource_expressions_spec.rb +3 -0
  165. data/spec/integration/parser/scope_spec.rb +26 -5
  166. data/spec/integration/transaction_spec.rb +1 -1
  167. data/spec/integration/type/file_spec.rb +318 -41
  168. data/spec/integration/util/windows/security_spec.rb +14 -5
  169. data/spec/lib/matchers/resource.rb +22 -1
  170. data/spec/lib/puppet_spec/matchers.rb +6 -4
  171. data/spec/unit/application/master_spec.rb +33 -7
  172. data/spec/unit/data_providers/function_data_provider_spec.rb +10 -1
  173. data/spec/unit/file_serving/metadata_spec.rb +1 -1
  174. data/spec/unit/file_serving/terminus_helper_spec.rb +2 -3
  175. data/spec/unit/file_system_spec.rb +38 -0
  176. data/spec/unit/functions/defined_spec.rb +289 -0
  177. data/spec/unit/functions/hiera_spec.rb +8 -6
  178. data/spec/unit/functions/regsubst_spec.rb +4 -0
  179. data/spec/unit/functions/split_spec.rb +8 -0
  180. data/spec/unit/functions4_spec.rb +97 -2
  181. data/spec/unit/indirector/facts/facter_spec.rb +7 -0
  182. data/spec/unit/node_spec.rb +6 -0
  183. data/spec/unit/parser/functions/file_spec.rb +7 -1
  184. data/spec/unit/parser/functions/template_spec.rb +1 -1
  185. data/spec/unit/parser/scope_spec.rb +2 -2
  186. data/spec/unit/parser/templatewrapper_spec.rb +1 -1
  187. data/spec/unit/pops/evaluator/access_ops_spec.rb +19 -0
  188. data/spec/unit/pops/evaluator/evaluating_parser_spec.rb +84 -18
  189. data/spec/unit/pops/evaluator/variables_spec.rb +1 -1
  190. data/spec/unit/pops/issues_spec.rb +16 -16
  191. data/spec/unit/pops/loaders/loaders_spec.rb +106 -48
  192. data/spec/unit/pops/migration_spec.rb +53 -0
  193. data/spec/unit/pops/parser/lexer2_spec.rb +142 -1
  194. data/spec/unit/pops/parser/parse_heredoc_spec.rb +26 -0
  195. data/spec/unit/pops/types/type_calculator_spec.rb +205 -12
  196. data/spec/unit/pops/validation_spec.rb +66 -0
  197. data/spec/unit/pops/validator/validator_spec.rb +1 -1
  198. data/spec/unit/provider/group/windows_adsi_spec.rb +57 -9
  199. data/spec/unit/provider/mount/parsed_spec.rb +31 -5
  200. data/spec/unit/provider/package/apt_spec.rb +5 -0
  201. data/spec/unit/provider/package/pip_spec.rb +9 -0
  202. data/spec/unit/provider/package/pkgng_spec.rb +172 -0
  203. data/spec/unit/provider/package/windows/exe_package_spec.rb +0 -1
  204. data/spec/unit/provider/package/windows/msi_package_spec.rb +0 -1
  205. data/spec/unit/provider/package/zypper_spec.rb +50 -19
  206. data/spec/unit/provider/scheduled_task/win32_taskscheduler_spec.rb +312 -70
  207. data/spec/unit/provider/service/base_spec.rb +38 -27
  208. data/spec/unit/provider/service/debian_spec.rb +8 -0
  209. data/spec/unit/provider/service/freebsd_spec.rb +1 -0
  210. data/spec/unit/provider/service/gentoo_spec.rb +1 -0
  211. data/spec/unit/provider/service/init_spec.rb +18 -0
  212. data/spec/unit/provider/service/openbsd_spec.rb +1 -0
  213. data/spec/unit/provider/service/redhat_spec.rb +1 -0
  214. data/spec/unit/provider/user/windows_adsi_spec.rb +134 -5
  215. data/spec/unit/settings_spec.rb +11 -0
  216. data/spec/unit/util/log_spec.rb +113 -0
  217. data/spec/unit/util/windows/adsi_spec.rb +135 -41
  218. data/spec/unit/util/windows/sid_spec.rb +0 -10
  219. metadata +48 -2
@@ -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
+ expect(dump(parse(src))).to eq([
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
+ expect(dump(parse(src))).to eq([
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)
@@ -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.type }.sort {|a,b| a.to_s <=> b.to_s }
398
+ els = t.elements.map { |e| e.value_type }.sort {|a,b| a.to_s <=> b.to_s }
393
399
  expect(els[0].class).to eq(Puppet::Pops::Types::PStringType)
394
400
  expect(els[1].class).to eq(Puppet::Pops::Types::PTupleType)
395
401
  end
@@ -471,6 +477,45 @@ describe 'The type calculator' do
471
477
  expect(calculator.string(calculator.common_type(r1, r2))).to eq("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| expect(t2.new).to 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| expect(t).not_to 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| expect(t).not_to 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| expect(t).not_to 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| expect(t).not_to 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| expect(t).not_to 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| expect(t).not_to 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| expect(t).not_to 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| expect(t).not_to 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| expect(t).not_to 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,8 +926,10 @@ 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]
796
- tested_types.each {|t2| expect(t).not_to be_assignable_to(t2.new) }
929
+ Puppet::Pops::Types::PAnyType,
930
+ Puppet::Pops::Types::POptionalType,
931
+ Puppet::Pops::Types::PNotUndefType]
932
+ tested_types.each {|t2| expect(t).to_not be_assignable_to(t2.new) }
797
933
  end
798
934
  end
799
935
 
@@ -1231,7 +1367,7 @@ describe 'The type calculator' do
1231
1367
  expect(calculator.instance?(Puppet::Pops::Types::POptionalType.new(), :undef)).to eq(true)
1232
1368
  end
1233
1369
 
1234
- it 'should not consider undef to be an instance of any other type than Any, NilType and Data' do
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
  expect(calculator.instance?(Puppet::Pops::Types::PAnyType.new(), :default)).to eq(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
  expect(calculator.instance?(range, 'abcd')).to eq(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
  expect(calculator.instance?(range, [1])).to eq(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
  expect(calculator.instance?(struct, {'a'=>1, 'b'=>'a', 'c'=>'x'})).to eq(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
@@ -1722,6 +1886,21 @@ describe 'The type calculator' do
1722
1886
  it "should yield Unit for a Unit type" do
1723
1887
  expect(calculator.string(unit_t)).to eql('Unit')
1724
1888
  end
1889
+
1890
+ it "should yield 'NotUndef' for a PNotUndefType" do
1891
+ t = not_undef_t
1892
+ expect(calculator.string(t)).to eq('NotUndef')
1893
+ end
1894
+
1895
+ it "should yield 'NotUndef[T]' for a PNotUndefType[T]" do
1896
+ t = not_undef_t(data_t)
1897
+ expect(calculator.string(t)).to eq('NotUndef[Data]')
1898
+ end
1899
+
1900
+ it "should yield 'NotUndef['string']' for a PNotUndefType['string']" do
1901
+ t = not_undef_t('hey')
1902
+ expect(calculator.string(t)).to eq("NotUndef['hey']")
1903
+ end
1725
1904
  end
1726
1905
 
1727
1906
  context 'when processing meta type' do
@@ -1865,7 +2044,7 @@ describe 'The type calculator' do
1865
2044
  expect(generic.element_type.values).to eq([])
1866
2045
  end
1867
2046
 
1868
- it "a generic result is created by generalize! given an instance specific result for a Hash" do
2047
+ it 'a generic result is created by generalize! given an instance specific result for a Hash' do
1869
2048
  generic = calculator.infer({'a' =>1,'b' => 2})
1870
2049
  expect(generic.key_type.values.sort).to eq(['a', 'b'])
1871
2050
  expect(generic.element_type.from).to eq(1)
@@ -1876,6 +2055,20 @@ describe 'The type calculator' do
1876
2055
  expect(generic.element_type.to).to eq(nil)
1877
2056
  end
1878
2057
 
2058
+ it 'ensures that Struct key types are not generalized' do
2059
+ generic = calculator.generalize!(struct_t({'a' => object_t}))
2060
+ expect(calculator.string(generic)).to eq("Struct[{'a'=>Any}]")
2061
+ generic = calculator.generalize!(struct_t({not_undef_t('a') => object_t}))
2062
+ expect(calculator.string(generic)).to eq("Struct[{NotUndef['a']=>Any}]")
2063
+ generic = calculator.generalize!(struct_t({optional_t('a') => string_t}))
2064
+ expect(calculator.string(generic)).to eq("Struct[{Optional['a']=>String}]")
2065
+ end
2066
+
2067
+ it 'ensures that Struct value types are generalized' do
2068
+ generic = calculator.generalize!(struct_t({'a' => range_t(1, 3)}))
2069
+ expect(calculator.string(generic)).to eq("Struct[{'a'=>Integer}]")
2070
+ end
2071
+
1879
2072
  it "does not reduce by combining types when using infer_set" do
1880
2073
  element_type = calculator.infer(['a','b',1,2]).element_type
1881
2074
  expect(element_type.class).to eq(Puppet::Pops::Types::PScalarType)
@@ -1981,7 +2174,7 @@ describe 'The type calculator' do
1981
2174
  end
1982
2175
 
1983
2176
  matcher :be_assignable_to do |type|
1984
- calc = Puppet::Pops::Types::TypeCalculator.new
2177
+ calc = Puppet::Pops::Types::TypeCalculator.singleton
1985
2178
 
1986
2179
  match do |actual|
1987
2180
  calc.assignable?(type, actual)
@@ -0,0 +1,66 @@
1
+ require 'spec_helper'
2
+ require 'puppet/pops'
3
+
4
+ describe 'Puppet::Pops::Validation::Diagnostic' do
5
+
6
+ # Mocks a SourcePosAdapter as it is used in these use cases
7
+ # of a Diagnostic
8
+ #
9
+ class MockSourcePos
10
+ attr_reader :offset
11
+ def initialize(offset)
12
+ @offset = offset
13
+ end
14
+ end
15
+
16
+ it "computes equal hash value ignoring arguments" do
17
+ issue = Puppet::Pops::Issues::DIV_BY_ZERO
18
+ source_pos = MockSourcePos.new(10)
19
+ d1 = Puppet::Pops::Validation::Diagnostic.new(:warning, issue, "foo", source_pos, {:foo => 10})
20
+ d2 = Puppet::Pops::Validation::Diagnostic.new(:warning, issue, "foo", source_pos.clone, {:bar => 20})
21
+ expect(d1.hash).to eql(d2.hash)
22
+ end
23
+
24
+ it "computes non equal hash value for different severities" do
25
+ issue = Puppet::Pops::Issues::DIV_BY_ZERO
26
+ source_pos = MockSourcePos.new(10)
27
+ d1 = Puppet::Pops::Validation::Diagnostic.new(:warning, issue, "foo", source_pos, {})
28
+ d2 = Puppet::Pops::Validation::Diagnostic.new(:error, issue, "foo", source_pos.clone, {})
29
+ expect(d1.hash).to_not eql(d2.hash)
30
+ end
31
+
32
+ it "computes non equal hash value for different offsets" do
33
+ issue = Puppet::Pops::Issues::DIV_BY_ZERO
34
+ source_pos1 = MockSourcePos.new(10)
35
+ source_pos2 = MockSourcePos.new(11)
36
+ d1 = Puppet::Pops::Validation::Diagnostic.new(:warning, issue, "foo", source_pos1, {})
37
+ d2 = Puppet::Pops::Validation::Diagnostic.new(:warning, issue, "foo", source_pos2, {})
38
+ expect(d1.hash).to_not eql(d2.hash)
39
+ end
40
+
41
+ it "can be used in a set" do
42
+ the_set = Set.new()
43
+ issue = Puppet::Pops::Issues::DIV_BY_ZERO
44
+ source_pos = MockSourcePos.new(10)
45
+ d1 = Puppet::Pops::Validation::Diagnostic.new(:warning, issue, "foo", source_pos, {})
46
+ d2 = Puppet::Pops::Validation::Diagnostic.new(:warning, issue, "foo", source_pos.clone, {})
47
+ d3 = Puppet::Pops::Validation::Diagnostic.new(:error, issue, "foo", source_pos.clone, {})
48
+ expect(the_set.add?(d1)).to_not be_nil
49
+ expect(the_set.add?(d2)).to be_nil
50
+ expect(the_set.add?(d3)).to_not be_nil
51
+ end
52
+
53
+ end
54
+
55
+ describe "Puppet::Pops::Validation::SeverityProducer" do
56
+ it 'sets default severity given in initializer' do
57
+ producer = Puppet::Pops::Validation::SeverityProducer.new(:warning)
58
+ expect(producer.severity(Puppet::Pops::Issues::DIV_BY_ZERO)).to be(:warning)
59
+ end
60
+
61
+ it 'sets default severity to :error if not given' do
62
+ producer = Puppet::Pops::Validation::SeverityProducer.new()
63
+ expect(producer.severity(Puppet::Pops::Issues::DIV_BY_ZERO)).to be(:error)
64
+ end
65
+
66
+ end