puppet 4.7.1-x86-mingw32 → 4.8.0-x86-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.

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
@@ -0,0 +1,69 @@
1
+ module Puppet::Pops
2
+ module Types
3
+ class PTimestampType < PAbstractTimeDataType
4
+ def self.register_ptype(loader, ir)
5
+ create_ptype(loader, ir, 'ScalarType',
6
+ 'from' => { KEY_TYPE => PTimestampType::DEFAULT, KEY_VALUE => :default },
7
+ 'to' => { KEY_TYPE => PTimestampType::DEFAULT, KEY_VALUE => :default }
8
+ )
9
+ end
10
+
11
+ def self.new_function(_, loader)
12
+ @new_function ||= Puppet::Functions.create_loaded_function(:new_timestamp, loader) do
13
+ local_types do
14
+ type 'Formats = Variant[String[2],Array[String[2]], 1]'
15
+ end
16
+
17
+ dispatch :now do
18
+ end
19
+
20
+ dispatch :from_seconds do
21
+ param 'Variant[Integer,Float]', :seconds
22
+ end
23
+
24
+ dispatch :from_string do
25
+ param 'String[1]', :string
26
+ optional_param 'Formats', :format
27
+ optional_param 'String[1]', :timezone
28
+ end
29
+
30
+ dispatch :from_string_hash do
31
+ param <<-TYPE, :hash_arg
32
+ Struct[{
33
+ string => String[1],
34
+ Optional[format] => Formats,
35
+ Optional[timezone] => String[1]
36
+ }]
37
+ TYPE
38
+ end
39
+
40
+ def now
41
+ Time::Timestamp.now
42
+ end
43
+
44
+ def from_string(string, format = :default, timezone = nil)
45
+ Time::Timestamp.parse(string, format, timezone)
46
+ end
47
+
48
+ def from_string_hash(args_hash)
49
+ Time::Timestamp.from_hash(args_hash)
50
+ end
51
+
52
+ def from_seconds(seconds)
53
+ Time::Timestamp.new((seconds * Time::NSECS_PER_SEC).to_i)
54
+ end
55
+ end
56
+ end
57
+
58
+ def generalize
59
+ DEFAULT
60
+ end
61
+
62
+ def impl_class
63
+ Time::Timestamp
64
+ end
65
+
66
+ DEFAULT = PTimestampType.new(nil, nil)
67
+ end
68
+ end
69
+ end
@@ -279,6 +279,7 @@ class StringConverter
279
279
  PNumericType::DEFAULT => Format.new('%d').freeze, # decimal number
280
280
  PArrayType::DEFAULT => DEFAULT_ARRAY_FORMAT.freeze,
281
281
  PHashType::DEFAULT => DEFAULT_HASH_FORMAT.freeze,
282
+ PBinaryType::DEFAULT => Format.new('%B').freeze, # strict base64 string unquoted
282
283
  PAnyType::DEFAULT => Format.new('%s').freeze, # unquoted string
283
284
  }.freeze
284
285
 
@@ -385,6 +386,21 @@ class StringConverter
385
386
  # | s | same as d
386
387
  # | p | same as d
387
388
  #
389
+ # ### Binary (value)
390
+ #
391
+ # | Format | Default formats
392
+ # | ------ | ---------------
393
+ # | s | binary as unquoted characters
394
+ # | p | 'Binary("<base64strict>")'
395
+ # | b | '<base64>' - base64 string with newlines inserted
396
+ # | B | '<base64strict>' - base64 strict string (without newlines inserted)
397
+ # | u | '<base64urlsafe>' - base64 urlsafe string
398
+ # | t | 'Binary' - outputs the name of the type only
399
+ # | T | 'BINARY' - output the name of the type in all caps only
400
+ #
401
+ # The alternate form flag `#` will quote the binary or base64 text output
402
+ # The width and precision values are applied to the text part only in `%p` format.
403
+ #
388
404
  # ### Array & Tuple
389
405
  #
390
406
  # | Format | Array/Tuple Formats
@@ -696,6 +712,52 @@ class StringConverter
696
712
  end
697
713
  end
698
714
 
715
+ # @api private
716
+ def string_PBinaryType(val_type, val, format_map, _)
717
+ f = get_format(val_type, format_map)
718
+ substitute = f.alt? ? 'p' : 's'
719
+ case f.format
720
+ when :s
721
+ val_to_convert = val.binary_buffer
722
+ if !f.alt?
723
+ # Assume it is valid UTF-8
724
+ val_to_convert = val_to_convert.dup.force_encoding('UTF-8')
725
+ # If it isn't
726
+ unless val_to_convert.valid_encoding?
727
+ # try to convert and fail with details about what is wrong
728
+ val_to_convert = val.binary_buffer.encode('UTF-8')
729
+ end
730
+ else
731
+ val_to_convert = val.binary_buffer
732
+ end
733
+ Kernel.format(f.orig_fmt.gsub('s', substitute), val_to_convert)
734
+
735
+ when :p
736
+ # width & precision applied to string, not the the name of the type
737
+ "Binary(\"#{Kernel.format(f.orig_fmt.gsub('p', 's'), val.to_s)}\")"
738
+
739
+ when :b
740
+ Kernel.format(f.orig_fmt.gsub('b', substitute), val.relaxed_to_s)
741
+
742
+ when :B
743
+ Kernel.format(f.orig_fmt.gsub('B', substitute), val.to_s)
744
+
745
+ when :u
746
+ Kernel.format(f.orig_fmt.gsub('u', substitute), val.urlsafe_to_s)
747
+
748
+ when :t
749
+ # Output as the type without any data
750
+ Kernel.format(f.orig_fmt.gsub('t', substitute), 'Binary')
751
+
752
+ when :T
753
+ # Output as the type without any data in all caps
754
+ Kernel.format(f.orig_fmt.gsub('T', substitute), 'BINARY')
755
+
756
+ else
757
+ raise FormatError.new('Binary', f.format, 'bButTsp')
758
+ end
759
+ end
760
+
699
761
  # @api private
700
762
  def string_PStringType(val_type, val, format_map, _)
701
763
  f = get_format(val_type, format_map)
@@ -39,7 +39,7 @@ module TypeAsserter
39
39
  subject = yield(subject) if block_given?
40
40
  subject = subject[0] % subject[1..-1] if subject.is_a?(Array)
41
41
  raise TypeAssertionError.new(
42
- TypeMismatchDescriber.singleton.describe_mismatch("#{subject} had wrong type,", expected_type, actual_type), expected_type, actual_type)
42
+ TypeMismatchDescriber.singleton.describe_mismatch("#{subject} has wrong type,", expected_type, actual_type), expected_type, actual_type)
43
43
  end
44
44
  private_class_method :report_type_mismatch
45
45
  end
@@ -620,9 +620,8 @@ class TypeCalculator
620
620
  max += 1
621
621
  PAnyType::DEFAULT
622
622
  end
623
- mapped_types << min
624
- mapped_types << max
625
- TypeFactory.callable(*mapped_types)
623
+ param_types = Types::PTupleType.new(mapped_types, Types::PIntegerType.new(min, max))
624
+ Types::PCallableType.new(param_types)
626
625
  end
627
626
 
628
627
  # @api private
@@ -648,6 +647,16 @@ class TypeCalculator
648
647
  PSensitiveType.new(infer(o.unwrap))
649
648
  end
650
649
 
650
+ # @api private
651
+ def infer_Timespan(o)
652
+ PTimespanType.new(o, o)
653
+ end
654
+
655
+ # @api private
656
+ def infer_Timestamp(o)
657
+ PTimestampType.new(o, o)
658
+ end
659
+
651
660
  # @api private
652
661
  def infer_TrueClass(o)
653
662
  PBooleanType::DEFAULT
@@ -678,6 +687,11 @@ class TypeCalculator
678
687
  end
679
688
  end
680
689
 
690
+ # @api private
691
+ def infer_Binary(o)
692
+ PBinaryType::DEFAULT
693
+ end
694
+
681
695
  # @api private
682
696
  def infer_Version(o)
683
697
  PSemVerType::DEFAULT
@@ -168,6 +168,28 @@ module TypeFactory
168
168
  hash.nil? || hash.empty? ? PTypeSetType::DEFAULT : PTypeSetType.new(hash)
169
169
  end
170
170
 
171
+ def self.timestamp(*args)
172
+ case args.size
173
+ when 0
174
+ PTimestampType::DEFAULT
175
+ when 1
176
+ PTimestampType.new(args[0], args[0])
177
+ else
178
+ PTimestampType.new(*args)
179
+ end
180
+ end
181
+
182
+ def self.timespan(*args)
183
+ case args.size
184
+ when 0
185
+ PTimespanType::DEFAULT
186
+ when 1
187
+ PTimespanType.new(args[0], args[0])
188
+ else
189
+ PTimespanType.new(*args)
190
+ end
191
+ end
192
+
171
193
  def self.tuple(types = [], size_type = nil)
172
194
  PTupleType.new(types.map {|elem| type_of(elem) }, size_type)
173
195
  end
@@ -250,6 +272,12 @@ module TypeFactory
250
272
  # Params are given as a sequence of arguments to {#type_of}.
251
273
  #
252
274
  def self.callable(*params)
275
+ if params.size == 2 && params[0].is_a?(Array)
276
+ return_t = type_of(params[1])
277
+ params = params[0]
278
+ else
279
+ return_t = nil
280
+ end
253
281
  last_callable = TypeCalculator.is_kind_of_callable?(params.last)
254
282
  block_t = last_callable ? params.pop : nil
255
283
 
@@ -272,7 +300,7 @@ module TypeFactory
272
300
  end
273
301
  # create a signature
274
302
  tuple_t = tuple(types, size_type)
275
- PCallableType.new(tuple_t, block_t)
303
+ PCallableType.new(tuple_t, block_t, return_t)
276
304
  end
277
305
 
278
306
  # Produces the abstract type Collection
@@ -301,6 +329,12 @@ module TypeFactory
301
329
  PDefaultType::DEFAULT
302
330
  end
303
331
 
332
+ # Creates an instance of the Binary type
333
+ # @api public
334
+ def self.binary
335
+ PBinaryType::DEFAULT
336
+ end
337
+
304
338
  # Produces an instance of the abstract type PCatalogEntryType
305
339
  def self.catalog_entry
306
340
  PCatalogEntryType::DEFAULT
@@ -69,6 +69,10 @@ class TypeFormatter
69
69
  end
70
70
 
71
71
 
72
+ def append_default
73
+ @bld << 'default'
74
+ end
75
+
72
76
  def append_string(t)
73
77
  if @ruby && t.is_a?(PAnyType)
74
78
  @ruby = false
@@ -129,6 +133,9 @@ class TypeFormatter
129
133
  # @api private
130
134
  def string_PNumericType(_) ; @bld << 'Numeric' ; end
131
135
 
136
+ # @api private
137
+ def string_PBinaryType(_) ; @bld << 'Binary' ; end
138
+
132
139
  # @api private
133
140
  def string_PIntegerType(t)
134
141
  append_array('Integer', t.unbounded?) { append_elements(range_array_part(t)) }
@@ -193,6 +200,32 @@ class TypeFormatter
193
200
  @bld << 'SemVerRange'
194
201
  end
195
202
 
203
+ # @api private
204
+ def string_PTimestampType(t)
205
+ min = t.from
206
+ max = t.to
207
+ append_array('Timestamp', min.nil? && max.nil?) do
208
+ min.nil? ? append_default : append_string(min)
209
+ unless max.nil? || max == min
210
+ @bld << COMMA_SEP
211
+ append_string(max)
212
+ end
213
+ end
214
+ end
215
+
216
+ # @api private
217
+ def string_PTimespanType(t)
218
+ min = t.from
219
+ max = t.to
220
+ append_array('Timespan', min.nil? && max.nil?) do
221
+ min.nil? ? append_default : append_string(min)
222
+ unless max.nil? || max == min
223
+ @bld << COMMA_SEP
224
+ append_string(max)
225
+ end
226
+ end
227
+ end
228
+
196
229
  # @api private
197
230
  def string_PTupleType(t)
198
231
  append_array('Tuple', t.types.empty?) do
@@ -204,21 +237,35 @@ class TypeFormatter
204
237
 
205
238
  # @api private
206
239
  def string_PCallableType(t)
207
- append_array('Callable', t.param_types.nil?) do
208
- # translate to string, and skip Unit types
209
- append_strings(t.param_types.types.reject {|t2| t2.class == PUnitType }, true)
210
-
211
- if t.param_types.types.empty?
212
- append_strings([0, 0], true)
240
+ if t.return_type.nil?
241
+ append_array('Callable', t.param_types.nil?) { append_callable_params(t) }
242
+ else
243
+ if t.param_types.nil?
244
+ append_array('Callable', false) { append_strings([[], t.return_type], false) }
213
245
  else
214
- append_elements(range_array_part(t.param_types.size_type), true)
246
+ append_array('Callable', false) do
247
+ append_array('', false) { append_callable_params(t) }
248
+ @bld << COMMA_SEP
249
+ append_string(t.return_type)
250
+ end
215
251
  end
252
+ end
253
+ end
216
254
 
217
- # Add block T last (after min, max) if present)
218
- #
219
- append_strings([t.block_type], true) unless t.block_type.nil?
220
- chomp_list
255
+ def append_callable_params(t)
256
+ # translate to string, and skip Unit types
257
+ append_strings(t.param_types.types.reject {|t2| t2.class == PUnitType }, true)
258
+
259
+ if t.param_types.types.empty?
260
+ append_strings([0, 0], true)
261
+ else
262
+ append_elements(range_array_part(t.param_types.size_type), true)
221
263
  end
264
+
265
+ # Add block T last (after min, max) if present)
266
+ #
267
+ append_strings([t.block_type], true) unless t.block_type.nil?
268
+ chomp_list
222
269
  end
223
270
 
224
271
  # @api private
@@ -460,6 +507,12 @@ class TypeFormatter
460
507
  # @api private
461
508
  def string_VersionRange(t) ; @bld << "'#{t}'" ; end
462
509
 
510
+ # @api private
511
+ def string_Timespan(t) ; @bld << "'#{t}'" ; end
512
+
513
+ # @api private
514
+ def string_Timestamp(t) ; @bld << "'#{t}'" ; end
515
+
463
516
  # Debugging to_s to reduce the amount of output
464
517
  def to_s
465
518
  '[a TypeFormatter]'
@@ -1,5 +1,6 @@
1
1
  module Puppet::Pops
2
2
  module Types
3
+ # @api private
3
4
  class TypePathElement
4
5
  attr_reader :key
5
6
 
@@ -20,30 +21,46 @@ module Types
20
21
  end
21
22
  end
22
23
 
24
+ # @api private
23
25
  class SubjectPathElement < TypePathElement
24
26
  def to_s
25
27
  key
26
28
  end
27
29
  end
28
30
 
31
+ # @api private
29
32
  class EntryValuePathElement < TypePathElement
30
33
  def to_s
31
34
  "entry '#{key}'"
32
35
  end
33
36
  end
34
37
 
38
+ # @api private
35
39
  class EntryKeyPathElement < TypePathElement
36
40
  def to_s
37
41
  "key of entry '#{key}'"
38
42
  end
39
43
  end
40
44
 
45
+ # @api private
41
46
  class ParameterPathElement < TypePathElement
42
47
  def to_s
43
48
  "parameter '#{key}'"
44
49
  end
45
50
  end
46
51
 
52
+ # @api private
53
+ class ReturnTypeElement < TypePathElement
54
+ def initialize(name = 'return')
55
+ super(name)
56
+ end
57
+
58
+ def to_s
59
+ key
60
+ end
61
+ end
62
+
63
+ # @api private
47
64
  class BlockPathElement < ParameterPathElement
48
65
  def initialize(name = 'block')
49
66
  super(name)
@@ -54,18 +71,21 @@ module Types
54
71
  end
55
72
  end
56
73
 
74
+ # @api private
57
75
  class ArrayPathElement < TypePathElement
58
76
  def to_s
59
77
  "index #{key}"
60
78
  end
61
79
  end
62
80
 
81
+ # @api private
63
82
  class VariantPathElement < TypePathElement
64
83
  def to_s
65
84
  "variant #{key}"
66
85
  end
67
86
  end
68
87
 
88
+ # @api private
69
89
  class SignaturePathElement < VariantPathElement
70
90
  def to_s
71
91
  "#{key+1}."
@@ -77,6 +97,8 @@ module Types
77
97
  # All method names prefixed with "it_" to avoid conflict with Mocha expectations. Adding a method
78
98
  # named 'expects' just doesn't work.
79
99
  #
100
+ # @deprecated Will be removed in Puppet 5
101
+ # @api private
80
102
  module TenseVariants
81
103
  def it_expects(tense)
82
104
  case tense
@@ -115,8 +137,8 @@ module Types
115
137
  end
116
138
  end
117
139
 
140
+ # @api private
118
141
  class Mismatch
119
- include TenseVariants
120
142
  attr_reader :path
121
143
 
122
144
  def initialize(path)
@@ -127,7 +149,7 @@ module Types
127
149
  @canonical_path ||= @path.reject { |e| e.is_a?(VariantPathElement) }
128
150
  end
129
151
 
130
- def message(variant, position, tense = :present)
152
+ def message(variant, position)
131
153
  "#{variant}unknown mismatch#{position}"
132
154
  end
133
155
 
@@ -161,10 +183,10 @@ module Types
161
183
  end
162
184
 
163
185
  def to_s
164
- format(:present)
186
+ format
165
187
  end
166
188
 
167
- def format(tense)
189
+ def format
168
190
  p = @path
169
191
  variant = ''
170
192
  position = ''
@@ -176,11 +198,12 @@ module Types
176
198
  end
177
199
  position = " #{p.join(' ')}" unless p.empty?
178
200
  end
179
- message(variant, position, tense)
201
+ message(variant, position)
180
202
  end
181
203
  end
182
204
 
183
205
  # @abstract
206
+ # @api private
184
207
  class KeyMismatch < Mismatch
185
208
  attr_reader :key
186
209
 
@@ -198,42 +221,49 @@ module Types
198
221
  end
199
222
  end
200
223
 
224
+ # @api private
201
225
  class MissingKey < KeyMismatch
202
- def message(variant, position, tense = :present)
203
- "#{variant}#{position} #{it_expects(tense)} a value for key '#{key}'"
226
+ def message(variant, position)
227
+ "#{variant}#{position} expects a value for key '#{key}'"
204
228
  end
205
229
  end
206
230
 
231
+ # @api private
207
232
  class MissingParameter < KeyMismatch
208
- def message(variant, position, tense = :present)
209
- "#{variant}#{position} #{it_expects(tense)} a value for parameter '#{key}'"
233
+ def message(variant, position)
234
+ "#{variant}#{position} expects a value for parameter '#{key}'"
210
235
  end
211
236
  end
212
237
 
238
+ # @api private
213
239
  class ExtraneousKey < KeyMismatch
214
- def message(variant, position, tense = :present)
240
+ def message(variant, position)
215
241
  "#{variant}#{position} unrecognized key '#{@key}'"
216
242
  end
217
243
  end
218
244
 
245
+ # @api private
219
246
  class InvalidParameter < ExtraneousKey
220
- def message(variant, position, tense = :present)
221
- "#{variant}#{position} #{it_has_no(tense)} parameter named '#{@key}'"
247
+ def message(variant, position)
248
+ "#{variant}#{position} has no parameter named '#{@key}'"
222
249
  end
223
250
  end
224
251
 
252
+ # @api private
225
253
  class UnexpectedBlock < Mismatch
226
- def message(variant, position, tense = :present)
227
- "#{variant}#{position} #{it_does_not_expect(tense)} a block"
254
+ def message(variant, position)
255
+ "#{variant}#{position} does not expect a block"
228
256
  end
229
257
  end
230
258
 
259
+ # @api private
231
260
  class MissingRequiredBlock < Mismatch
232
- def message(variant, position, tense = :present)
233
- "#{variant}#{position} #{it_expects(tense)} a block"
261
+ def message(variant, position)
262
+ "#{variant}#{position} expects a block"
234
263
  end
235
264
  end
236
265
 
266
+ # @api private
237
267
  class UnresolvedTypeReference < Mismatch
238
268
  attr_reader :unresolved
239
269
 
@@ -250,11 +280,12 @@ module Types
250
280
  @unresolved.hash
251
281
  end
252
282
 
253
- def message(variant, position, tense = :present)
254
- "#{variant}#{position} #{it_references(tense)} an unresolved type '#{@unresolved}'"
283
+ def message(variant, position)
284
+ "#{variant}#{position} references an unresolved type '#{@unresolved}'"
255
285
  end
256
286
  end
257
287
 
288
+ # @api private
258
289
  class ExpectedActualMismatch < Mismatch
259
290
  attr_reader :expected, :actual
260
291
 
@@ -279,6 +310,7 @@ module Types
279
310
  end
280
311
  end
281
312
 
313
+ # @api private
282
314
  class TypeMismatch < ExpectedActualMismatch
283
315
  include LabelProvider
284
316
 
@@ -287,7 +319,7 @@ module Types
287
319
  self.class.new(path, [expected, o.expected].flatten.uniq, actual)
288
320
  end
289
321
 
290
- def message(variant, position, tense = :present)
322
+ def message(variant, position)
291
323
  e = expected
292
324
  a = actual
293
325
  multi = false
@@ -321,9 +353,9 @@ module Types
321
353
  end
322
354
  end
323
355
  if multi
324
- "#{variant}#{position} #{it_expects(tense)} a value of type #{e}, got #{label(a)}"
356
+ "#{variant}#{position} expects a value of type #{e}, got #{label(a)}"
325
357
  else
326
- "#{variant}#{position} #{it_expects(tense)} #{a_an(e)} value, got #{label(a)}"
358
+ "#{variant}#{position} expects #{a_an(e)} value, got #{label(a)}"
327
359
  end
328
360
  end
329
361
 
@@ -424,9 +456,10 @@ module Types
424
456
  end
425
457
  end
426
458
 
459
+ # @api private
427
460
  class PatternMismatch < TypeMismatch
428
- def message(variant, position, tense = :present)
429
- "#{variant}#{position} #{it_expects(tense)} a match for #{expected.to_alias_expanded_s}, got #{actual_string}"
461
+ def message(variant, position)
462
+ "#{variant}#{position} expects a match for #{expected.to_alias_expanded_s}, got #{actual_string}"
430
463
  end
431
464
 
432
465
  def actual_string
@@ -435,6 +468,7 @@ module Types
435
468
  end
436
469
  end
437
470
 
471
+ # @api private
438
472
  class SizeMismatch < ExpectedActualMismatch
439
473
  def from
440
474
  @expected.from || 0
@@ -450,8 +484,8 @@ module Types
450
484
  self.class.new(path, range, @actual)
451
485
  end
452
486
 
453
- def message(variant, position, tense = :present)
454
- "#{variant}#{position} #{it_expects(tense)} size to be #{range_to_s(expected, '0')}, got #{range_to_s(actual, '0')}"
487
+ def message(variant, position)
488
+ "#{variant}#{position} expects size to be #{range_to_s(expected, '0')}, got #{range_to_s(actual, '0')}"
455
489
  end
456
490
 
457
491
  def range_to_s(range, zero_string)
@@ -469,22 +503,22 @@ module Types
469
503
  end
470
504
  end
471
505
 
506
+ # @api private
472
507
  class CountMismatch < SizeMismatch
473
508
  def initialize(path, expected, actual)
474
509
  super(path, expected, actual)
475
510
  end
476
511
 
477
- def message(variant, position, tense = :present)
512
+ def message(variant, position)
478
513
  min = expected.from || 0
479
514
  max = expected.to || Float::INFINITY
480
515
  suffix = min == 1 && (max == 1 || max == Float::INFINITY) || min == 0 && max == 1 ? '' : 's'
481
- "#{variant}#{position} #{it_expects(tense)} #{range_to_s(expected, 'no')} argument#{suffix}, got #{range_to_s(actual, 'none')}"
516
+ "#{variant}#{position} expects #{range_to_s(expected, 'no')} argument#{suffix}, got #{range_to_s(actual, 'none')}"
482
517
  end
483
518
  end
484
519
 
520
+ # @api private
485
521
  class TypeMismatchDescriber
486
- include TenseVariants
487
-
488
522
  def self.validate_parameters(subject, params_struct, given_hash, missing_ok = false)
489
523
  singleton.validate_parameters(subject, params_struct, given_hash, missing_ok)
490
524
  end
@@ -501,6 +535,10 @@ module Types
501
535
  @singleton ||= new
502
536
  end
503
537
 
538
+ def tense_deprecated
539
+ Puppet.warn_once(:deprecation, 'typemismatch#tense', "Passing a 'tense' argument to the TypeMismatchDescriber is deprecated and ignored. Everything is now reported using present tense")
540
+ end
541
+
504
542
  # Validates that all entries in the give_hash exists in the given param_struct, that their type conforms
505
543
  # with the corresponding param_struct element and that all required values are provided.
506
544
  #
@@ -508,16 +546,17 @@ module Types
508
546
  # @param params_struct [PStructType] Struct to use for validation
509
547
  # @param given_hash [Hash<String,Object>] the parameters to validate
510
548
  # @param missing_ok [Boolean] Do not generate errors on missing parameters
511
- # @param tense [Symbol] the symbol :present or :past
549
+ # @param tense [Symbol] deprecated and ignored
512
550
  #
513
- def validate_parameters(subject, params_struct, given_hash, missing_ok = false, tense = :present)
551
+ def validate_parameters(subject, params_struct, given_hash, missing_ok = false, tense = :ignored)
552
+ tense_deprecated unless tense == :ignored
514
553
  errors = describe_struct_signature(params_struct, given_hash, missing_ok).flatten
515
554
  case errors.size
516
555
  when 0
517
556
  when 1
518
- raise Puppet::ParseError.new("#{subject}:#{errors[0].format(tense)}")
557
+ raise Puppet::ParseError.new("#{subject}:#{errors[0].format}")
519
558
  else
520
- errors_str = errors.map { |error| error.format(tense) }.join("\n ")
559
+ errors_str = errors.map { |error| error.format }.join("\n ")
521
560
  raise Puppet::ParseError.new("#{subject}:\n #{errors_str}")
522
561
  end
523
562
  end
@@ -527,17 +566,18 @@ module Types
527
566
  # @param name [String] name of mismatch
528
567
  # @param expected [PAnyType] expected type
529
568
  # @param actual [PAnyType] actual type
530
- # @param tense [Symbol] the symbol :present or :past
569
+ # @param tense [Symbol] deprecated and ignored
531
570
  #
532
- def describe_mismatch(name, expected, actual, tense = :past)
571
+ def describe_mismatch(name, expected, actual, tense = :ignored)
572
+ tense_deprecated unless tense == :ignored
533
573
  errors = describe(expected, actual, [SubjectPathElement.new(name)])
534
574
  case errors.size
535
575
  when 0
536
576
  ''
537
577
  when 1
538
- errors[0].format(tense).strip
578
+ errors[0].format.strip
539
579
  else
540
- errors.map { |error| error.format(tense) }.join("\n ")
580
+ errors.map { |error| error.format }.join("\n ")
541
581
  end
542
582
  end
543
583
 
@@ -545,17 +585,18 @@ module Types
545
585
  # @param param_name [String] parameter name
546
586
  # @param param_type [PAnyType] parameter type
547
587
  # @param value [Object] value to be validated against the given type
548
- # @param tense [Symbol] the symbol :present or :past
588
+ # @param tense [Symbol] deprecated and ignored
549
589
  #
550
- def validate_default_parameter(subject, param_name, param_type, value, tense = :present)
590
+ def validate_default_parameter(subject, param_name, param_type, value, tense = :ignored)
591
+ tense_deprecated unless tense == :ignored
551
592
  unless param_type.instance?(value)
552
593
  errors = describe(param_type, TypeCalculator.singleton.infer_set(value).generalize, [ParameterPathElement.new(param_name)])
553
594
  case errors.size
554
595
  when 0
555
596
  when 1
556
- raise Puppet::ParseError.new("#{subject}:#{errors[0].format(tense)}")
597
+ raise Puppet::ParseError.new("#{subject}:#{errors[0].format}")
557
598
  else
558
- errors_str = errors.map { |error| error.format(tense) }.join("\n ")
599
+ errors_str = errors.map { |error| error.format }.join("\n ")
559
600
  raise Puppet::ParseError.new("#{subject}:\n #{errors_str}")
560
601
  end
561
602
  end
@@ -578,7 +619,7 @@ module Types
578
619
  value = param_hash[name]
579
620
  value_type = elem.value_type
580
621
  if param_hash.include?(name)
581
- result << describe(value_type, TypeCalculator.singleton.infer_set(value).generalize, [ParameterPathElement.new(name)]) unless value_type.instance?(value)
622
+ result << describe(value_type, TypeCalculator.singleton.infer_set(value), [ParameterPathElement.new(name)]) unless value_type.instance?(value)
582
623
  else
583
624
  result << MissingParameter.new(nil, name) unless elem.key_type.assignable?(PUndefType::DEFAULT) unless missing_ok
584
625
  end
@@ -586,7 +627,8 @@ module Types
586
627
  result
587
628
  end
588
629
 
589
- def describe_signatures(closure, signatures, args_tuple, tense = :present)
630
+ def describe_signatures(closure, signatures, args_tuple, tense = :ignored)
631
+ tense_deprecated unless tense == :ignored
590
632
  error_arrays = []
591
633
  signatures.each_with_index do |signature, index|
592
634
  error_arrays << describe_signature_arguments(signature, args_tuple, [SignaturePathElement.new(index)])
@@ -612,17 +654,17 @@ module Types
612
654
  label = closure == 'lambda' ? 'block' : "'#{closure}'"
613
655
  errors = merge_descriptions(0, CountMismatch, error_arrays)
614
656
  if errors.size == 1
615
- "#{label}#{errors[0].format(tense)}"
657
+ "#{label}#{errors[0].format}"
616
658
  else
617
659
  if signatures.size == 1
618
660
  sig = signatures[0]
619
- result = ["#{label} #{it_expects(tense)} (#{signature_string(sig)})"]
620
- result.concat(error_arrays[0].map { |e| " rejected:#{e.chop_path(0).format(tense)}" })
661
+ result = ["#{label} expects (#{signature_string(sig)})"]
662
+ result.concat(error_arrays[0].map { |e| " rejected:#{e.chop_path(0).format}" })
621
663
  else
622
- result = ["#{label} #{it_expects(tense)} one of:"]
664
+ result = ["#{label} expects one of:"]
623
665
  signatures.each_with_index do |sg, index|
624
666
  result << " (#{signature_string(sg)})"
625
- result.concat(error_arrays[index].map { |e| " rejected:#{e.chop_path(0).format(tense)}" })
667
+ result.concat(error_arrays[index].map { |e| " rejected:#{e.chop_path(0).format}" })
626
668
  end
627
669
  end
628
670
  result.join("\n")
@@ -840,7 +882,7 @@ module Types
840
882
  end
841
883
 
842
884
  def describe_tuple(expected, actual, path, size_mismatch_class)
843
- return if expected == actual || expected.types.empty? && (actual.is_a?(PArrayType))
885
+ return EMPTY_ARRAY if expected == actual || expected.types.empty? && (actual.is_a?(PArrayType))
844
886
  expected_size = expected.size_type || TypeFactory.range(*expected.size_range)
845
887
 
846
888
  if actual.is_a?(PTupleType)
@@ -850,10 +892,11 @@ module Types
850
892
  if expected_size.assignable?(actual_size)
851
893
  etypes = expected.types
852
894
  descriptions = []
853
- actual.types.each_with_index do |atype, index|
854
- adx = index >= etypes.size ? etypes.size - 1 : index
855
- etype = etypes[adx]
856
- descriptions.concat(describe(etypes[adx], atype, path + [ArrayPathElement.new(adx)]))
895
+ unless etypes.empty?
896
+ actual.types.each_with_index do |atype, index|
897
+ adx = index >= etypes.size ? etypes.size - 1 : index
898
+ descriptions.concat(describe(etypes[adx], atype, path + [ArrayPathElement.new(adx)]))
899
+ end
857
900
  end
858
901
  descriptions
859
902
  else
@@ -888,21 +931,27 @@ module Types
888
931
  def describe_PCallableType(expected, actual, path)
889
932
  if actual.is_a?(PCallableType)
890
933
  # nil param_types means, any other Callable is assignable
891
- if expected.param_types.nil?
934
+ if expected.param_types.nil? && expected.return_type.nil?
892
935
  EMPTY_ARRAY
893
936
  else
894
937
  # NOTE: these tests are made in reverse as it is calling the callable that is constrained
895
938
  # (it's lower bound), not its upper bound
896
939
  param_errors = describe_argument_tuple(expected.param_types, actual.param_types, path)
897
940
  if param_errors.empty?
898
- # names are ignored, they are just information
899
- # Blocks must be compatible
900
- this_block_t = expected.block_type || PUndefType::DEFAULT
901
- that_block_t = actual.block_type || PUndefType::DEFAULT
902
- if that_block_t.assignable?(this_block_t)
903
- EMPTY_ARRAY
941
+ this_return_t = expected.return_type || PAnyType::DEFAULT
942
+ that_return_t = actual.return_type || PAnyType::DEFAULT
943
+ unless this_return_t.assignable?(that_return_t)
944
+ [TypeMismatch.new(path + [ReturnTypeElement.new], this_return_t, that_return_t)]
904
945
  else
905
- [TypeMismatch.new(path + BlockPathElement.new, this_block_t, that_block_t)]
946
+ # names are ignored, they are just information
947
+ # Blocks must be compatible
948
+ this_block_t = expected.block_type || PUndefType::DEFAULT
949
+ that_block_t = actual.block_type || PUndefType::DEFAULT
950
+ if that_block_t.assignable?(this_block_t)
951
+ EMPTY_ARRAY
952
+ else
953
+ [TypeMismatch.new(path + [BlockPathElement.new], this_block_t, that_block_t)]
954
+ end
906
955
  end
907
956
  else
908
957
  param_errors