puppet 4.7.1-universal-darwin → 4.8.0-universal-darwin

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 (276) hide show
  1. data/Gemfile +0 -3
  2. data/MAINTAINERS +76 -0
  3. data/README.md +0 -6
  4. data/Rakefile +2 -2
  5. data/lib/puppet/agent.rb +3 -3
  6. data/lib/puppet/application/apply.rb +1 -1
  7. data/lib/puppet/configurer.rb +2 -2
  8. data/lib/puppet/data_providers.rb +1 -0
  9. data/lib/puppet/data_providers/data_adapter.rb +1 -0
  10. data/lib/puppet/data_providers/data_function_support.rb +1 -0
  11. data/lib/puppet/data_providers/function_env_data_provider.rb +1 -0
  12. data/lib/puppet/data_providers/function_module_data_provider.rb +1 -0
  13. data/lib/puppet/data_providers/hiera_config.rb +1 -0
  14. data/lib/puppet/data_providers/hiera_env_data_provider.rb +1 -0
  15. data/lib/puppet/data_providers/hiera_interpolate.rb +1 -0
  16. data/lib/puppet/data_providers/hiera_module_data_provider.rb +1 -0
  17. data/lib/puppet/data_providers/hiera_support.rb +1 -2
  18. data/lib/puppet/data_providers/json_data_provider_factory.rb +2 -0
  19. data/lib/puppet/data_providers/yaml_data_provider_factory.rb +2 -0
  20. data/lib/puppet/defaults.rb +20 -1
  21. data/lib/puppet/environments.rb +5 -2
  22. data/lib/puppet/face/catalog.rb +1 -1
  23. data/lib/puppet/face/epp.rb +57 -11
  24. data/lib/puppet/face/module/install.rb +6 -6
  25. data/lib/puppet/functions.rb +23 -24
  26. data/lib/puppet/functions/alert.rb +14 -0
  27. data/lib/puppet/functions/binary_file.rb +25 -0
  28. data/lib/puppet/functions/break.rb +22 -0
  29. data/lib/puppet/functions/contain.rb +33 -0
  30. data/lib/puppet/functions/crit.rb +14 -0
  31. data/lib/puppet/functions/debug.rb +14 -0
  32. data/lib/puppet/functions/emerg.rb +14 -0
  33. data/lib/puppet/functions/epp.rb +1 -1
  34. data/lib/puppet/functions/err.rb +14 -0
  35. data/lib/puppet/functions/find_file.rb +31 -0
  36. data/lib/puppet/functions/include.rb +21 -0
  37. data/lib/puppet/functions/info.rb +14 -0
  38. data/lib/puppet/functions/new.rb +1 -1
  39. data/lib/puppet/functions/next.rb +23 -0
  40. data/lib/puppet/functions/notice.rb +14 -0
  41. data/lib/puppet/functions/regsubst.rb +12 -16
  42. data/lib/puppet/functions/require.rb +37 -0
  43. data/lib/puppet/functions/return.rb +22 -0
  44. data/lib/puppet/functions/strftime.rb +35 -0
  45. data/lib/puppet/functions/warning.rb +14 -0
  46. data/lib/puppet/generate/models/type/type.rb +4 -0
  47. data/lib/puppet/generate/templates/type/pcore.erb +2 -1
  48. data/lib/puppet/indirector/face.rb +6 -1
  49. data/lib/puppet/network/http/error.rb +2 -2
  50. data/lib/puppet/network/http/handler.rb +2 -2
  51. data/lib/puppet/node/environment.rb +11 -0
  52. data/lib/puppet/parser/ast.rb +5 -0
  53. data/lib/puppet/parser/ast/pops_bridge.rb +17 -4
  54. data/lib/puppet/parser/compiler.rb +29 -1
  55. data/lib/puppet/parser/functions.rb +6 -0
  56. data/lib/puppet/parser/functions/assert_type.rb +1 -1
  57. data/lib/puppet/parser/functions/binary_file.rb +24 -0
  58. data/lib/puppet/parser/functions/break.rb +39 -0
  59. data/lib/puppet/parser/functions/contain.rb +7 -15
  60. data/lib/puppet/parser/functions/defined.rb +2 -2
  61. data/lib/puppet/parser/functions/dig.rb +1 -1
  62. data/lib/puppet/parser/functions/each.rb +1 -1
  63. data/lib/puppet/parser/functions/epp.rb +2 -2
  64. data/lib/puppet/parser/functions/filter.rb +1 -1
  65. data/lib/puppet/parser/functions/find_file.rb +28 -0
  66. data/lib/puppet/parser/functions/hiera.rb +4 -4
  67. data/lib/puppet/parser/functions/hiera_array.rb +1 -1
  68. data/lib/puppet/parser/functions/hiera_hash.rb +1 -1
  69. data/lib/puppet/parser/functions/hiera_include.rb +1 -1
  70. data/lib/puppet/parser/functions/include.rb +4 -8
  71. data/lib/puppet/parser/functions/inline_epp.rb +1 -1
  72. data/lib/puppet/parser/functions/lest.rb +1 -1
  73. data/lib/puppet/parser/functions/lookup.rb +4 -2
  74. data/lib/puppet/parser/functions/map.rb +1 -1
  75. data/lib/puppet/parser/functions/match.rb +1 -1
  76. data/lib/puppet/parser/functions/new.rb +414 -18
  77. data/lib/puppet/parser/functions/next.rb +38 -0
  78. data/lib/puppet/parser/functions/reduce.rb +1 -1
  79. data/lib/puppet/parser/functions/regsubst.rb +4 -2
  80. data/lib/puppet/parser/functions/require.rb +4 -27
  81. data/lib/puppet/parser/functions/return.rb +71 -0
  82. data/lib/puppet/parser/functions/reverse_each.rb +1 -1
  83. data/lib/puppet/parser/functions/scanf.rb +13 -8
  84. data/lib/puppet/parser/functions/slice.rb +1 -1
  85. data/lib/puppet/parser/functions/split.rb +1 -1
  86. data/lib/puppet/parser/functions/step.rb +1 -1
  87. data/lib/puppet/parser/functions/strftime.rb +185 -0
  88. data/lib/puppet/parser/functions/then.rb +1 -1
  89. data/lib/puppet/parser/functions/type.rb +1 -1
  90. data/lib/puppet/parser/functions/with.rb +3 -3
  91. data/lib/puppet/parser/resource.rb +8 -5
  92. data/lib/puppet/parser/scope.rb +1 -1
  93. data/lib/puppet/plugins/configuration.rb +8 -0
  94. data/lib/puppet/plugins/data_providers.rb +1 -0
  95. data/lib/puppet/plugins/data_providers/data_provider.rb +7 -28
  96. data/lib/puppet/plugins/data_providers/registry.rb +1 -0
  97. data/lib/puppet/pops.rb +4 -0
  98. data/lib/puppet/pops/evaluator/access_operator.rb +36 -5
  99. data/lib/puppet/pops/evaluator/closure.rb +81 -12
  100. data/lib/puppet/pops/evaluator/compare_operator.rb +24 -1
  101. data/lib/puppet/pops/evaluator/evaluator_impl.rb +29 -5
  102. data/lib/puppet/pops/evaluator/json_strict_literal_evaluator.rb +1 -1
  103. data/lib/puppet/pops/evaluator/runtime3_converter.rb +53 -62
  104. data/lib/puppet/pops/evaluator/runtime3_support.rb +15 -6
  105. data/lib/puppet/pops/functions/dispatch.rb +9 -2
  106. data/lib/puppet/pops/functions/dispatcher.rb +3 -1
  107. data/lib/puppet/pops/functions/function.rb +19 -2
  108. data/lib/puppet/pops/issues.rb +9 -0
  109. data/lib/puppet/pops/label_provider.rb +2 -2
  110. data/lib/puppet/pops/loader/loader.rb +17 -0
  111. data/lib/puppet/pops/loader/static_loader.rb +0 -41
  112. data/lib/puppet/pops/lookup.rb +12 -0
  113. data/lib/puppet/pops/lookup/context.rb +86 -0
  114. data/lib/puppet/pops/lookup/explainer.rb +46 -6
  115. data/lib/puppet/pops/lookup/invocation.rb +19 -0
  116. data/lib/puppet/pops/lookup/sub_lookup.rb +1 -1
  117. data/lib/puppet/pops/model/factory.rb +20 -8
  118. data/lib/puppet/pops/model/model_label_provider.rb +3 -0
  119. data/lib/puppet/pops/model/model_meta.rb +2 -0
  120. data/lib/puppet/pops/model/model_tree_dumper.rb +14 -0
  121. data/lib/puppet/pops/parser/egrammar.ra +11 -6
  122. data/lib/puppet/pops/parser/eparser.rb +1112 -1086
  123. data/lib/puppet/pops/parser/heredoc_support.rb +1 -2
  124. data/lib/puppet/pops/pcore.rb +1 -0
  125. data/lib/puppet/pops/puppet_stack.rb +3 -3
  126. data/lib/puppet/pops/resource/param.rb +5 -1
  127. data/lib/puppet/pops/resource/resource_type_impl.rb +8 -4
  128. data/lib/puppet/pops/resource/resource_type_set.pcore +1 -0
  129. data/lib/puppet/pops/serialization/abstract_reader.rb +19 -2
  130. data/lib/puppet/pops/serialization/abstract_writer.rb +16 -3
  131. data/lib/puppet/pops/serialization/deserializer.rb +5 -1
  132. data/lib/puppet/pops/serialization/extension.rb +2 -0
  133. data/lib/puppet/pops/serialization/json.rb +76 -26
  134. data/lib/puppet/pops/serialization/serializer.rb +5 -1
  135. data/lib/puppet/pops/serialization/time_factory.rb +2 -1
  136. data/lib/puppet/pops/time/timespan.rb +718 -0
  137. data/lib/puppet/pops/time/timestamp.rb +148 -0
  138. data/lib/puppet/pops/types/p_binary_type.rb +220 -0
  139. data/lib/puppet/pops/types/p_object_type.rb +12 -6
  140. data/lib/puppet/pops/types/p_sensitive_type.rb +5 -1
  141. data/lib/puppet/pops/types/p_timespan_type.rb +141 -0
  142. data/lib/puppet/pops/types/p_timestamp_type.rb +69 -0
  143. data/lib/puppet/pops/types/string_converter.rb +62 -0
  144. data/lib/puppet/pops/types/type_asserter.rb +1 -1
  145. data/lib/puppet/pops/types/type_calculator.rb +17 -3
  146. data/lib/puppet/pops/types/type_factory.rb +35 -1
  147. data/lib/puppet/pops/types/type_formatter.rb +64 -11
  148. data/lib/puppet/pops/types/type_mismatch_describer.rb +110 -61
  149. data/lib/puppet/pops/types/type_parser.rb +18 -4
  150. data/lib/puppet/pops/types/types.rb +98 -63
  151. data/lib/puppet/pops/validation.rb +9 -1
  152. data/lib/puppet/pops/validation/checker4_0.rb +7 -0
  153. data/lib/puppet/property.rb +1 -1
  154. data/lib/puppet/provider.rb +3 -6
  155. data/lib/puppet/provider/mcx/mcxcontent.rb +1 -1
  156. data/lib/puppet/provider/mount/parsed.rb +18 -4
  157. data/lib/puppet/provider/nameservice/directoryservice.rb +15 -7
  158. data/lib/puppet/provider/package/gem.rb +6 -1
  159. data/lib/puppet/provider/package/pip.rb +0 -1
  160. data/lib/puppet/provider/package/pkg.rb +5 -1
  161. data/lib/puppet/provider/package/pkgng.rb +1 -1
  162. data/lib/puppet/provider/package/yum.rb +10 -0
  163. data/lib/puppet/provider/service/launchd.rb +1 -0
  164. data/lib/puppet/provider/user/directoryservice.rb +6 -6
  165. data/lib/puppet/provider/yumrepo/inifile.rb +1 -1
  166. data/lib/puppet/provider/zpool/zpool.rb +1 -1
  167. data/lib/puppet/resource.rb +54 -12
  168. data/lib/puppet/resource/capability_finder.rb +15 -9
  169. data/lib/puppet/resource/catalog.rb +25 -6
  170. data/lib/puppet/resource/type.rb +3 -1
  171. data/lib/puppet/settings.rb +1 -1
  172. data/lib/puppet/settings/environment_conf.rb +12 -4
  173. data/lib/puppet/syntax_checkers/base64.rb +41 -0
  174. data/lib/puppet/syntax_checkers/json.rb +0 -2
  175. data/lib/puppet/transaction.rb +6 -0
  176. data/lib/puppet/transaction/additional_resource_generator.rb +5 -0
  177. data/lib/puppet/transaction/report.rb +7 -2
  178. data/lib/puppet/type.rb +2 -1
  179. data/lib/puppet/type/file/checksum.rb +1 -0
  180. data/lib/puppet/type/file/content.rb +4 -4
  181. data/lib/puppet/type/mount.rb +44 -0
  182. data/lib/puppet/type/ssh_authorized_key.rb +1 -1
  183. data/lib/puppet/type/tidy.rb +3 -0
  184. data/lib/puppet/type/user.rb +12 -6
  185. data/lib/puppet/util/log.rb +25 -0
  186. data/lib/puppet/util/plist.rb +8 -3
  187. data/lib/puppet/version.rb +1 -1
  188. data/lib/puppet_x.rb +7 -1
  189. data/spec/integration/application/apply_spec.rb +118 -0
  190. data/spec/integration/parser/compiler_spec.rb +28 -0
  191. data/spec/integration/parser/pcore_resource_spec.rb +40 -3
  192. data/spec/integration/provider/mount_spec.rb +2 -1
  193. data/spec/integration/util/windows/principal_spec.rb +2 -2
  194. data/spec/integration/util/windows/registry_spec.rb +4 -4
  195. data/spec/lib/puppet_spec/compiler.rb +5 -1
  196. data/spec/lib/puppet_spec/unindent.rb +5 -0
  197. data/spec/shared_contexts/types_setup.rb +6 -0
  198. data/spec/shared_examples/rhel_package_provider.rb +16 -0
  199. data/spec/spec_helper.rb +1 -0
  200. data/spec/unit/agent_spec.rb +11 -0
  201. data/spec/unit/application/lookup_spec.rb +94 -3
  202. data/spec/unit/capability_spec.rb +22 -0
  203. data/spec/unit/configurer_spec.rb +8 -0
  204. data/spec/unit/face/epp_face_spec.rb +22 -3
  205. data/spec/unit/functions/assert_type_spec.rb +3 -3
  206. data/spec/unit/functions/binary_file_spec.rb +46 -0
  207. data/spec/unit/functions/break_spec.rb +89 -0
  208. data/spec/unit/{parser/functions → functions}/contain_spec.rb +68 -3
  209. data/spec/unit/functions/find_file_spec.rb +69 -0
  210. data/spec/unit/functions/include_spec.rb +175 -0
  211. data/spec/unit/functions/logging_spec.rb +54 -0
  212. data/spec/unit/functions/lookup_spec.rb +3 -3
  213. data/spec/unit/functions/new_spec.rb +105 -5
  214. data/spec/unit/functions/next_spec.rb +93 -0
  215. data/spec/unit/functions/require_spec.rb +83 -0
  216. data/spec/unit/functions/return_spec.rb +105 -0
  217. data/spec/unit/{parser/functions → functions}/shared.rb +14 -11
  218. data/spec/unit/functions/strftime_spec.rb +152 -0
  219. data/spec/unit/functions4_spec.rb +22 -0
  220. data/spec/unit/indirector/face_spec.rb +10 -2
  221. data/spec/unit/network/http/error_spec.rb +1 -2
  222. data/spec/unit/network/http/handler_spec.rb +6 -5
  223. data/spec/unit/parser/functions/hiera_array_spec.rb +1 -1
  224. data/spec/unit/parser/functions/hiera_hash_spec.rb +1 -1
  225. data/spec/unit/parser/functions/hiera_include_spec.rb +1 -1
  226. data/spec/unit/parser/functions/hiera_spec.rb +1 -1
  227. data/spec/unit/parser/functions/lookup_spec.rb +1 -1
  228. data/spec/unit/parser/functions/regsubst_spec.rb +1 -1
  229. data/spec/unit/parser/functions/split_spec.rb +1 -1
  230. data/spec/unit/pops/evaluator/access_ops_spec.rb +81 -1
  231. data/spec/unit/pops/evaluator/arithmetic_ops_spec.rb +170 -0
  232. data/spec/unit/pops/evaluator/evaluating_parser_spec.rb +29 -4
  233. data/spec/unit/pops/evaluator/runtime3_converter_spec.rb +112 -4
  234. data/spec/unit/pops/loaders/dependency_loader_spec.rb +12 -0
  235. data/spec/unit/pops/loaders/static_loader_spec.rb +0 -26
  236. data/spec/unit/pops/lookup/context_spec.rb +149 -0
  237. data/spec/unit/pops/parser/parse_functions_spec.rb +19 -0
  238. data/spec/unit/pops/parser/parse_lambda_spec.rb +19 -0
  239. data/spec/unit/pops/puppet_stack_spec.rb +1 -1
  240. data/spec/unit/pops/resource/resource_type_impl_spec.rb +74 -0
  241. data/spec/unit/pops/serialization/packer_spec.rb +34 -14
  242. data/spec/unit/pops/serialization/serialization_spec.rb +67 -5
  243. data/spec/unit/pops/time/timespan_spec.rb +121 -0
  244. data/spec/unit/pops/types/p_binary_type_spec.rb +243 -0
  245. data/spec/unit/pops/types/p_object_type_spec.rb +7 -7
  246. data/spec/unit/pops/types/p_sensitive_type_spec.rb +1 -1
  247. data/spec/unit/pops/types/p_timespan_type_spec.rb +273 -0
  248. data/spec/unit/pops/types/p_timestamp_type_spec.rb +311 -0
  249. data/spec/unit/pops/types/p_type_set_type_spec.rb +13 -13
  250. data/spec/unit/pops/types/ruby_generator_spec.rb +12 -12
  251. data/spec/unit/pops/types/string_converter_spec.rb +89 -0
  252. data/spec/unit/pops/types/type_asserter_spec.rb +3 -3
  253. data/spec/unit/pops/types/type_calculator_spec.rb +113 -5
  254. data/spec/unit/pops/types/type_formatter_spec.rb +40 -0
  255. data/spec/unit/pops/types/type_mismatch_describer_spec.rb +49 -38
  256. data/spec/unit/pops/types/type_parser_spec.rb +87 -4
  257. data/spec/unit/pops/types/types_spec.rb +1 -1
  258. data/spec/unit/pops/validator/validator_spec.rb +23 -0
  259. data/spec/unit/provider/mount/parsed_spec.rb +47 -29
  260. data/spec/unit/provider/package/pkg_spec.rb +109 -99
  261. data/spec/unit/provider/ssh_authorized_key/parsed_spec.rb +1 -0
  262. data/spec/unit/provider/user/aix_spec.rb +1 -1
  263. data/spec/unit/provider/user/directoryservice_spec.rb +101 -30
  264. data/spec/unit/resource/capability_finder_spec.rb +29 -7
  265. data/spec/unit/resource/catalog_spec.rb +127 -0
  266. data/spec/unit/ssl/certificate_request_spec.rb +1 -1
  267. data/spec/unit/transaction/additional_resource_generator_spec.rb +30 -0
  268. data/spec/unit/transaction/persistence_spec.rb +1 -6
  269. data/spec/unit/transaction/report_spec.rb +23 -0
  270. data/spec/unit/transaction_spec.rb +38 -0
  271. data/spec/unit/type/mount_spec.rb +5 -0
  272. data/spec/unit/util/plist_spec.rb +14 -2
  273. metadata +71 -12
  274. data/spec/integration/parser/functions/require_spec.rb +0 -43
  275. data/spec/unit/parser/functions/include_spec.rb +0 -55
  276. data/spec/unit/parser/functions/require_spec.rb +0 -68
@@ -5,6 +5,7 @@ describe 'The string converter' do
5
5
  let(:converter) { Puppet::Pops::Types::StringConverter.singleton }
6
6
  let(:factory) { Puppet::Pops::Types::TypeFactory }
7
7
  let(:format) { Puppet::Pops::Types::StringConverter::Format }
8
+ let(:binary) { Puppet::Pops::Types::PBinaryType::Binary }
8
9
 
9
10
  describe 'helper Format' do
10
11
  it 'parses a single character like "%d" as a format' do
@@ -903,6 +904,94 @@ describe 'The string converter' do
903
904
  end
904
905
  end
905
906
 
907
+ context 'when converting binary' do
908
+ let(:sample) { binary.from_binary_string('binary') }
909
+
910
+ it 'the binary is converted to strict base64 string unquoted by default (same as %B)' do
911
+ expect(converter.convert(sample, :default)).to eq("YmluYXJ5")
912
+ end
913
+
914
+ it 'the binary is converted using %p by default when contained in an array' do
915
+ expect(converter.convert([sample], :default)).to eq("[Binary(\"YmluYXJ5\")]")
916
+ end
917
+
918
+ it '%B formats in base64 strict mode (same as default)' do
919
+ string_formats = { Puppet::Pops::Types::PBinaryType::DEFAULT => '%B'}
920
+ expect(converter.convert(sample, string_formats)).to eq("YmluYXJ5")
921
+ end
922
+
923
+ it '%b formats in base64 relaxed mode, and adds newline' do
924
+ string_formats = { Puppet::Pops::Types::PBinaryType::DEFAULT => '%b'}
925
+ expect(converter.convert(sample, string_formats)).to eq("YmluYXJ5\n")
926
+ end
927
+
928
+ it '%u formats in base64 urlsafe mode' do
929
+ string_formats = { Puppet::Pops::Types::PBinaryType::DEFAULT => '%u'}
930
+ expect(converter.convert(binary.from_base64("++//"), string_formats)).to eq("--__")
931
+ end
932
+
933
+ it '%p formats with type name' do
934
+ string_formats = { Puppet::Pops::Types::PBinaryType::DEFAULT => '%p'}
935
+ expect(converter.convert(sample, string_formats)).to eq("Binary(\"YmluYXJ5\")")
936
+ end
937
+
938
+ it '%#s formats as quoted string with escaped non printable bytes' do
939
+ string_formats = { Puppet::Pops::Types::PBinaryType::DEFAULT => '%#s'}
940
+ expect(converter.convert(binary.from_base64("apa="), string_formats)).to eq("\"j\\x96\"")
941
+ end
942
+
943
+ it '%s formats as unquoted string with valid UTF-8 chars' do
944
+ string_formats = { Puppet::Pops::Types::PBinaryType::DEFAULT => '%s'}
945
+ # womans hat emoji is E318, a three byte UTF-8 char EE 8C 98
946
+ expect(converter.convert(binary.from_binary_string("\xEE\x8C\x98"), string_formats)).to eq("\uE318")
947
+ end
948
+
949
+ it '%s errors if given non UTF-8 bytes' do
950
+ string_formats = { Puppet::Pops::Types::PBinaryType::DEFAULT => '%s'}
951
+ expect {
952
+ converter.convert(binary.from_base64("apa="), string_formats)
953
+ }.to raise_error(Encoding::UndefinedConversionError)
954
+ end
955
+
956
+ { "%s" => 'binary',
957
+ "%#s" => '"binary"',
958
+ "%8s" => ' binary',
959
+ "%.2s" => 'bi',
960
+ "%-8s" => 'binary ',
961
+ "%p" => 'Binary("YmluYXJ5")',
962
+ "%10p" => 'Binary(" YmluYXJ5")',
963
+ "%-10p" => 'Binary("YmluYXJ5 ")',
964
+ "%.2p" => 'Binary("Ym")',
965
+ "%b" => "YmluYXJ5\n",
966
+ "%11b" => " YmluYXJ5\n",
967
+ "%-11b" => "YmluYXJ5\n ",
968
+ "%.2b" => "Ym",
969
+ "%B" => "YmluYXJ5",
970
+ "%11B" => " YmluYXJ5",
971
+ "%-11B" => "YmluYXJ5 ",
972
+ "%.2B" => "Ym",
973
+ "%u" => "YmluYXJ5",
974
+ "%11u" => " YmluYXJ5",
975
+ "%-11u" => "YmluYXJ5 ",
976
+ "%.2u" => "Ym",
977
+ "%t" => 'Binary',
978
+ "%#t" => '"Binary"',
979
+ "%8t" => ' Binary',
980
+ "%-8t" => 'Binary ',
981
+ "%.3t" => 'Bin',
982
+ "%T" => 'BINARY',
983
+ "%#T" => '"BINARY"',
984
+ "%8T" => ' BINARY',
985
+ "%-8T" => 'BINARY ',
986
+ "%.3T" => 'BIN',
987
+ }.each do |fmt, result |
988
+ it "the format #{fmt} produces #{result}" do
989
+ string_formats = { Puppet::Pops::Types::PBinaryType::DEFAULT => fmt}
990
+ expect(converter.convert(sample, string_formats)).to eq(result)
991
+ end
992
+ end
993
+ end
994
+
906
995
  context 'when converting iterator' do
907
996
  it 'the iterator is transformed to an array and formatted using array rules' do
908
997
  itor = Puppet::Pops::Types::Iterator.new(Puppet::Pops::Types::PIntegerType::DEFAULT, [1,2,3]).reverse_each
@@ -8,19 +8,19 @@ describe 'the type asserter' do
8
8
  context 'when deferring formatting of subject'
9
9
  it 'can use an array' do
10
10
  expect{ asserter.assert_instance_of(['The %s in the %s', 'gizmo', 'gadget'], PIntegerType::DEFAULT, 'lens') }.to(
11
- raise_error(TypeAssertionError, 'The gizmo in the gadget had wrong type, expected an Integer value, got String'))
11
+ raise_error(TypeAssertionError, 'The gizmo in the gadget has wrong type, expects an Integer value, got String'))
12
12
  end
13
13
 
14
14
  it 'can use an array obtained from block' do
15
15
  expect do
16
16
  asserter.assert_instance_of('gizmo', PIntegerType::DEFAULT, 'lens') { |s| ['The %s in the %s', s, 'gadget'] }
17
- end.to(raise_error(TypeAssertionError, 'The gizmo in the gadget had wrong type, expected an Integer value, got String'))
17
+ end.to(raise_error(TypeAssertionError, 'The gizmo in the gadget has wrong type, expects an Integer value, got String'))
18
18
  end
19
19
 
20
20
  it 'can use an subject obtained from zero argument block' do
21
21
  expect do
22
22
  asserter.assert_instance_of(nil, PIntegerType::DEFAULT, 'lens') { 'The gizmo in the gadget' }
23
- end.to(raise_error(TypeAssertionError, 'The gizmo in the gadget had wrong type, expected an Integer value, got String'))
23
+ end.to(raise_error(TypeAssertionError, 'The gizmo in the gadget has wrong type, expects an Integer value, got String'))
24
24
  end
25
25
 
26
26
  it 'does not produce a string unless the assertion fails' do
@@ -214,6 +214,12 @@ describe 'The type calculator' do
214
214
  end
215
215
  end
216
216
 
217
+ context 'binary' do
218
+ it 'translates to PBinaryType' do
219
+ expect(calculator.infer(PBinaryType::Binary.from_binary_string("binary")).class).to eq(PBinaryType)
220
+ end
221
+ end
222
+
217
223
  context 'version' do
218
224
  it 'translates to PVersionType' do
219
225
  expect(calculator.infer(Semantic::Version.new(1,0,0)).class).to eq(PSemVerType)
@@ -233,6 +239,34 @@ describe 'The type calculator' do
233
239
  end
234
240
  end
235
241
 
242
+ context 'timespan' do
243
+ it 'translates to PTimespanType' do
244
+ expect(calculator.infer(Time::Timespan.from_fields_hash('days' => 2))).to be_a(PTimespanType)
245
+ end
246
+
247
+ it 'translates to a limited PTimespanType by infer_set' do
248
+ ts = Time::Timespan.from_fields_hash('days' => 2)
249
+ t = calculator.infer_set(ts)
250
+ expect(t.class).to eq(PTimespanType)
251
+ expect(t.from).to be(ts)
252
+ expect(t.to).to be(ts)
253
+ end
254
+ end
255
+
256
+ context 'timestamp' do
257
+ it 'translates to PTimespanType' do
258
+ expect(calculator.infer(Time::Timestamp.now)).to be_a(PTimestampType)
259
+ end
260
+
261
+ it 'translates to a limited PTimespanType by infer_set' do
262
+ ts = Time::Timestamp.now
263
+ t = calculator.infer_set(ts)
264
+ expect(t.class).to eq(PTimestampType)
265
+ expect(t.from).to be(ts)
266
+ expect(t.to).to be(ts)
267
+ end
268
+ end
269
+
236
270
  context 'array' do
237
271
  it 'translates to PArrayType' do
238
272
  expect(calculator.infer([1,2]).class).to eq(PArrayType)
@@ -559,6 +593,24 @@ describe 'The type calculator' do
559
593
  expect(common_t.param_types.class).to be(PTupleType)
560
594
  expect(common_t.block_type).to eql(callable_t(scalar_t))
561
595
  end
596
+
597
+ it 'return_type is included in the check (incompatible return_type)' do
598
+ t1 = callable_t([String], String)
599
+ t2 = callable_t([String], Integer)
600
+ common_t = calculator.common_type(t1, t2)
601
+ expect(common_t.class).to be(PCallableType)
602
+ expect(common_t.param_types).to be_nil
603
+ expect(common_t.return_type).to be_nil
604
+ end
605
+
606
+ it 'return_type is included in the check (compatible return_type)' do
607
+ t1 = callable_t([String], Numeric)
608
+ t2 = callable_t([String], Integer)
609
+ common_t = calculator.common_type(t1, t2)
610
+ expect(common_t.class).to be(PCallableType)
611
+ expect(common_t.param_types).to be_a(PTupleType)
612
+ expect(common_t.return_type).to eql(PNumericType::DEFAULT)
613
+ end
562
614
  end
563
615
  end
564
616
 
@@ -864,6 +916,34 @@ describe 'The type calculator' do
864
916
  end
865
917
  end
866
918
 
919
+ context 'for Timespan such that' do
920
+ it 'Timespan is assignable to less constrained Timespan' do
921
+ t1 = PTimespanType.new('00:00:10', '00:00:20')
922
+ t2 = PTimespanType.new('00:00:11', '00:00:19')
923
+ expect(t2).to be_assignable_to(t1)
924
+ end
925
+
926
+ it 'Timespan is not assignable to more constrained Timespan' do
927
+ t1 = PTimespanType.new('00:00:10', '00:00:20')
928
+ t2 = PTimespanType.new('00:00:11', '00:00:19')
929
+ expect(t1).not_to be_assignable_to(t2)
930
+ end
931
+ end
932
+
933
+ context 'for Timestamp such that' do
934
+ it 'Timestamp is assignable to less constrained Timestamp' do
935
+ t1 = PTimestampType.new('2016-01-01', '2016-12-31')
936
+ t2 = PTimestampType.new('2016-02-01', '2016-11-30')
937
+ expect(t2).to be_assignable_to(t1)
938
+ end
939
+
940
+ it 'Timestamp is not assignable to more constrained Timestamp' do
941
+ t1 = PTimestampType.new('2016-01-01', '2016-12-31')
942
+ t2 = PTimestampType.new('2016-02-01', '2016-11-30')
943
+ expect(t1).not_to be_assignable_to(t2)
944
+ end
945
+ end
946
+
867
947
  context 'for Tuple, such that' do
868
948
  it 'Tuple is not assignable to any other non Array based Collection type' do
869
949
  t = PTupleType::DEFAULT
@@ -875,8 +955,8 @@ describe 'The type calculator' do
875
955
  end
876
956
 
877
957
  it 'A tuple with parameters is assignable to the default Tuple' do
878
- t = Puppet::Pops::Types::PTupleType::DEFAULT
879
- t2 = Puppet::Pops::Types::PTupleType.new([Puppet::Pops::Types::PStringType::DEFAULT])
958
+ t = PTupleType::DEFAULT
959
+ t2 = PTupleType.new([PStringType::DEFAULT])
880
960
  expect(t2).to be_assignable_to(t)
881
961
  end
882
962
 
@@ -967,11 +1047,39 @@ describe 'The type calculator' do
967
1047
  end
968
1048
 
969
1049
  it 'a callable with parameter is assignable to the default callable' do
970
- expect(callable_t(string_t)).to be_assignable_to(Puppet::Pops::Types::PCallableType::DEFAULT)
1050
+ expect(callable_t(string_t)).to be_assignable_to(PCallableType::DEFAULT)
971
1051
  end
972
1052
 
973
1053
  it 'the default callable is not assignable to a callable with parameter' do
974
- expect(Puppet::Pops::Types::PCallableType::DEFAULT).not_to be_assignable_to(callable_t(string_t))
1054
+ expect(PCallableType::DEFAULT).not_to be_assignable_to(callable_t(string_t))
1055
+ end
1056
+
1057
+ it 'a callable with a return type is assignable to the default callable' do
1058
+ expect(callable_t([], string_t)).to be_assignable_to(PCallableType::DEFAULT)
1059
+ end
1060
+
1061
+ it 'the default callable is not assignable to a callable with a return type' do
1062
+ expect(PCallableType::DEFAULT).not_to be_assignable_to(callable_t([],string_t))
1063
+ end
1064
+
1065
+ it 'a callable with a return type Any is assignable to the default callable' do
1066
+ expect(callable_t([], object_t)).to be_assignable_to(PCallableType::DEFAULT)
1067
+ end
1068
+
1069
+ it 'a callable with a return type Any is equal to a callable with the same parameters and no return type' do
1070
+ expect(callable_t([string_t], object_t)).to eql(callable_t(string_t))
1071
+ end
1072
+
1073
+ it 'a callable with a return type different than Any is not equal to a callable with the same parameters and no return type' do
1074
+ expect(callable_t([string_t], string_t)).not_to eql(callable_t(string_t))
1075
+ end
1076
+
1077
+ it 'a callable with a return type is assignable from another callable with an assignable return type' do
1078
+ expect(callable_t([], string_t)).to be_assignable_to(callable_t([], PScalarType::DEFAULT))
1079
+ end
1080
+
1081
+ it 'a callable with a return type is not assignable from another callable unless the return type is assignable' do
1082
+ expect(callable_t([], string_t)).not_to be_assignable_to(callable_t([], integer_t))
975
1083
  end
976
1084
  end
977
1085
 
@@ -1720,7 +1828,7 @@ describe 'The type calculator' do
1720
1828
  it 'a Closure should be considered a Callable' do
1721
1829
  factory = Model::Factory
1722
1830
  params = [factory.PARAM('a')]
1723
- the_block = factory.LAMBDA(params,factory.literal(42))
1831
+ the_block = factory.LAMBDA(params,factory.literal(42), nil)
1724
1832
  the_closure = Evaluator::Closure::Dynamic.new(:fake_evaluator, the_block, :fake_scope)
1725
1833
  expect(calculator.instance?(all_callables_t, the_closure)).to be_truthy
1726
1834
  expect(calculator.instance?(callable_t(object_t), the_closure)).to be_truthy
@@ -178,6 +178,38 @@ end
178
178
  expect(s.string(f.iterator(f.integer))).to eq('Iterator[Integer]')
179
179
  end
180
180
 
181
+ it "should yield 'Timespan' for PTimespanType" do
182
+ expect(s.string(f.timespan())).to eq('Timespan')
183
+ end
184
+
185
+ it "should yield 'Timespan[{hours => 1}] for PTimespanType[Timespan]" do
186
+ expect(s.string(f.timespan({'hours' => 1}))).to eq("Timespan['0-01:00:00.0']")
187
+ end
188
+
189
+ it "should yield 'Timespan[default, {hours => 2}] for PTimespanType[nil, Timespan]" do
190
+ expect(s.string(f.timespan(nil, {'hours' => 2}))).to eq("Timespan[default, '0-02:00:00.0']")
191
+ end
192
+
193
+ it "should yield 'Timespan[{hours => 1}, {hours => 2}] for PTimespanType[Timespan, Timespan]" do
194
+ expect(s.string(f.timespan({'hours' => 1}, {'hours' => 2}))).to eq("Timespan['0-01:00:00.0', '0-02:00:00.0']")
195
+ end
196
+
197
+ it "should yield 'Timestamp' for PTimestampType" do
198
+ expect(s.string(f.timestamp())).to eq('Timestamp')
199
+ end
200
+
201
+ it "should yield 'Timestamp['2016-09-05T13:00:00.000 UTC'] for PTimestampType[Timestamp]" do
202
+ expect(s.string(f.timestamp('2016-09-05T13:00:00.000 UTC'))).to eq("Timestamp['2016-09-05T13:00:00.000 UTC']")
203
+ end
204
+
205
+ it "should yield 'Timestamp[default, '2016-09-05T13:00:00.000 UTC'] for PTimestampType[nil, Timestamp]" do
206
+ expect(s.string(f.timestamp(nil, '2016-09-05T13:00:00.000 UTC'))).to eq("Timestamp[default, '2016-09-05T13:00:00.000 UTC']")
207
+ end
208
+
209
+ it "should yield 'Timestamp['2016-09-05T13:00:00.000 UTC', '2016-12-01T00:00:00.000 UTC'] for PTimestampType[Timestamp, Timestamp]" do
210
+ expect(s.string(f.timestamp('2016-09-05T13:00:00.000 UTC', '2016-12-01T00:00:00.000 UTC'))).to eq("Timestamp['2016-09-05T13:00:00.000 UTC', '2016-12-01T00:00:00.000 UTC']")
211
+ end
212
+
181
213
  it "should yield 'Tuple[Integer]' for PTupleType[PIntegerType]" do
182
214
  expect(s.string(f.tuple([f.integer]))).to eq('Tuple[Integer]')
183
215
  end
@@ -269,10 +301,18 @@ end
269
301
  expect(s.string(f.callable)).to eql('Callable[0, 0]')
270
302
  end
271
303
 
304
+ it "should yield 'Callable[[0,0],rt]' for callable without params but with return type" do
305
+ expect(s.string(f.callable([], Float))).to eql('Callable[[0, 0], Float]')
306
+ end
307
+
272
308
  it "should yield 'Callable[t,t]' for callable with typed parameters" do
273
309
  expect(s.string(f.callable(String, Integer))).to eql('Callable[String, Integer]')
274
310
  end
275
311
 
312
+ it "should yield 'Callable[[t,t],rt]' for callable with typed parameters and return type" do
313
+ expect(s.string(f.callable([String, Integer], Float))).to eql('Callable[[String, Integer], Float]')
314
+ end
315
+
276
316
  it "should yield 'Callable[t,min,max]' for callable with size constraint (infinite max)" do
277
317
  expect(s.string(f.callable(String, 0))).to eql('Callable[String, 0, default]')
278
318
  end
@@ -112,84 +112,95 @@ describe 'the type mismatch describer' do
112
112
  /parameter 'evars' expects a match for EVariants = Enum\['a', 'b', 'c', 'd'\], got 'n'/))
113
113
  end
114
114
 
115
+ it "will not generalize a string that doesn't match an enum in a function call" do
116
+ code = <<-CODE
117
+ function check_enums(Enum[a,b] $arg) {}
118
+ check_enums('c')
119
+ CODE
120
+ expect { eval_and_collect_notices(code) }.to(raise_error(Puppet::Error,
121
+ /parameter 'arg' expects a match for Enum\['a', 'b'\], got 'c'/))
122
+ end
123
+
124
+ it "will not disclose a Sensitive that doesn't match an enum in a function call" do
125
+ code = <<-CODE
126
+ function check_enums(Enum[a,b] $arg) {}
127
+ check_enums(Sensitive('c'))
128
+ CODE
129
+ expect { eval_and_collect_notices(code) }.to(raise_error(Puppet::Error,
130
+ /parameter 'arg' expects a match for Enum\['a', 'b'\], got Sensitive/))
131
+ end
132
+
133
+ it "will not generalize a string that doesn't match an enum in a define call" do
134
+ code = <<-CODE
135
+ define check_enums(Enum[a,b] $arg) {}
136
+ check_enums { x: arg => 'c' }
137
+ CODE
138
+ expect { eval_and_collect_notices(code) }.to(raise_error(Puppet::Error,
139
+ /parameter 'arg' expects a match for Enum\['a', 'b'\], got 'c'/))
140
+ end
141
+
142
+ it "will not disclose a Sensitive that doesn't match an enum in a define call" do
143
+ code = <<-CODE
144
+ define check_enums(Enum[a,b] $arg) {}
145
+ check_enums { x: arg => Sensitive('c') }
146
+ CODE
147
+ expect { eval_and_collect_notices(code) }.to(raise_error(Puppet::Error,
148
+ /parameter 'arg' expects a match for Enum\['a', 'b'\], got Sensitive/))
149
+ end
150
+
115
151
  context 'when reporting a mismatch between' do
116
- let(:parser) { TypeParser.new }
152
+ let(:parser) { TypeParser.singleton }
117
153
  let(:subject) { TypeMismatchDescriber.singleton }
118
154
 
119
155
  context 'hash and struct' do
120
156
  it 'reports a size mismatch when hash has unlimited size' do
121
157
  expected = parser.parse('Struct[{a=>Integer,b=>Integer}]')
122
158
  actual = parser.parse('Hash[String,Integer]')
123
- expect(subject.describe_mismatch('', expected, actual)).to eq('expected size to be 2, got unlimited')
159
+ expect(subject.describe_mismatch('', expected, actual)).to eq('expects size to be 2, got unlimited')
124
160
  end
125
161
 
126
162
  it 'reports a size mismatch when hash has specified but incorrect size' do
127
163
  expected = parser.parse('Struct[{a=>Integer,b=>Integer}]')
128
164
  actual = parser.parse('Hash[String,Integer,1,1]')
129
- expect(subject.describe_mismatch('', expected, actual)).to eq('expected size to be 2, got 1')
165
+ expect(subject.describe_mismatch('', expected, actual)).to eq('expects size to be 2, got 1')
130
166
  end
131
167
 
132
168
  it 'reports a full type mismatch when size is correct but hash value type is incorrect' do
133
169
  expected = parser.parse('Struct[{a=>Integer,b=>String}]')
134
170
  actual = parser.parse('Hash[String,Integer,2,2]')
135
- expect(subject.describe_mismatch('', expected, actual)).to eq("expected a Struct[{'a' => Integer, 'b' => String}] value, got Hash[String, Integer]")
171
+ expect(subject.describe_mismatch('', expected, actual)).to eq("expects a Struct[{'a' => Integer, 'b' => String}] value, got Hash[String, Integer]")
136
172
  end
137
173
  end
138
- end
139
174
 
140
- context 'when using present tense' do
141
- let(:parser) { TypeParser.singleton }
142
- let(:subject) { TypeMismatchDescriber.singleton }
143
175
  it 'reports a missing parameter as "has no parameter"' do
144
176
  t = parser.parse('Struct[{a=>String}]')
145
- expect { subject.validate_parameters('v', t, {'a'=>'a','b'=>'b'}, false, :present) }.to raise_error(Puppet::Error, "v: has no parameter named 'b'")
177
+ expect { subject.validate_parameters('v', t, {'a'=>'a','b'=>'b'}, false) }.to raise_error(Puppet::Error, "v: has no parameter named 'b'")
146
178
  end
147
179
 
148
180
  it 'reports a missing value as "expects a value"' do
149
181
  t = parser.parse('Struct[{a=>String,b=>String}]')
150
- expect { subject.validate_parameters('v', t, {'a'=>'a'}, false, :present) }.to raise_error(Puppet::Error, "v: expects a value for parameter 'b'")
182
+ expect { subject.validate_parameters('v', t, {'a'=>'a'}, false) }.to raise_error(Puppet::Error, "v: expects a value for parameter 'b'")
151
183
  end
152
184
 
153
185
  it 'reports a missing block as "expects a block"' do
154
186
  callable = parser.parse('Callable[String,String,Callable]')
155
187
  args_tuple = parser.parse('Tuple[String,String]')
156
188
  dispatch = Functions::Dispatch.new(callable, 'foo', ['a','b'], 'block', nil, nil, false)
157
- expect(subject.describe_signatures('function', [dispatch], args_tuple, :present)).to eq("'function' expects a block")
189
+ expect(subject.describe_signatures('function', [dispatch], args_tuple)).to eq("'function' expects a block")
158
190
  end
159
191
 
160
192
  it 'reports an unexpected block as "does not expect a block"' do
161
193
  callable = parser.parse('Callable[String,String]')
162
194
  args_tuple = parser.parse('Tuple[String,String,Callable]')
163
195
  dispatch = Functions::Dispatch.new(callable, 'foo', ['a','b'], nil, nil, nil, false)
164
- expect(subject.describe_signatures('function', [dispatch], args_tuple, :present)).to eq("'function' does not expect a block")
165
- end
166
- end
167
-
168
- context 'when using past tense' do
169
- let(:parser) { TypeParser.singleton }
170
- let(:subject) { TypeMismatchDescriber.singleton }
171
- it 'reports a missing parameter as "did not have a parameter"' do
172
- t = parser.parse('Struct[{a=>String}]')
173
- expect { subject.validate_parameters('v', t, {'a'=>'a','b'=>'b'}, false, :past) }.to raise_error(Puppet::Error, "v: did not have a parameter named 'b'")
174
- end
175
-
176
- it 'reports a missing value as "expected a value"' do
177
- t = parser.parse('Struct[{a=>String,b=>String}]')
178
- expect { subject.validate_parameters('v', t, {'a'=>'a'}, false, :past) }.to raise_error(Puppet::Error, "v: expected a value for parameter 'b'")
179
- end
180
-
181
- it 'reports a missing block as "expected a block"' do
182
- callable = parser.parse('Callable[String,String,Callable]')
183
- args_tuple = parser.parse('Tuple[String,String]')
184
- dispatch = Functions::Dispatch.new(callable, 'foo', ['a','b'], 'block', nil, nil, false)
185
- expect(subject.describe_signatures('function', [dispatch], args_tuple, :past)).to eq("'function' expected a block")
196
+ expect(subject.describe_signatures('function', [dispatch], args_tuple)).to eq("'function' does not expect a block")
186
197
  end
187
198
 
188
- it 'reports an unexpected block as "did not expect a block"' do
189
- callable = parser.parse('Callable[String,String]')
190
- args_tuple = parser.parse('Tuple[String,String,Callable]')
191
- dispatch = Functions::Dispatch.new(callable, 'foo', ['a','b'], nil, nil, nil, false)
192
- expect(subject.describe_signatures('function', [dispatch], args_tuple, :past)).to eq("'function' did not expect a block")
199
+ it 'reports a block return type mismatch' do
200
+ callable = parser.parse('Callable[[0,0,Callable[ [0,0],String]],Undef]')
201
+ args_tuple = parser.parse('Tuple[Callable[[0,0],Integer]]')
202
+ dispatch = Functions::Dispatch.new(callable, 'foo', [], 'block', nil, nil, false)
203
+ expect(subject.describe_signatures('function', [dispatch], args_tuple)).to eq("'function' block return expects a String value, got Integer")
193
204
  end
194
205
  end
195
206
  end