puppet 3.4.3 → 3.5.0.rc1

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 (811) hide show
  1. data/CONTRIBUTING.md +6 -6
  2. data/Gemfile +22 -16
  3. data/LICENSE +1 -1
  4. data/README.md +33 -11
  5. data/Rakefile +1 -1
  6. data/conf/auth.conf +4 -0
  7. data/ext/build_defaults.yaml +1 -1
  8. data/ext/debian/control +6 -6
  9. data/ext/ips/transforms +1 -1
  10. data/ext/nagios/naggen +1 -1
  11. data/ext/project_data.yaml +21 -1
  12. data/ext/puppet-test +3 -3
  13. data/ext/redhat/puppet.spec.erb +28 -2
  14. data/ext/suse/puppet.spec +1 -1
  15. data/ext/upload_facts.rb +1 -1
  16. data/ext/windows/service/daemon.rb +99 -20
  17. data/lib/hiera_puppet.rb +2 -2
  18. data/lib/puppet.rb +68 -5
  19. data/lib/puppet/agent.rb +5 -1
  20. data/lib/puppet/application.rb +20 -11
  21. data/lib/puppet/application/agent.rb +1 -1
  22. data/lib/puppet/application/apply.rb +61 -41
  23. data/lib/puppet/application/cert.rb +3 -3
  24. data/lib/puppet/application/device.rb +7 -8
  25. data/lib/puppet/application/doc.rb +1 -1
  26. data/lib/puppet/application/filebucket.rb +3 -3
  27. data/lib/puppet/application/kick.rb +2 -2
  28. data/lib/puppet/application/master.rb +1 -1
  29. data/lib/puppet/application/queue.rb +9 -9
  30. data/lib/puppet/application/resource.rb +2 -2
  31. data/lib/puppet/bindings.rb +6 -6
  32. data/lib/puppet/configurer.rb +17 -14
  33. data/lib/puppet/configurer/fact_handler.rb +1 -1
  34. data/lib/puppet/confine/any.rb +26 -0
  35. data/lib/puppet/confine/exists.rb +1 -1
  36. data/lib/puppet/confiner.rb +1 -0
  37. data/lib/puppet/context.rb +55 -0
  38. data/lib/puppet/context/trusted_information.rb +56 -0
  39. data/lib/puppet/defaults.rb +97 -26
  40. data/lib/puppet/environments.rb +187 -0
  41. data/lib/puppet/error.rb +2 -1
  42. data/lib/puppet/external/pson/common.rb +1 -1
  43. data/lib/puppet/external/pson/pure/generator.rb +1 -1
  44. data/lib/puppet/external/pson/pure/parser.rb +1 -1
  45. data/lib/puppet/face/config.rb +73 -15
  46. data/lib/puppet/face/file/store.rb +1 -1
  47. data/lib/puppet/face/help.rb +2 -1
  48. data/lib/puppet/face/help/action.erb +1 -0
  49. data/lib/puppet/face/help/face.erb +1 -0
  50. data/lib/puppet/face/help/global.erb +1 -0
  51. data/lib/puppet/face/help/man.erb +9 -8
  52. data/lib/puppet/face/module/list.rb +13 -7
  53. data/lib/puppet/face/node/clean.rb +2 -2
  54. data/lib/puppet/face/parser.rb +11 -5
  55. data/lib/puppet/face/status.rb +1 -1
  56. data/lib/puppet/feature/external_facts.rb +2 -2
  57. data/lib/puppet/feature/libuser.rb +1 -1
  58. data/lib/puppet/feature/msgpack.rb +2 -0
  59. data/lib/puppet/feature/rails.rb +2 -2
  60. data/lib/puppet/file_bucket/dipper.rb +9 -9
  61. data/lib/puppet/file_bucket/file.rb +9 -5
  62. data/lib/puppet/file_serving/base.rb +1 -1
  63. data/lib/puppet/file_serving/configuration.rb +1 -1
  64. data/lib/puppet/file_serving/configuration/parser.rb +3 -3
  65. data/lib/puppet/file_serving/content.rb +2 -2
  66. data/lib/puppet/file_serving/fileset.rb +4 -4
  67. data/lib/puppet/file_serving/metadata.rb +69 -15
  68. data/lib/puppet/file_serving/mount/file.rb +1 -1
  69. data/lib/puppet/file_system.rb +361 -1
  70. data/lib/puppet/file_system/file18.rb +3 -3
  71. data/lib/puppet/file_system/file19.rb +3 -3
  72. data/lib/puppet/file_system/file19windows.rb +18 -23
  73. data/lib/puppet/file_system/file_impl.rb +145 -0
  74. data/lib/puppet/file_system/memory_file.rb +23 -9
  75. data/lib/puppet/file_system/memory_impl.rb +64 -0
  76. data/lib/puppet/forge.rb +4 -3
  77. data/lib/puppet/forge/repository.rb +0 -1
  78. data/lib/puppet/graph/relationship_graph.rb +7 -7
  79. data/lib/puppet/indirector.rb +1 -0
  80. data/lib/puppet/indirector/catalog/compiler.rb +3 -30
  81. data/lib/puppet/indirector/catalog/msgpack.rb +6 -0
  82. data/lib/puppet/indirector/catalog/static_compiler.rb +3 -7
  83. data/lib/puppet/indirector/data_binding/hiera.rb +1 -1
  84. data/lib/puppet/indirector/direct_file_server.rb +2 -2
  85. data/lib/puppet/indirector/exec.rb +1 -1
  86. data/lib/puppet/indirector/face.rb +3 -2
  87. data/lib/puppet/indirector/facts/facter.rb +1 -1
  88. data/lib/puppet/indirector/file_bucket_file/file.rb +25 -15
  89. data/lib/puppet/indirector/file_metadata/file.rb +1 -1
  90. data/lib/puppet/indirector/file_server.rb +1 -1
  91. data/lib/puppet/indirector/indirection.rb +1 -1
  92. data/lib/puppet/indirector/json.rb +4 -4
  93. data/lib/puppet/indirector/key/file.rb +8 -5
  94. data/lib/puppet/indirector/ldap.rb +1 -1
  95. data/lib/puppet/indirector/memory.rb +4 -0
  96. data/lib/puppet/indirector/msgpack.rb +82 -0
  97. data/lib/puppet/indirector/node/exec.rb +1 -1
  98. data/lib/puppet/indirector/node/ldap.rb +3 -3
  99. data/lib/puppet/indirector/node/msgpack.rb +7 -0
  100. data/lib/puppet/indirector/node/yaml.rb +15 -0
  101. data/lib/puppet/indirector/queue.rb +3 -2
  102. data/lib/puppet/indirector/report/msgpack.rb +11 -0
  103. data/lib/puppet/indirector/request.rb +17 -20
  104. data/lib/puppet/indirector/resource/rest.rb +1 -1
  105. data/lib/puppet/indirector/resource_type/parser.rb +3 -13
  106. data/lib/puppet/indirector/rest.rb +6 -7
  107. data/lib/puppet/indirector/ssl_file.rb +7 -7
  108. data/lib/puppet/indirector/yaml.rb +9 -13
  109. data/lib/puppet/metatype/manager.rb +12 -7
  110. data/lib/puppet/module.rb +14 -9
  111. data/lib/puppet/module_tool.rb +21 -26
  112. data/lib/puppet/module_tool/applications/application.rb +1 -1
  113. data/lib/puppet/module_tool/applications/generator.rb +2 -1
  114. data/lib/puppet/module_tool/applications/installer.rb +9 -4
  115. data/lib/puppet/module_tool/applications/uninstaller.rb +10 -7
  116. data/lib/puppet/module_tool/applications/unpacker.rb +1 -1
  117. data/lib/puppet/module_tool/applications/upgrader.rb +11 -8
  118. data/lib/puppet/module_tool/checksums.rb +1 -1
  119. data/lib/puppet/module_tool/contents_description.rb +2 -0
  120. data/lib/puppet/module_tool/dependency.rb +4 -5
  121. data/lib/puppet/module_tool/errors.rb +2 -0
  122. data/lib/puppet/module_tool/install_directory.rb +3 -0
  123. data/lib/puppet/module_tool/metadata.rb +3 -5
  124. data/lib/puppet/module_tool/modulefile.rb +3 -0
  125. data/lib/puppet/module_tool/shared_behaviors.rb +6 -1
  126. data/lib/puppet/module_tool/skeleton.rb +3 -0
  127. data/lib/puppet/module_tool/tar.rb +3 -0
  128. data/lib/puppet/network/auth_config_parser.rb +1 -1
  129. data/lib/puppet/network/authconfig.rb +5 -2
  130. data/lib/puppet/network/authentication.rb +7 -2
  131. data/lib/puppet/network/authorization.rb +2 -2
  132. data/lib/puppet/network/format_support.rb +4 -0
  133. data/lib/puppet/network/formats.rb +9 -14
  134. data/lib/puppet/network/http.rb +11 -0
  135. data/lib/puppet/network/http/api.rb +0 -2
  136. data/lib/puppet/network/http/api/v1.rb +146 -11
  137. data/lib/puppet/network/http/api/v2.rb +32 -0
  138. data/lib/puppet/network/http/api/v2/authorization.rb +13 -0
  139. data/lib/puppet/network/http/api/v2/environments.rb +21 -0
  140. data/lib/puppet/network/http/connection.rb +94 -37
  141. data/lib/puppet/network/http/error.rb +69 -0
  142. data/lib/puppet/network/http/handler.rb +28 -196
  143. data/lib/puppet/network/http/issues.rb +9 -0
  144. data/lib/puppet/network/http/memory_response.rb +13 -0
  145. data/lib/puppet/network/http/rack/rest.rb +10 -18
  146. data/lib/puppet/network/http/request.rb +56 -0
  147. data/lib/puppet/network/http/response.rb +11 -0
  148. data/lib/puppet/network/http/route.rb +91 -0
  149. data/lib/puppet/network/http/webrick.rb +1 -1
  150. data/lib/puppet/network/http/webrick/rest.rb +7 -12
  151. data/lib/puppet/network/http_pool.rb +3 -3
  152. data/lib/puppet/network/rights.rb +4 -4
  153. data/lib/puppet/node.rb +23 -14
  154. data/lib/puppet/node/environment.rb +149 -125
  155. data/lib/puppet/node/facts.rb +6 -5
  156. data/lib/puppet/parameter.rb +1 -1
  157. data/lib/puppet/parser/ast.rb +1 -1
  158. data/lib/puppet/parser/ast/block_expression.rb +1 -6
  159. data/lib/puppet/parser/ast/collexpr.rb +54 -2
  160. data/lib/puppet/parser/ast/lambda.rb +9 -0
  161. data/lib/puppet/parser/ast/leaf.rb +15 -0
  162. data/lib/puppet/parser/ast/pops_bridge.rb +168 -0
  163. data/lib/puppet/parser/code_merger.rb +13 -0
  164. data/lib/puppet/parser/collector.rb +1 -1
  165. data/lib/puppet/parser/compiler.rb +28 -30
  166. data/lib/puppet/parser/e4_parser_adapter.rb +81 -0
  167. data/lib/puppet/parser/e_parser_adapter.rb +0 -1
  168. data/lib/puppet/parser/files.rb +12 -7
  169. data/lib/puppet/parser/functions.rb +36 -29
  170. data/lib/puppet/parser/functions/collect.rb +1 -1
  171. data/lib/puppet/parser/functions/defined.rb +40 -16
  172. data/lib/puppet/parser/functions/each.rb +55 -41
  173. data/lib/puppet/parser/functions/epp.rb +41 -0
  174. data/lib/puppet/parser/functions/extlookup.rb +2 -2
  175. data/lib/puppet/parser/functions/file.rb +1 -1
  176. data/lib/puppet/parser/functions/filter.rb +68 -16
  177. data/lib/puppet/parser/functions/generate.rb +1 -1
  178. data/lib/puppet/parser/functions/include.rb +3 -2
  179. data/lib/puppet/parser/functions/inline_epp.rb +79 -0
  180. data/lib/puppet/parser/functions/inline_template.rb +1 -1
  181. data/lib/puppet/parser/functions/lookup.rb +127 -27
  182. data/lib/puppet/parser/functions/map.rb +64 -12
  183. data/lib/puppet/parser/functions/reduce.rb +40 -16
  184. data/lib/puppet/parser/functions/select.rb +1 -1
  185. data/lib/puppet/parser/functions/slice.rb +42 -23
  186. data/lib/puppet/parser/grammar.ra +3 -0
  187. data/lib/puppet/parser/lexer.rb +10 -9
  188. data/lib/puppet/parser/parser.rb +15 -12
  189. data/lib/puppet/parser/parser_factory.rb +26 -1
  190. data/lib/puppet/parser/parser_support.rb +13 -4
  191. data/lib/puppet/parser/resource.rb +1 -1
  192. data/lib/puppet/parser/scope.rb +246 -97
  193. data/lib/puppet/parser/templatewrapper.rb +1 -1
  194. data/lib/puppet/parser/type_loader.rb +13 -2
  195. data/lib/puppet/pops.rb +15 -1
  196. data/lib/puppet/pops/adapters.rb +64 -32
  197. data/lib/puppet/pops/binder/binder.rb +122 -150
  198. data/lib/puppet/pops/binder/binder_issues.rb +1 -21
  199. data/lib/puppet/pops/binder/bindings_checker.rb +0 -20
  200. data/lib/puppet/pops/binder/bindings_composer.rb +4 -70
  201. data/lib/puppet/pops/binder/bindings_factory.rb +16 -58
  202. data/lib/puppet/pops/binder/bindings_label_provider.rb +0 -3
  203. data/lib/puppet/pops/binder/bindings_loader.rb +13 -4
  204. data/lib/puppet/pops/binder/bindings_model.rb +17 -31
  205. data/lib/puppet/pops/binder/bindings_model_dumper.rb +2 -20
  206. data/lib/puppet/pops/binder/config/binder_config.rb +8 -40
  207. data/lib/puppet/pops/binder/config/binder_config_checker.rb +2 -43
  208. data/lib/puppet/pops/binder/config/issues.rb +1 -21
  209. data/lib/puppet/pops/binder/injector.rb +86 -7
  210. data/lib/puppet/pops/binder/injector_entry.rb +6 -2
  211. data/lib/puppet/pops/binder/key_factory.rb +7 -1
  212. data/lib/puppet/pops/binder/lookup.rb +191 -0
  213. data/lib/puppet/pops/binder/producers.rb +5 -5
  214. data/lib/puppet/pops/binder/scheme_handler/symbolic_scheme.rb +2 -3
  215. data/lib/puppet/pops/binder/system_bindings.rb +4 -16
  216. data/lib/puppet/pops/containment.rb +72 -5
  217. data/lib/puppet/pops/evaluator/access_operator.rb +548 -0
  218. data/lib/puppet/pops/evaluator/closure.rb +57 -0
  219. data/lib/puppet/pops/evaluator/compare_operator.rb +168 -0
  220. data/lib/puppet/pops/evaluator/epp_evaluator.rb +87 -0
  221. data/lib/puppet/pops/evaluator/evaluator_impl.rb +1069 -0
  222. data/lib/puppet/pops/evaluator/external_syntax_support.rb +49 -0
  223. data/lib/puppet/pops/evaluator/relationship_operator.rb +156 -0
  224. data/lib/puppet/pops/evaluator/runtime3_support.rb +489 -0
  225. data/lib/puppet/pops/issue_reporter.rb +8 -4
  226. data/lib/puppet/pops/issues.rb +199 -4
  227. data/lib/puppet/pops/label_provider.rb +5 -0
  228. data/lib/puppet/pops/model/ast_transformer.rb +55 -31
  229. data/lib/puppet/pops/model/ast_tree_dumper.rb +9 -1
  230. data/lib/puppet/pops/model/factory.rb +265 -111
  231. data/lib/puppet/pops/model/model.rb +179 -140
  232. data/lib/puppet/pops/model/model_label_provider.rb +38 -9
  233. data/lib/puppet/pops/model/model_tree_dumper.rb +38 -13
  234. data/lib/puppet/pops/parser/code_merger.rb +17 -0
  235. data/lib/puppet/pops/parser/egrammar.ra +110 -61
  236. data/lib/puppet/pops/parser/eparser.rb +1415 -1092
  237. data/lib/puppet/pops/parser/epp_parser.rb +51 -0
  238. data/lib/puppet/pops/parser/epp_support.rb +247 -0
  239. data/lib/puppet/pops/parser/evaluating_parser.rb +53 -15
  240. data/lib/puppet/pops/parser/heredoc_support.rb +139 -0
  241. data/lib/puppet/pops/parser/interpolation_support.rb +227 -0
  242. data/lib/puppet/pops/parser/lexer.rb +83 -192
  243. data/lib/puppet/pops/parser/lexer2.rb +684 -0
  244. data/lib/puppet/pops/parser/lexer_support.rb +107 -0
  245. data/lib/puppet/pops/parser/locatable.rb +23 -0
  246. data/lib/puppet/pops/parser/locator.rb +291 -0
  247. data/lib/puppet/pops/parser/makefile +1 -8
  248. data/lib/puppet/pops/parser/parser_support.rb +76 -48
  249. data/lib/puppet/pops/parser/slurp_support.rb +95 -0
  250. data/lib/puppet/pops/patterns.rb +13 -4
  251. data/lib/puppet/pops/types/class_loader.rb +2 -2
  252. data/lib/puppet/pops/types/enumeration.rb +34 -0
  253. data/lib/puppet/pops/types/type_calculator.rb +983 -58
  254. data/lib/puppet/pops/types/type_factory.rb +203 -15
  255. data/lib/puppet/pops/types/type_parser.rb +355 -12
  256. data/lib/puppet/pops/types/types.rb +314 -24
  257. data/lib/puppet/pops/utils.rb +23 -7
  258. data/lib/puppet/pops/validation.rb +14 -8
  259. data/lib/puppet/pops/validation/checker3_1.rb +17 -12
  260. data/lib/puppet/pops/validation/checker4_0.rb +514 -0
  261. data/lib/puppet/pops/validation/validator_factory_4_0.rb +31 -0
  262. data/lib/puppet/pops/visitor.rb +146 -4
  263. data/lib/puppet/property.rb +1 -1
  264. data/lib/puppet/property/ensure.rb +1 -1
  265. data/lib/puppet/provider.rb +47 -26
  266. data/lib/puppet/provider/aixobject.rb +3 -3
  267. data/lib/puppet/provider/augeas/augeas.rb +11 -11
  268. data/lib/puppet/provider/cron/crontab.rb +10 -1
  269. data/lib/puppet/provider/exec.rb +1 -1
  270. data/lib/puppet/provider/exec/posix.rb +1 -1
  271. data/lib/puppet/provider/exec/windows.rb +1 -1
  272. data/lib/puppet/provider/file/posix.rb +2 -2
  273. data/lib/puppet/provider/file/windows.rb +15 -9
  274. data/lib/puppet/provider/group/aix.rb +2 -2
  275. data/lib/puppet/provider/macauthorization/macauthorization.rb +3 -3
  276. data/lib/puppet/provider/mount.rb +7 -0
  277. data/lib/puppet/provider/mount/parsed.rb +0 -1
  278. data/lib/puppet/provider/naginator.rb +1 -1
  279. data/lib/puppet/provider/nameservice.rb +3 -3
  280. data/lib/puppet/provider/nameservice/directoryservice.rb +3 -3
  281. data/lib/puppet/provider/package/aix.rb +1 -1
  282. data/lib/puppet/provider/package/appdmg.rb +1 -4
  283. data/lib/puppet/provider/package/apple.rb +1 -1
  284. data/lib/puppet/provider/package/apt.rb +1 -1
  285. data/lib/puppet/provider/package/blastwave.rb +1 -1
  286. data/lib/puppet/provider/package/fink.rb +1 -1
  287. data/lib/puppet/provider/package/gem.rb +3 -3
  288. data/lib/puppet/provider/package/openbsd.rb +6 -4
  289. data/lib/puppet/provider/package/pacman.rb +58 -5
  290. data/lib/puppet/provider/package/pip.rb +2 -2
  291. data/lib/puppet/provider/package/pkgdmg.rb +25 -10
  292. data/lib/puppet/provider/package/pkgin.rb +48 -23
  293. data/lib/puppet/provider/package/pkgutil.rb +1 -1
  294. data/lib/puppet/provider/package/ports.rb +1 -1
  295. data/lib/puppet/provider/package/portupgrade.rb +7 -7
  296. data/lib/puppet/provider/package/rpm.rb +16 -8
  297. data/lib/puppet/provider/package/windows.rb +1 -1
  298. data/lib/puppet/provider/package/windows/package.rb +1 -1
  299. data/lib/puppet/provider/parsedfile.rb +1 -1
  300. data/lib/puppet/provider/selboolean/getsetsebool.rb +1 -1
  301. data/lib/puppet/provider/selmodule/semodule.rb +5 -5
  302. data/lib/puppet/provider/service/base.rb +1 -1
  303. data/lib/puppet/provider/service/bsd.rb +3 -3
  304. data/lib/puppet/provider/service/daemontools.rb +20 -20
  305. data/lib/puppet/provider/service/debian.rb +1 -1
  306. data/lib/puppet/provider/service/freebsd.rb +3 -3
  307. data/lib/puppet/provider/service/gentoo.rb +2 -2
  308. data/lib/puppet/provider/service/init.rb +5 -5
  309. data/lib/puppet/provider/service/launchd.rb +4 -4
  310. data/lib/puppet/provider/service/redhat.rb +2 -2
  311. data/lib/puppet/provider/service/runit.rb +4 -4
  312. data/lib/puppet/provider/service/service.rb +3 -4
  313. data/lib/puppet/provider/service/smf.rb +1 -1
  314. data/lib/puppet/provider/service/src.rb +3 -3
  315. data/lib/puppet/provider/service/systemd.rb +4 -4
  316. data/lib/puppet/provider/service/upstart.rb +22 -7
  317. data/lib/puppet/provider/service/windows.rb +7 -7
  318. data/lib/puppet/provider/ssh_authorized_key/parsed.rb +3 -3
  319. data/lib/puppet/provider/user/aix.rb +5 -5
  320. data/lib/puppet/provider/user/directoryservice.rb +8 -5
  321. data/lib/puppet/provider/user/ldap.rb +1 -1
  322. data/lib/puppet/provider/user/pw.rb +1 -1
  323. data/lib/puppet/provider/user/user_role_add.rb +2 -2
  324. data/lib/puppet/provider/user/useradd.rb +19 -5
  325. data/lib/puppet/provider/yumrepo/inifile.rb +187 -0
  326. data/lib/puppet/provider/zone/solaris.rb +4 -4
  327. data/lib/puppet/rails.rb +16 -11
  328. data/lib/puppet/rails/benchmark.rb +1 -1
  329. data/lib/puppet/rails/resource.rb +5 -1
  330. data/lib/puppet/reference/configuration.rb +1 -1
  331. data/lib/puppet/reference/report.rb +1 -1
  332. data/lib/puppet/relationship.rb +10 -5
  333. data/lib/puppet/reports/http.rb +8 -2
  334. data/lib/puppet/reports/rrdgraph.rb +1 -1
  335. data/lib/puppet/reports/store.rb +3 -3
  336. data/lib/puppet/reports/tagmail.rb +4 -4
  337. data/lib/puppet/resource.rb +37 -44
  338. data/lib/puppet/resource/catalog.rb +18 -20
  339. data/lib/puppet/resource/status.rb +7 -6
  340. data/lib/puppet/resource/type.rb +6 -5
  341. data/lib/puppet/resource/type_collection.rb +2 -2
  342. data/lib/puppet/run.rb +9 -8
  343. data/lib/puppet/settings.rb +395 -244
  344. data/lib/puppet/settings/base_setting.rb +10 -4
  345. data/lib/puppet/settings/config_file.rb +81 -44
  346. data/lib/puppet/settings/directory_setting.rb +1 -2
  347. data/lib/puppet/settings/file_setting.rb +12 -5
  348. data/lib/puppet/settings/ini_file.rb +171 -0
  349. data/lib/puppet/ssl/base.rb +4 -0
  350. data/lib/puppet/ssl/certificate_authority.rb +16 -11
  351. data/lib/puppet/ssl/certificate_authority/interface.rb +3 -2
  352. data/lib/puppet/ssl/certificate_factory.rb +50 -5
  353. data/lib/puppet/ssl/certificate_request.rb +2 -2
  354. data/lib/puppet/ssl/certificate_request_attributes.rb +1 -1
  355. data/lib/puppet/ssl/certificate_revocation_list.rb +3 -1
  356. data/lib/puppet/ssl/host.rb +9 -8
  357. data/lib/puppet/ssl/inventory.rb +1 -1
  358. data/lib/puppet/ssl/key.rb +1 -1
  359. data/lib/puppet/ssl/validator/default_validator.rb +1 -1
  360. data/lib/puppet/status.rb +8 -7
  361. data/lib/puppet/test/test_helper.rb +35 -4
  362. data/lib/puppet/transaction/event.rb +6 -5
  363. data/lib/puppet/transaction/report.rb +10 -10
  364. data/lib/puppet/type.rb +1 -3
  365. data/lib/puppet/type/augeas.rb +2 -1
  366. data/lib/puppet/type/cron.rb +41 -11
  367. data/lib/puppet/type/exec.rb +5 -5
  368. data/lib/puppet/type/file.rb +42 -4
  369. data/lib/puppet/type/file/content.rb +5 -6
  370. data/lib/puppet/type/file/ensure.rb +3 -3
  371. data/lib/puppet/type/file/source.rb +12 -6
  372. data/lib/puppet/type/file/target.rb +5 -5
  373. data/lib/puppet/type/k5login.rb +4 -4
  374. data/lib/puppet/type/mount.rb +1 -1
  375. data/lib/puppet/type/package.rb +79 -3
  376. data/lib/puppet/type/resources.rb +34 -5
  377. data/lib/puppet/type/selboolean.rb +1 -1
  378. data/lib/puppet/type/selmodule.rb +1 -1
  379. data/lib/puppet/type/ssh_authorized_key.rb +2 -1
  380. data/lib/puppet/type/sshkey.rb +2 -1
  381. data/lib/puppet/type/tidy.rb +1 -1
  382. data/lib/puppet/type/user.rb +4 -1
  383. data/lib/puppet/type/yumrepo.rb +219 -344
  384. data/lib/puppet/type/zone.rb +15 -5
  385. data/lib/puppet/util.rb +14 -13
  386. data/lib/puppet/util/adsi.rb +19 -3
  387. data/lib/puppet/util/autoload.rb +27 -24
  388. data/lib/puppet/util/backups.rb +6 -6
  389. data/lib/puppet/util/checksums.rb +2 -2
  390. data/lib/puppet/util/classgen.rb +1 -1
  391. data/lib/puppet/util/colors.rb +4 -12
  392. data/lib/puppet/util/command_line.rb +2 -2
  393. data/lib/puppet/util/command_line/trollop.rb +3 -3
  394. data/lib/puppet/util/docs.rb +2 -2
  395. data/lib/puppet/util/errors.rb +8 -1
  396. data/lib/puppet/util/execution.rb +12 -5
  397. data/lib/puppet/util/filetype.rb +5 -5
  398. data/lib/puppet/util/inifile.rb +19 -4
  399. data/lib/puppet/util/instrumentation/data.rb +5 -0
  400. data/lib/puppet/util/instrumentation/indirection_probe.rb +6 -1
  401. data/lib/puppet/util/instrumentation/listener.rb +6 -1
  402. data/lib/puppet/util/json_lockfile.rb +4 -1
  403. data/lib/puppet/util/ldap/connection.rb +1 -1
  404. data/lib/puppet/util/lockfile.rb +10 -6
  405. data/lib/puppet/util/log.rb +6 -1
  406. data/lib/puppet/util/log/destinations.rb +2 -2
  407. data/lib/puppet/util/metric.rb +9 -4
  408. data/lib/puppet/util/nagios_maker.rb +26 -1
  409. data/lib/puppet/util/network_device.rb +1 -1
  410. data/lib/puppet/util/network_device/config.rb +1 -1
  411. data/lib/puppet/util/network_device/transport/ssh.rb +3 -3
  412. data/lib/puppet/util/plugins.rb +1 -1
  413. data/lib/puppet/util/profiler.rb +13 -1
  414. data/lib/puppet/util/pson.rb +1 -1
  415. data/lib/puppet/util/queue/stomp.rb +2 -2
  416. data/lib/puppet/util/rdoc.rb +1 -1
  417. data/lib/puppet/util/rdoc/generators/puppet_generator.rb +1 -1
  418. data/lib/puppet/util/rdoc/parser/puppet_parser_core.rb +19 -19
  419. data/lib/puppet/util/reference.rb +1 -1
  420. data/lib/puppet/util/resource_template.rb +1 -1
  421. data/lib/puppet/util/retryaction.rb +1 -1
  422. data/lib/puppet/util/selinux.rb +2 -2
  423. data/lib/puppet/util/storage.rb +3 -3
  424. data/lib/puppet/util/symbolic_file_mode.rb +1 -1
  425. data/lib/puppet/util/tag_set.rb +15 -3
  426. data/lib/puppet/util/tagging.rb +12 -17
  427. data/lib/puppet/util/watched_file.rb +1 -1
  428. data/lib/puppet/util/watcher.rb +1 -1
  429. data/lib/puppet/util/windows/error.rb +2 -2
  430. data/lib/puppet/util/windows/file.rb +20 -4
  431. data/lib/puppet/util/windows/registry.rb +2 -2
  432. data/lib/puppet/vendor/safe_yaml/CHANGES.md +1 -1
  433. data/lib/puppet/version.rb +1 -1
  434. data/lib/puppetx.rb +1 -21
  435. data/lib/puppetx/puppet/syntax_checker.rb +1 -1
  436. data/lib/puppetx/puppetlabs/syntax_checkers/json.rb +9 -11
  437. data/spec/fixtures/integration/node/environment/sitedir/00_a.pp +2 -0
  438. data/spec/fixtures/integration/node/environment/sitedir/01_b.pp +6 -0
  439. data/spec/fixtures/{unit/pops/binder/hiera2/yaml_backend/empty/common.yaml → integration/node/environment/sitedir/03_empty.pp} +0 -0
  440. data/spec/fixtures/integration/node/environment/sitedir/04_include.pp +2 -0
  441. data/spec/fixtures/integration/provider/cron/crontab/purged +8 -0
  442. data/spec/fixtures/releases/jamtur01-apache/lib/puppet/provider/a2mod/debian.rb +1 -1
  443. data/spec/fixtures/unit/pops/binder/bindings_composer/ok/binder_config.yaml +3 -12
  444. data/spec/fixtures/unit/pops/binder/bindings_composer/ok/lib/puppet/bindings/confdirtest.rb +10 -0
  445. data/spec/fixtures/unit/pops/binder/bindings_composer/ok/modules/awesome2/lib/puppet/bindings/awesome2/default.rb +20 -0
  446. data/spec/fixtures/unit/pops/binder/bindings_composer/ok/modules/{awesome/lib/puppetx/awesome → awesome2/lib/puppetx/awesome2}/echo_scheme_handler.rb +2 -2
  447. data/spec/fixtures/unit/pops/binder/bindings_composer/ok/modules/bad/lib/puppet/bindings/bad/default.rb +5 -0
  448. data/spec/fixtures/unit/pops/binder/bindings_composer/ok/modules/good/lib/puppet/bindings/good/default.rb +6 -0
  449. data/spec/fixtures/unit/pops/binder/config/binder_config/ok/binder_config.yaml +2 -2
  450. data/spec/fixtures/unit/provider/service/systemd/{list_units → list_units_services} +0 -1
  451. data/spec/integration/agent/logging_spec.rb +1 -1
  452. data/spec/integration/application/apply_spec.rb +78 -3
  453. data/spec/integration/application/doc_spec.rb +3 -2
  454. data/spec/integration/configurer_spec.rb +5 -3
  455. data/spec/integration/directory_environments_spec.rb +50 -0
  456. data/spec/integration/indirector/direct_file_server_spec.rb +1 -1
  457. data/spec/integration/indirector/file_content/file_server_spec.rb +4 -5
  458. data/spec/integration/network/authconfig_spec.rb +4 -4
  459. data/spec/integration/network/formats_spec.rb +1 -1
  460. data/spec/integration/node/environment_spec.rb +67 -15
  461. data/spec/integration/node/facts_spec.rb +1 -1
  462. data/spec/integration/node_spec.rb +1 -1
  463. data/spec/integration/parser/catalog_spec.rb +100 -60
  464. data/spec/integration/parser/compiler_spec.rb +102 -13
  465. data/spec/integration/parser/future_compiler_spec.rb +416 -0
  466. data/spec/integration/parser/parser_spec.rb +44 -105
  467. data/spec/integration/parser/scope_spec.rb +614 -528
  468. data/spec/integration/provider/cron/crontab_spec.rb +21 -0
  469. data/spec/integration/provider/mount_spec.rb +15 -2
  470. data/spec/integration/resource/catalog_spec.rb +1 -1
  471. data/spec/integration/resource/type_collection_spec.rb +3 -4
  472. data/spec/integration/ssl/autosign_spec.rb +1 -1
  473. data/spec/integration/ssl/certificate_revocation_list_spec.rb +1 -1
  474. data/spec/integration/ssl/host_spec.rb +1 -1
  475. data/spec/integration/transaction_spec.rb +13 -13
  476. data/spec/integration/type/exec_spec.rb +2 -2
  477. data/spec/integration/type/file_spec.rb +114 -41
  478. data/spec/integration/type/nagios_spec.rb +80 -0
  479. data/spec/integration/type/tidy_spec.rb +2 -2
  480. data/spec/integration/util/execution_spec.rb +17 -0
  481. data/spec/integration/util/rdoc/parser_spec.rb +1 -1
  482. data/spec/integration/util/settings_spec.rb +1 -1
  483. data/spec/integration/util/windows/security_spec.rb +27 -2
  484. data/spec/lib/matchers/include.rb +27 -0
  485. data/spec/lib/matchers/include_spec.rb +32 -0
  486. data/spec/lib/matchers/json.rb +135 -79
  487. data/spec/lib/matchers/match_tokens2.rb +74 -0
  488. data/spec/lib/matchers/resource.rb +35 -0
  489. data/spec/lib/puppet/indirector/indirector_testing/memory.rb +7 -0
  490. data/spec/lib/puppet/indirector/indirector_testing/msgpack.rb +6 -0
  491. data/spec/lib/puppet/indirector_testing.rb +12 -2
  492. data/spec/lib/puppet_spec/files.rb +1 -0
  493. data/spec/lib/puppet_spec/matchers.rb +5 -0
  494. data/spec/lib/puppet_spec/modules.rb +1 -1
  495. data/spec/lib/puppet_spec/scope.rb +14 -0
  496. data/spec/shared_behaviours/file_server_terminus.rb +2 -2
  497. data/spec/spec_helper.rb +47 -17
  498. data/spec/unit/agent_spec.rb +8 -1
  499. data/spec/unit/application/agent_spec.rb +5 -4
  500. data/spec/unit/application/apply_spec.rb +34 -15
  501. data/spec/unit/application/device_spec.rb +27 -32
  502. data/spec/unit/application/doc_spec.rb +4 -4
  503. data/spec/unit/application/filebucket_spec.rb +1 -1
  504. data/spec/unit/application/master_spec.rb +2 -2
  505. data/spec/unit/application_spec.rb +1 -1
  506. data/spec/unit/configurer/downloader_spec.rb +1 -1
  507. data/spec/unit/configurer/fact_handler_spec.rb +5 -16
  508. data/spec/unit/configurer_spec.rb +2 -2
  509. data/spec/unit/confine/exists_spec.rb +5 -5
  510. data/spec/unit/context/trusted_information_spec.rb +124 -0
  511. data/spec/unit/context_spec.rb +74 -0
  512. data/spec/unit/environments_spec.rb +126 -0
  513. data/spec/unit/face/config_spec.rb +31 -16
  514. data/spec/unit/face/module/build_spec.rb +1 -0
  515. data/spec/unit/face/module/install_spec.rb +21 -104
  516. data/spec/unit/face/module/list_spec.rb +52 -36
  517. data/spec/unit/face/module/uninstall_spec.rb +18 -25
  518. data/spec/unit/face/parser_spec.rb +39 -23
  519. data/spec/unit/file_bucket/dipper_spec.rb +2 -2
  520. data/spec/unit/file_serving/base_spec.rb +9 -13
  521. data/spec/unit/file_serving/configuration/parser_spec.rb +8 -2
  522. data/spec/unit/file_serving/configuration_spec.rb +7 -7
  523. data/spec/unit/file_serving/content_spec.rb +7 -12
  524. data/spec/unit/file_serving/fileset_spec.rb +49 -53
  525. data/spec/unit/file_serving/metadata_spec.rb +83 -32
  526. data/spec/unit/file_serving/mount/file_spec.rb +10 -10
  527. data/spec/unit/file_system/tempfile_spec.rb +3 -3
  528. data/spec/unit/file_system_spec.rb +508 -0
  529. data/spec/unit/forge/errors_spec.rb +1 -1
  530. data/spec/unit/forge/repository_spec.rb +1 -3
  531. data/spec/unit/hiera/scope_spec.rb +6 -2
  532. data/spec/unit/hiera_puppet_spec.rb +13 -6
  533. data/spec/unit/indirector/catalog/msgpack_spec.rb +12 -0
  534. data/spec/unit/indirector/catalog/static_compiler_spec.rb +42 -11
  535. data/spec/unit/indirector/direct_file_server_spec.rb +6 -6
  536. data/spec/unit/indirector/facts/facter_spec.rb +5 -5
  537. data/spec/unit/indirector/file_bucket_file/file_spec.rb +4 -4
  538. data/spec/unit/indirector/file_metadata/file_spec.rb +2 -2
  539. data/spec/unit/indirector/file_server_spec.rb +4 -4
  540. data/spec/unit/indirector/json_spec.rb +6 -6
  541. data/spec/unit/indirector/key/file_spec.rb +8 -8
  542. data/spec/unit/indirector/msgpack_spec.rb +191 -0
  543. data/spec/unit/indirector/node/active_record_spec.rb +1 -1
  544. data/spec/unit/indirector/node/ldap_spec.rb +16 -7
  545. data/spec/unit/indirector/node/msgpack_spec.rb +24 -0
  546. data/spec/unit/indirector/node/plain_spec.rb +1 -1
  547. data/spec/unit/indirector/queue_spec.rb +1 -1
  548. data/spec/unit/indirector/report/msgpack_spec.rb +28 -0
  549. data/spec/unit/indirector/request_spec.rb +16 -8
  550. data/spec/unit/indirector/rest_spec.rb +0 -4
  551. data/spec/unit/indirector/ssl_file_spec.rb +12 -11
  552. data/spec/unit/indirector/yaml_spec.rb +4 -4
  553. data/spec/unit/man_spec.rb +32 -0
  554. data/spec/unit/module_spec.rb +60 -46
  555. data/spec/unit/module_tool/applications/checksummer_spec.rb +1 -1
  556. data/spec/unit/module_tool/applications/installer_spec.rb +53 -16
  557. data/spec/unit/module_tool/applications/uninstaller_spec.rb +26 -25
  558. data/spec/unit/module_tool/tar_spec.rb +1 -1
  559. data/spec/unit/module_tool_spec.rb +17 -90
  560. data/spec/unit/network/authconfig_spec.rb +3 -4
  561. data/spec/unit/network/authentication_spec.rb +20 -6
  562. data/spec/unit/network/authorization_spec.rb +11 -1
  563. data/spec/unit/network/formats_spec.rb +32 -9
  564. data/spec/unit/network/http/api/v1_spec.rb +365 -62
  565. data/spec/unit/network/http/api/v2/authorization_spec.rb +57 -0
  566. data/spec/unit/network/http/api/v2/environments_spec.rb +42 -0
  567. data/spec/unit/network/http/api/v2_spec.rb +14 -0
  568. data/spec/unit/network/http/connection_spec.rb +39 -5
  569. data/spec/unit/network/http/error_spec.rb +30 -0
  570. data/spec/unit/network/http/handler_spec.rb +69 -419
  571. data/spec/unit/network/http/rack/rest_spec.rb +20 -28
  572. data/spec/unit/network/http/route_spec.rb +75 -0
  573. data/spec/unit/network/http/webrick/rest_spec.rb +21 -58
  574. data/spec/unit/network/http_pool_spec.rb +3 -3
  575. data/spec/unit/network/rights_spec.rb +2 -2
  576. data/spec/unit/node/environment_spec.rb +108 -89
  577. data/spec/unit/node/facts_spec.rb +5 -12
  578. data/spec/unit/node_spec.rb +22 -22
  579. data/spec/unit/parser/ast/collection_spec.rb +1 -1
  580. data/spec/unit/parser/ast/leaf_spec.rb +2 -0
  581. data/spec/unit/parser/ast/resource_spec.rb +1 -1
  582. data/spec/unit/parser/compiler_spec.rb +5 -3
  583. data/spec/unit/parser/files_spec.rb +40 -50
  584. data/spec/unit/parser/functions/defined_spec.rb +80 -18
  585. data/spec/unit/parser/functions/epp_spec.rb +88 -0
  586. data/spec/unit/parser/functions/fqdn_rand_spec.rb +4 -1
  587. data/spec/unit/parser/functions/generate_spec.rb +6 -2
  588. data/spec/unit/parser/functions/hiera_array_spec.rb +5 -2
  589. data/spec/unit/parser/functions/hiera_hash_spec.rb +4 -1
  590. data/spec/unit/parser/functions/hiera_include_spec.rb +6 -3
  591. data/spec/unit/parser/functions/hiera_spec.rb +5 -2
  592. data/spec/unit/parser/functions/include_spec.rb +0 -1
  593. data/spec/unit/parser/functions/inline_epp_spec.rb +82 -0
  594. data/spec/unit/parser/functions/lookup_spec.rb +66 -16
  595. data/spec/unit/parser/functions_spec.rb +25 -91
  596. data/spec/unit/parser/lexer_spec.rb +1 -1
  597. data/spec/unit/parser/methods/filter_spec.rb +56 -0
  598. data/spec/unit/parser/methods/map_spec.rb +94 -5
  599. data/spec/unit/parser/methods/reduce_spec.rb +10 -0
  600. data/spec/unit/parser/methods/shared.rb +2 -18
  601. data/spec/unit/parser/methods/slice_spec.rb +39 -1
  602. data/spec/unit/parser/parser_spec.rb +14 -10
  603. data/spec/unit/parser/resource_spec.rb +3 -9
  604. data/spec/unit/parser/scope_spec.rb +81 -78
  605. data/spec/unit/parser/type_loader_spec.rb +0 -4
  606. data/spec/unit/pops/benchmark_spec.rb +142 -0
  607. data/spec/unit/pops/binder/binder_spec.rb +15 -34
  608. data/spec/unit/pops/binder/bindings_checker_spec.rb +0 -41
  609. data/spec/unit/pops/binder/bindings_composer_spec.rb +6 -31
  610. data/spec/unit/pops/binder/config/binder_config_spec.rb +5 -18
  611. data/spec/unit/pops/binder/injector_spec.rb +76 -81
  612. data/spec/unit/pops/evaluator/access_ops_spec.rb +376 -0
  613. data/spec/unit/pops/evaluator/arithmetic_ops_spec.rb +77 -0
  614. data/spec/unit/pops/evaluator/basic_expressions_spec.rb +103 -0
  615. data/spec/unit/pops/evaluator/collections_ops_spec.rb +111 -0
  616. data/spec/unit/pops/evaluator/comparison_ops_spec.rb +256 -0
  617. data/spec/unit/pops/evaluator/conditionals_spec.rb +190 -0
  618. data/spec/unit/pops/evaluator/evaluating_parser_spec.rb +1045 -0
  619. data/spec/unit/pops/evaluator/evaluator_rspec_helper.rb +75 -0
  620. data/spec/unit/pops/evaluator/logical_ops_spec.rb +90 -0
  621. data/spec/unit/pops/evaluator/string_interpolation_spec.rb +44 -0
  622. data/spec/unit/pops/evaluator/variables_spec.rb +194 -0
  623. data/spec/unit/pops/factory_spec.rb +6 -29
  624. data/spec/unit/pops/issues_spec.rb +1 -1
  625. data/spec/unit/pops/model/ast_transformer_spec.rb +6 -9
  626. data/spec/unit/pops/model/model_spec.rb +2 -2
  627. data/spec/unit/pops/parser/epp_parser_spec.rb +86 -0
  628. data/spec/unit/pops/parser/evaluating_parser_spec.rb +4 -2
  629. data/spec/unit/pops/parser/lexer2_spec.rb +428 -0
  630. data/spec/unit/pops/parser/lexer_spec.rb +25 -86
  631. data/spec/unit/pops/parser/parse_basic_expressions_spec.rb +29 -4
  632. data/spec/unit/pops/parser/parse_calls_spec.rb +10 -6
  633. data/spec/unit/pops/parser/parse_conditionals_spec.rb +0 -9
  634. data/spec/unit/pops/parser/parse_containers_spec.rb +43 -12
  635. data/spec/unit/pops/parser/parse_heredoc_spec.rb +73 -0
  636. data/spec/unit/pops/parser/parse_resource_spec.rb +14 -0
  637. data/spec/unit/pops/parser/parser_spec.rb +3 -1
  638. data/spec/unit/pops/transformer/transform_basic_expressions_spec.rb +4 -4
  639. data/spec/unit/pops/transformer/transform_calls_spec.rb +41 -6
  640. data/spec/unit/pops/transformer/transform_conditionals_spec.rb +0 -9
  641. data/spec/unit/pops/transformer/transform_containers_spec.rb +12 -4
  642. data/spec/unit/pops/types/enumeration_spec.rb +50 -0
  643. data/spec/unit/pops/types/type_calculator_spec.rb +1171 -196
  644. data/spec/unit/pops/types/type_factory_spec.rb +108 -4
  645. data/spec/unit/pops/types/type_parser_spec.rb +114 -10
  646. data/spec/unit/pops/validator/validator_spec.rb +36 -1
  647. data/spec/unit/provider/augeas/augeas_spec.rb +39 -16
  648. data/spec/unit/provider/cron/parsed_spec.rb +27 -31
  649. data/spec/unit/provider/file/posix_spec.rb +2 -2
  650. data/spec/unit/provider/group/windows_adsi_spec.rb +1 -0
  651. data/spec/unit/provider/mount_spec.rb +12 -1
  652. data/spec/unit/provider/nameservice/directoryservice_spec.rb +3 -3
  653. data/spec/unit/provider/package/apt_spec.rb +1 -1
  654. data/spec/unit/provider/package/aptrpm_spec.rb +1 -1
  655. data/spec/unit/provider/package/gem_spec.rb +12 -0
  656. data/spec/unit/provider/package/msi_spec.rb +4 -0
  657. data/spec/unit/provider/package/openbsd_spec.rb +10 -10
  658. data/spec/unit/provider/package/pacman_spec.rb +36 -7
  659. data/spec/unit/provider/package/pkgin_spec.rb +57 -55
  660. data/spec/unit/provider/package/rpm_spec.rb +51 -6
  661. data/spec/unit/provider/service/base_spec.rb +4 -4
  662. data/spec/unit/provider/service/daemontools_spec.rb +8 -13
  663. data/spec/unit/provider/service/freebsd_spec.rb +3 -3
  664. data/spec/unit/provider/service/gentoo_spec.rb +24 -24
  665. data/spec/unit/provider/service/init_spec.rb +15 -15
  666. data/spec/unit/provider/service/openbsd_spec.rb +16 -16
  667. data/spec/unit/provider/service/openrc_spec.rb +20 -20
  668. data/spec/unit/provider/service/openwrt_spec.rb +1 -1
  669. data/spec/unit/provider/service/runit_spec.rb +5 -8
  670. data/spec/unit/provider/service/src_spec.rb +4 -4
  671. data/spec/unit/provider/service/systemd_spec.rb +24 -14
  672. data/spec/unit/provider/service/upstart_spec.rb +12 -4
  673. data/spec/unit/provider/service/windows_spec.rb +1 -1
  674. data/spec/unit/provider/ssh_authorized_key/parsed_spec.rb +21 -23
  675. data/spec/unit/provider/user/directoryservice_spec.rb +7 -7
  676. data/spec/unit/provider/user/useradd_spec.rb +43 -15
  677. data/spec/unit/provider/user/windows_adsi_spec.rb +1 -0
  678. data/spec/unit/provider/yumrepo/inifile_spec.rb +105 -0
  679. data/spec/unit/provider/zone/solaris_spec.rb +1 -1
  680. data/spec/unit/provider_spec.rb +120 -62
  681. data/spec/unit/rails/host_spec.rb +1 -1
  682. data/spec/unit/rails/param_value_spec.rb +4 -0
  683. data/spec/unit/relationship_spec.rb +4 -4
  684. data/spec/unit/reports/http_spec.rb +14 -3
  685. data/spec/unit/reports/rrdgraph_spec.rb +0 -1
  686. data/spec/unit/reports/store_spec.rb +2 -2
  687. data/spec/unit/resource/catalog_spec.rb +17 -29
  688. data/spec/unit/resource/status_spec.rb +1 -1
  689. data/spec/unit/resource/type_collection_spec.rb +28 -47
  690. data/spec/unit/resource/type_spec.rb +12 -23
  691. data/spec/unit/resource_spec.rb +54 -93
  692. data/spec/unit/run_spec.rb +3 -3
  693. data/spec/unit/settings/autosign_setting_spec.rb +1 -1
  694. data/spec/unit/settings/config_file_spec.rb +68 -15
  695. data/spec/unit/settings/file_setting_spec.rb +2 -2
  696. data/spec/unit/settings/ini_file_spec.rb +184 -0
  697. data/spec/unit/settings_spec.rb +137 -79
  698. data/spec/unit/ssl/certificate_authority/interface_spec.rb +3 -1
  699. data/spec/unit/ssl/certificate_authority_spec.rb +11 -9
  700. data/spec/unit/ssl/certificate_factory_spec.rb +19 -4
  701. data/spec/unit/ssl/certificate_request_attributes_spec.rb +1 -1
  702. data/spec/unit/ssl/certificate_revocation_list_spec.rb +101 -72
  703. data/spec/unit/ssl/host_spec.rb +8 -20
  704. data/spec/unit/ssl/inventory_spec.rb +2 -2
  705. data/spec/unit/ssl/key_spec.rb +4 -4
  706. data/spec/unit/status_spec.rb +6 -4
  707. data/spec/unit/transaction/additional_resource_generator_spec.rb +3 -11
  708. data/spec/unit/transaction/event_spec.rb +2 -2
  709. data/spec/unit/transaction/report_spec.rb +24 -15
  710. data/spec/unit/transaction/resource_harness_spec.rb +1 -1
  711. data/spec/unit/type/cron_spec.rb +39 -1
  712. data/spec/unit/type/file/content_spec.rb +4 -5
  713. data/spec/unit/type/file/ctime_spec.rb +1 -1
  714. data/spec/unit/type/file/mode_spec.rb +5 -4
  715. data/spec/unit/type/file/mtime_spec.rb +1 -1
  716. data/spec/unit/type/file/source_spec.rb +30 -7
  717. data/spec/unit/type/file_spec.rb +8 -8
  718. data/spec/unit/type/k5login_spec.rb +3 -3
  719. data/spec/unit/type/nagios_spec.rb +6 -0
  720. data/spec/unit/type/package/package_settings_spec.rb +135 -0
  721. data/spec/unit/type/package_spec.rb +13 -1
  722. data/spec/unit/type/resources_spec.rb +155 -0
  723. data/spec/unit/type/service_spec.rb +3 -3
  724. data/spec/unit/type/ssh_authorized_key_spec.rb +96 -93
  725. data/spec/unit/type/sshkey_spec.rb +39 -30
  726. data/spec/unit/type/tidy_spec.rb +19 -12
  727. data/spec/unit/type/user_spec.rb +47 -2
  728. data/spec/unit/type/whit_spec.rb +2 -2
  729. data/spec/unit/type/yumrepo_spec.rb +32 -177
  730. data/spec/unit/type/zone_spec.rb +2 -2
  731. data/spec/unit/type_spec.rb +11 -0
  732. data/spec/unit/util/adsi_spec.rb +48 -1
  733. data/spec/unit/util/autoload_spec.rb +24 -39
  734. data/spec/unit/util/backups_spec.rb +25 -28
  735. data/spec/unit/util/checksums_spec.rb +1 -3
  736. data/spec/unit/util/colors_spec.rb +14 -0
  737. data/spec/unit/util/docs_spec.rb +9 -0
  738. data/spec/unit/util/execution_spec.rb +1 -1
  739. data/spec/unit/util/filetype_spec.rb +7 -7
  740. data/spec/unit/util/instrumentation/data_spec.rb +3 -1
  741. data/spec/unit/util/instrumentation/indirection_probe_spec.rb +2 -0
  742. data/spec/unit/util/instrumentation/listener_spec.rb +3 -2
  743. data/spec/unit/util/json_lockfile_spec.rb +25 -4
  744. data/spec/unit/util/lockfile_spec.rb +49 -7
  745. data/spec/unit/util/log/destinations_spec.rb +1 -0
  746. data/spec/unit/util/log_spec.rb +1 -1
  747. data/spec/unit/util/metric_spec.rb +1 -1
  748. data/spec/unit/util/pidlock_spec.rb +6 -6
  749. data/spec/unit/util/pson_spec.rb +2 -2
  750. data/spec/unit/util/rdoc/parser_spec.rb +32 -29
  751. data/spec/unit/util/resource_template_spec.rb +3 -3
  752. data/spec/unit/util/selinux_spec.rb +5 -5
  753. data/spec/unit/util/storage_spec.rb +4 -4
  754. data/spec/unit/util/tag_set_spec.rb +1 -1
  755. data/spec/unit/util/watcher_spec.rb +1 -4
  756. data/spec/unit/util/yaml_spec.rb +2 -2
  757. data/spec/unit/util_spec.rb +7 -7
  758. data/tasks/benchmark.rake +0 -1
  759. data/tasks/parallel.rake +408 -0
  760. data/tasks/yard.rake +59 -0
  761. metadata +2889 -2782
  762. checksums.yaml +0 -7
  763. data/README_DEVELOPER.md +0 -809
  764. data/lib/puppet/file_system/file.rb +0 -271
  765. data/lib/puppet/network/http/rack/httphandler.rb +0 -13
  766. data/lib/puppet/pops/binder/hiera2.rb +0 -10
  767. data/lib/puppet/pops/binder/hiera2/bindings_provider.rb +0 -148
  768. data/lib/puppet/pops/binder/hiera2/config.rb +0 -69
  769. data/lib/puppet/pops/binder/hiera2/config_checker.rb +0 -68
  770. data/lib/puppet/pops/binder/hiera2/diagnostic_producer.rb +0 -36
  771. data/lib/puppet/pops/binder/hiera2/issues.rb +0 -67
  772. data/lib/puppet/pops/binder/hiera2/json_backend.rb +0 -18
  773. data/lib/puppet/pops/binder/hiera2/yaml_backend.rb +0 -21
  774. data/lib/puppet/pops/binder/scheme_handler/confdir_hiera_scheme.rb +0 -67
  775. data/lib/puppet/pops/binder/scheme_handler/module_hiera_scheme.rb +0 -92
  776. data/lib/puppet/pops/parser/grammar.ra +0 -746
  777. data/lib/puppet/provider/port/parsed.rb +0 -173
  778. data/lib/puppet/type/port.rb +0 -119
  779. data/lib/puppetx/puppet/hiera2_backend.rb +0 -31
  780. data/spec/fixtures/unit/pops/binder/bindings_composer/hiera1config/binder_config.yaml +0 -18
  781. data/spec/fixtures/unit/pops/binder/bindings_composer/hiera1config/hiera.yaml +0 -8
  782. data/spec/fixtures/unit/pops/binder/bindings_composer/hiera1config/modules/good/common.yaml +0 -1
  783. data/spec/fixtures/unit/pops/binder/bindings_composer/hiera1config/modules/good/hiera.yaml +0 -10
  784. data/spec/fixtures/unit/pops/binder/bindings_composer/ok/common.yaml +0 -1
  785. data/spec/fixtures/unit/pops/binder/bindings_composer/ok/hiera.yaml +0 -11
  786. data/spec/fixtures/unit/pops/binder/bindings_composer/ok/localhost.yaml +0 -1
  787. data/spec/fixtures/unit/pops/binder/bindings_composer/ok/modules/awesome/common.yaml +0 -3
  788. data/spec/fixtures/unit/pops/binder/bindings_composer/ok/modules/awesome/hiera.yaml +0 -13
  789. data/spec/fixtures/unit/pops/binder/bindings_composer/ok/modules/awesome/lib/puppet/bindings/awesome/default.rb +0 -4
  790. data/spec/fixtures/unit/pops/binder/bindings_composer/ok/modules/awesome/lib/puppetx/awesome/echo_backend.rb +0 -11
  791. data/spec/fixtures/unit/pops/binder/bindings_composer/ok/modules/awesome/localhost.yaml +0 -1
  792. data/spec/fixtures/unit/pops/binder/bindings_composer/ok/modules/bad/common.yaml +0 -3
  793. data/spec/fixtures/unit/pops/binder/bindings_composer/ok/modules/bad/hiera_config.yaml +0 -9
  794. data/spec/fixtures/unit/pops/binder/bindings_composer/ok/modules/good/common.yaml +0 -2
  795. data/spec/fixtures/unit/pops/binder/bindings_composer/ok/modules/good/hiera.yaml +0 -11
  796. data/spec/fixtures/unit/pops/binder/hiera2/bindings_provider/ok/hiera.yaml +0 -9
  797. data/spec/fixtures/unit/pops/binder/hiera2/bindings_provider/ok/node.example.com.json +0 -9
  798. data/spec/fixtures/unit/pops/binder/hiera2/bindings_provider/ok/node.example.com.yaml +0 -5
  799. data/spec/fixtures/unit/pops/binder/hiera2/config/bad_syntax/hiera.yaml +0 -10
  800. data/spec/fixtures/unit/pops/binder/hiera2/config/malformed_hierarchy/hiera.yaml +0 -8
  801. data/spec/fixtures/unit/pops/binder/hiera2/config/missing/foo.txt +0 -1
  802. data/spec/fixtures/unit/pops/binder/hiera2/config/no_backends/hiera.yaml +0 -7
  803. data/spec/fixtures/unit/pops/binder/hiera2/config/no_hierarchy/hiera.yaml +0 -4
  804. data/spec/fixtures/unit/pops/binder/hiera2/config/not_a_hash/hiera.yaml +0 -2
  805. data/spec/fixtures/unit/pops/binder/hiera2/config/ok/hiera.yaml +0 -8
  806. data/spec/fixtures/unit/pops/binder/hiera2/yaml_backend/invalid/common.yaml +0 -1
  807. data/spec/fixtures/unit/pops/binder/hiera2/yaml_backend/ok/common.yaml +0 -2
  808. data/spec/unit/file_system/file_spec.rb +0 -486
  809. data/spec/unit/pops/binder/hiera2/bindings_provider_spec.rb +0 -74
  810. data/spec/unit/pops/binder/hiera2/config_spec.rb +0 -61
  811. data/spec/unit/pops/binder/hiera2/yaml_backend_spec.rb +0 -33
@@ -126,6 +126,20 @@ describe "egrammar parsing resource declarations" do
126
126
  ].join("\n")
127
127
  end
128
128
 
129
+ it "@class { 'cname': }" do
130
+ dump(parse("@class { 'cname': }")).should == [
131
+ "(virtual-resource class",
132
+ " ('cname'))"
133
+ ].join("\n")
134
+ end
135
+
136
+ it "@@class { 'cname': }" do
137
+ dump(parse("@@class { 'cname': }")).should == [
138
+ "(exported-resource class",
139
+ " ('cname'))"
140
+ ].join("\n")
141
+ end
142
+
129
143
  it "class { 'cname': x => 1, y => 2}" do
130
144
  dump(parse("class { 'cname': x => 1, y => 2}")).should == [
131
145
  "(resource class",
@@ -10,6 +10,8 @@ describe Puppet::Pops::Parser::Parser do
10
10
  it "should parse a code string and return a model" do
11
11
  parser = Puppet::Pops::Parser::Parser.new()
12
12
  model = parser.parse_string("$a = 10").current
13
- model.class.should == Puppet::Pops::Model::AssignmentExpression
13
+ model.class.should == Puppet::Pops::Model::Program
14
+ model.body.class.should == Puppet::Pops::Model::AssignmentExpression
14
15
  end
16
+
15
17
  end
@@ -117,13 +117,13 @@ describe "transformation to Puppet AST for basic expressions" do
117
117
  end
118
118
 
119
119
  context "of regular expressions (parse errors)" do
120
- # Not supported in concrete syntax
120
+ # Not supported in concrete syntax (until Lexer2)
121
121
  it "$a = /.*/ == /.*/" do
122
- expect { parse("$a = /.*/ == /.*/") }.to raise_error(Puppet::ParseError)
122
+ astdump(parse("$a = /.*/ == /.*/")).should == "(= $a (== /.*/ /.*/))"
123
123
  end
124
124
 
125
125
  it "$a = /.*/ != /a.*/" do
126
- expect { parse("$a = /.*/ != /.*/") }.to raise_error(Puppet::ParseError)
126
+ astdump(parse("$a = /.*/ != /.*/")).should == "(= $a (!= /.*/ /.*/))"
127
127
  end
128
128
  end
129
129
  end
@@ -237,7 +237,7 @@ describe "transformation to Puppet AST for basic expressions" do
237
237
  end
238
238
 
239
239
  it "should interpolate any expression in a text expression, \"${var*2}\"" do
240
- astdump(parse("$a = \"yo${var+2}yo\"")).should == "(= $a (cat 'yo' (str (+ $var 2)) 'yo'))"
240
+ astdump(parse("$a = \"yo${$var+2}yo\"")).should == "(= $a (cat 'yo' (str (+ $var 2)) 'yo'))"
241
241
  end
242
242
  end
243
243
  end
@@ -14,8 +14,8 @@ describe "transformation to Puppet AST for function calls" do
14
14
  astdump(parse("foo()")).should == "(invoke foo)"
15
15
  end
16
16
 
17
- it "foo bar" do
18
- astdump(parse("foo bar")).should == "(invoke foo bar)"
17
+ it "notice bar" do
18
+ astdump(parse("notice bar")).should == "(invoke notice bar)"
19
19
  end
20
20
  end
21
21
 
@@ -24,10 +24,45 @@ describe "transformation to Puppet AST for function calls" do
24
24
  astdump(parse("if true {foo()}")).should == "(if true\n (then (invoke foo)))"
25
25
  end
26
26
 
27
- it "if true { foo bar}" do
28
- astdump(parse("if true {foo bar}")).should == "(if true\n (then (invoke foo bar)))"
27
+ it "if true { notice bar}" do
28
+ astdump(parse("if true {notice bar}")).should == "(if true\n (then (invoke notice bar)))"
29
29
  end
30
30
  end
31
+ context "in general" do
32
+ {
33
+ "require bar" => '(invoke require bar)',
34
+ "realize bar" => '(invoke realize bar)',
35
+ "contain bar" => '(invoke contain bar)',
36
+ "include bar" => '(invoke include bar)',
37
+
38
+ "info bar" => '(invoke info bar)',
39
+ "notice bar" => '(invoke notice bar)',
40
+ "error bar" => '(invoke error bar)',
41
+ "warning bar" => '(invoke warning bar)',
42
+ "debug bar" => '(invoke debug bar)',
43
+
44
+ "fail bar" => '(invoke fail bar)',
45
+
46
+ "notice {a => 1}" => "(invoke notice ({} ('a' 1)))",
47
+ "notice 1,2,3" => "(invoke notice 1 2 3)",
48
+ "notice(1,2,3)" => "(invoke notice 1 2 3)",
49
+ }.each do |source, result|
50
+ it "should transform #{source} to #{result}" do
51
+ astdump(parse(source)).should == result
52
+ end
53
+ end
54
+
55
+ {
56
+ "foo bar" => '(block foo bar)',
57
+ "tag bar" => '(block tag bar)',
58
+ "tag" => 'tag',
59
+ }.each do |source, result|
60
+ it "should not transform #{source}, and instead produce #{result}" do
61
+ astdump(parse(source)).should == result
62
+ end
63
+ end
64
+
65
+ end
31
66
  end
32
67
 
33
68
  context "When transforming calls as expressions" do
@@ -60,7 +95,7 @@ describe "transformation to Puppet AST for function calls" do
60
95
  astdump(parse("$a.foo")).should == "(call-method (. $a foo))"
61
96
  end
62
97
 
63
- it "$a.foo ||{ }" do
98
+ it "$a.foo || { }" do
64
99
  astdump(parse("$a.foo || { }")).should == "(call-method (. $a foo) (lambda ()))"
65
100
  end
66
101
 
@@ -68,7 +103,7 @@ describe "transformation to Puppet AST for function calls" do
68
103
  astdump(parse("$a.foo || {[]}")).should == "(call-method (. $a foo) (lambda (block ([]))))"
69
104
  end
70
105
 
71
- it "$a.foo {|$x| }" do
106
+ it "$a.foo |$x| { }" do
72
107
  astdump(parse("$a.foo |$x| { }")).should == "(call-method (. $a foo) (lambda (parameters x) ()))"
73
108
  end
74
109
 
@@ -120,13 +120,4 @@ describe "transformation to Puppet AST for conditionals" do
120
120
  end
121
121
  end
122
122
 
123
- context "When transforming imports" do
124
- it "import 'foo'" do
125
- astdump(parse("import 'foo'")).should == ":nop"
126
- end
127
-
128
- it "import 'foo', 'bar'" do
129
- astdump(parse("import 'foo', 'bar'")).should == ":nop"
130
- end
131
- end
132
123
  end
@@ -57,7 +57,9 @@ describe "transformation to Puppet AST for containers" do
57
57
  # a very confusing effect when resolving relative names, getting the global hardwired "Class"
58
58
  # instead of some foo::class etc.
59
59
  # This is allowed in 3.x.
60
+ expect {
60
61
  astdump(parse("class class {}")).should == "(class class ())"
62
+ }.to raise_error(/is not a valid classname/)
61
63
  end
62
64
 
63
65
  it "class default {} # a class named 'default'" do
@@ -81,11 +83,15 @@ describe "transformation to Puppet AST for containers" do
81
83
  # full class name for nested classes - only, it gets this wrong when a class is named "class" - or at least
82
84
  # I think it is wrong.)
83
85
  #
84
- astdump(parse("class class inherits default {}")).should == "(class class::class (inherits default) ())"
86
+ expect {
87
+ astdump(parse("class class inherits default {}")).should == "(class class::class (inherits default) ())"
88
+ }.to raise_error(/is not a valid classname/)
85
89
  end
86
90
 
87
91
  it "class foo inherits class" do
88
- astdump(parse("class foo inherits class {}")).should == "(class foo (inherits class) ())"
92
+ expect {
93
+ astdump(parse("class foo inherits class {}")).should == "(class foo (inherits class) ())"
94
+ }.to raise_error(/is not a valid classname/)
89
95
  end
90
96
  end
91
97
  end
@@ -119,7 +125,9 @@ describe "transformation to Puppet AST for containers" do
119
125
  it "define class {} # a define named 'class'" do
120
126
  # This is weird because Class already exists, and instantiating this define will probably not
121
127
  # work
122
- astdump(parse("define class {}")).should == "(define class ())"
128
+ expect {
129
+ astdump(parse("define class {}")).should == "(define class ())"
130
+ }.to raise_error(/is not a valid classname/)
123
131
  end
124
132
 
125
133
  it "define default {} # a define named 'default'" do
@@ -171,7 +179,7 @@ describe "transformation to Puppet AST for containers" do
171
179
  end
172
180
 
173
181
  it "node wat inherits /apache.*/ {}" do
174
- expect { parse("node wat inherits /apache.*/ {}")}.to raise_error(Puppet::ParseError)
182
+ astdump(parse("node wat inherits /apache.*/ {}")).should == "(node (matches 'wat') (parent /apache.*/) ())"
175
183
  end
176
184
 
177
185
  it "node foo inherits bar {$a = 10 $b = 20}" do
@@ -0,0 +1,50 @@
1
+ require 'spec_helper'
2
+ require 'puppet/pops'
3
+
4
+ describe 'The enumeration support' do
5
+ it 'produces an enumerator for Array' do
6
+ expect(Puppet::Pops::Types::Enumeration.enumerator([1,2,3]).respond_to?(:next)).to eql(true)
7
+ end
8
+
9
+ it 'produces an enumerator for Hash' do
10
+ expect(Puppet::Pops::Types::Enumeration.enumerator({:a=>1}).respond_to?(:next)).to eql(true)
11
+ end
12
+
13
+ it 'produces a char enumerator for String' do
14
+ enum = Puppet::Pops::Types::Enumeration.enumerator("abc")
15
+ expect(enum.respond_to?(:next)).to eql(true)
16
+ expect(enum.next).to eql('a')
17
+ end
18
+
19
+ it 'produces an enumerator for integer times' do
20
+ enum = Puppet::Pops::Types::Enumeration.enumerator(2)
21
+ expect(enum.next).to eql(0)
22
+ expect(enum.next).to eql(1)
23
+ expect{enum.next}.to raise_error(StopIteration)
24
+ end
25
+
26
+ it 'produces an enumerator for Integer range' do
27
+ range = Puppet::Pops::Types::TypeFactory.range(1,2)
28
+ enum = Puppet::Pops::Types::Enumeration.enumerator(range)
29
+ expect(enum.next).to eql(1)
30
+ expect(enum.next).to eql(2)
31
+ expect{enum.next}.to raise_error(StopIteration)
32
+ end
33
+
34
+ it 'does not produce an enumerator for infinite Integer range' do
35
+ range = Puppet::Pops::Types::TypeFactory.range(1,:default)
36
+ enum = Puppet::Pops::Types::Enumeration.enumerator(range)
37
+ expect(enum).to be_nil
38
+ range = Puppet::Pops::Types::TypeFactory.range(:default,2)
39
+ enum = Puppet::Pops::Types::Enumeration.enumerator(range)
40
+ expect(enum).to be_nil
41
+ end
42
+
43
+ [3.14, /.*/, true, false, nil, :something].each do |x|
44
+ it "does not produce an enumerator for object of type #{x.class}" do
45
+ enum = Puppet::Pops::Types::Enumeration.enumerator(x)
46
+ expect(enum).to be_nil
47
+ end
48
+ end
49
+
50
+ end
@@ -4,6 +4,157 @@ require 'puppet/pops'
4
4
  describe 'The type calculator' do
5
5
  let(:calculator) { Puppet::Pops::Types::TypeCalculator.new() }
6
6
 
7
+ def range_t(from, to)
8
+ t = Puppet::Pops::Types::PIntegerType.new
9
+ t.from = from
10
+ t.to = to
11
+ t
12
+ end
13
+
14
+ def pattern_t(*patterns)
15
+ Puppet::Pops::Types::TypeFactory.pattern(*patterns)
16
+ end
17
+
18
+ def regexp_t(pattern)
19
+ Puppet::Pops::Types::TypeFactory.regexp(pattern)
20
+ end
21
+
22
+ def string_t(*strings)
23
+ Puppet::Pops::Types::TypeFactory.string(*strings)
24
+ end
25
+
26
+ def enum_t(*strings)
27
+ Puppet::Pops::Types::TypeFactory.enum(*strings)
28
+ end
29
+
30
+ def variant_t(*types)
31
+ Puppet::Pops::Types::TypeFactory.variant(*types)
32
+ end
33
+
34
+ def integer_t()
35
+ Puppet::Pops::Types::TypeFactory.integer()
36
+ end
37
+
38
+ def array_t(t)
39
+ Puppet::Pops::Types::TypeFactory.array_of(t)
40
+ end
41
+
42
+ def hash_t(k,v)
43
+ Puppet::Pops::Types::TypeFactory.hash_of(v, k)
44
+ end
45
+
46
+ def data_t()
47
+ Puppet::Pops::Types::TypeFactory.data()
48
+ end
49
+
50
+ def factory()
51
+ Puppet::Pops::Types::TypeFactory
52
+ end
53
+
54
+ def collection_t()
55
+ Puppet::Pops::Types::TypeFactory.collection()
56
+ end
57
+
58
+ def tuple_t(*types)
59
+ Puppet::Pops::Types::TypeFactory.tuple(*types)
60
+ end
61
+
62
+ def struct_t(type_hash)
63
+ Puppet::Pops::Types::TypeFactory.struct(type_hash)
64
+ end
65
+
66
+ def types
67
+ Puppet::Pops::Types
68
+ end
69
+
70
+ shared_context "types_setup" do
71
+
72
+ def all_types
73
+ [ Puppet::Pops::Types::PObjectType,
74
+ Puppet::Pops::Types::PNilType,
75
+ Puppet::Pops::Types::PDataType,
76
+ Puppet::Pops::Types::PScalarType,
77
+ Puppet::Pops::Types::PStringType,
78
+ Puppet::Pops::Types::PNumericType,
79
+ Puppet::Pops::Types::PIntegerType,
80
+ Puppet::Pops::Types::PFloatType,
81
+ Puppet::Pops::Types::PRegexpType,
82
+ Puppet::Pops::Types::PBooleanType,
83
+ Puppet::Pops::Types::PCollectionType,
84
+ Puppet::Pops::Types::PArrayType,
85
+ Puppet::Pops::Types::PHashType,
86
+ Puppet::Pops::Types::PRubyType,
87
+ Puppet::Pops::Types::PHostClassType,
88
+ Puppet::Pops::Types::PResourceType,
89
+ Puppet::Pops::Types::PPatternType,
90
+ Puppet::Pops::Types::PEnumType,
91
+ Puppet::Pops::Types::PVariantType,
92
+ Puppet::Pops::Types::PStructType,
93
+ Puppet::Pops::Types::PTupleType,
94
+ ]
95
+ end
96
+
97
+ def scalar_types
98
+ # PVariantType is also scalar, if its types are all Scalar
99
+ [
100
+ Puppet::Pops::Types::PScalarType,
101
+ Puppet::Pops::Types::PStringType,
102
+ Puppet::Pops::Types::PNumericType,
103
+ Puppet::Pops::Types::PIntegerType,
104
+ Puppet::Pops::Types::PFloatType,
105
+ Puppet::Pops::Types::PRegexpType,
106
+ Puppet::Pops::Types::PBooleanType,
107
+ Puppet::Pops::Types::PPatternType,
108
+ Puppet::Pops::Types::PEnumType,
109
+ ]
110
+ end
111
+
112
+ def numeric_types
113
+ # PVariantType is also numeric, if its types are all numeric
114
+ [
115
+ Puppet::Pops::Types::PNumericType,
116
+ Puppet::Pops::Types::PIntegerType,
117
+ Puppet::Pops::Types::PFloatType,
118
+ ]
119
+ end
120
+
121
+ def string_types
122
+ # PVariantType is also string type, if its types are all compatible
123
+ [
124
+ Puppet::Pops::Types::PStringType,
125
+ Puppet::Pops::Types::PPatternType,
126
+ Puppet::Pops::Types::PEnumType,
127
+ ]
128
+ end
129
+
130
+ def collection_types
131
+ # PVariantType is also string type, if its types are all compatible
132
+ [
133
+ Puppet::Pops::Types::PCollectionType,
134
+ Puppet::Pops::Types::PHashType,
135
+ Puppet::Pops::Types::PArrayType,
136
+ Puppet::Pops::Types::PStructType,
137
+ Puppet::Pops::Types::PTupleType,
138
+ ]
139
+ end
140
+
141
+ def data_compatible_types
142
+ result = scalar_types
143
+ result << Puppet::Pops::Types::PDataType
144
+ result << array_t(types::PDataType.new)
145
+ result << types::TypeFactory.hash_of_data
146
+ result << Puppet::Pops::Types::PNilType
147
+ tmp = tuple_t(types::PDataType.new)
148
+ result << (tmp)
149
+ tmp.size_type = range_t(0, nil)
150
+ result
151
+ end
152
+
153
+ def type_from_class(c)
154
+ c.is_a?(Class) ? c.new : c
155
+ end
156
+ end
157
+
7
158
  context 'when inferring ruby' do
8
159
 
9
160
  it 'fixnum translates to PIntegerType' do
@@ -22,6 +173,12 @@ describe 'The type calculator' do
22
173
  calculator.infer('foo').class.should == Puppet::Pops::Types::PStringType
23
174
  end
24
175
 
176
+ it 'inferred string type knows the string value' do
177
+ t = calculator.infer('foo')
178
+ t.class.should == Puppet::Pops::Types::PStringType
179
+ t.values.should == ['foo']
180
+ end
181
+
25
182
  it 'boolean true translates to PBooleanType' do
26
183
  calculator.infer(true).class.should == Puppet::Pops::Types::PBooleanType
27
184
  end
@@ -30,14 +187,18 @@ describe 'The type calculator' do
30
187
  calculator.infer(false).class.should == Puppet::Pops::Types::PBooleanType
31
188
  end
32
189
 
33
- it 'regexp translates to PPatternType' do
34
- calculator.infer(/^a regular exception$/).class.should == Puppet::Pops::Types::PPatternType
190
+ it 'regexp translates to PRegexpType' do
191
+ calculator.infer(/^a regular expression$/).class.should == Puppet::Pops::Types::PRegexpType
35
192
  end
36
193
 
37
194
  it 'nil translates to PNilType' do
38
195
  calculator.infer(nil).class.should == Puppet::Pops::Types::PNilType
39
196
  end
40
197
 
198
+ it ':undef translates to PNilType' do
199
+ calculator.infer(:undef).class.should == Puppet::Pops::Types::PNilType
200
+ end
201
+
41
202
  it 'an instance of class Foo translates to PRubyType[Foo]' do
42
203
  class Foo
43
204
  end
@@ -60,28 +221,41 @@ describe 'The type calculator' do
60
221
  calculator.infer([1,2**33]).element_type.class.should == Puppet::Pops::Types::PIntegerType
61
222
  end
62
223
 
224
+ it 'Range of integer values are computed' do
225
+ t = calculator.infer([-3,0,42]).element_type
226
+ t.class.should == Puppet::Pops::Types::PIntegerType
227
+ t.from.should == -3
228
+ t.to.should == 42
229
+ end
230
+
231
+ it "Compound string values are computed" do
232
+ t = calculator.infer(['a','b', 'c']).element_type
233
+ t.class.should == Puppet::Pops::Types::PStringType
234
+ t.values.should == ['a', 'b', 'c']
235
+ end
236
+
63
237
  it 'with fixnum and float values translates to PArrayType[PNumericType]' do
64
238
  calculator.infer([1,2.0]).element_type.class.should == Puppet::Pops::Types::PNumericType
65
239
  end
66
240
 
67
- it 'with fixnum and string values translates to PArrayType[PLiteralType]' do
68
- calculator.infer([1,'two']).element_type.class.should == Puppet::Pops::Types::PLiteralType
241
+ it 'with fixnum and string values translates to PArrayType[PScalarType]' do
242
+ calculator.infer([1,'two']).element_type.class.should == Puppet::Pops::Types::PScalarType
69
243
  end
70
244
 
71
- it 'with float and string values translates to PArrayType[PLiteralType]' do
72
- calculator.infer([1.0,'two']).element_type.class.should == Puppet::Pops::Types::PLiteralType
245
+ it 'with float and string values translates to PArrayType[PScalarType]' do
246
+ calculator.infer([1.0,'two']).element_type.class.should == Puppet::Pops::Types::PScalarType
73
247
  end
74
248
 
75
- it 'with fixnum, float, and string values translates to PArrayType[PLiteralType]' do
76
- calculator.infer([1, 2.0,'two']).element_type.class.should == Puppet::Pops::Types::PLiteralType
249
+ it 'with fixnum, float, and string values translates to PArrayType[PScalarType]' do
250
+ calculator.infer([1, 2.0,'two']).element_type.class.should == Puppet::Pops::Types::PScalarType
77
251
  end
78
252
 
79
- it 'with fixnum and regexp values translates to PArrayType[PLiteralType]' do
80
- calculator.infer([1, /two/]).element_type.class.should == Puppet::Pops::Types::PLiteralType
253
+ it 'with fixnum and regexp values translates to PArrayType[PScalarType]' do
254
+ calculator.infer([1, /two/]).element_type.class.should == Puppet::Pops::Types::PScalarType
81
255
  end
82
256
 
83
- it 'with string and regexp values translates to PArrayType[PLiteralType]' do
84
- calculator.infer(['one', /two/]).element_type.class.should == Puppet::Pops::Types::PLiteralType
257
+ it 'with string and regexp values translates to PArrayType[PScalarType]' do
258
+ calculator.infer(['one', /two/]).element_type.class.should == Puppet::Pops::Types::PScalarType
85
259
  end
86
260
 
87
261
  it 'with string and symbol values translates to PArrayType[PObjectType]' do
@@ -101,13 +275,13 @@ describe 'The type calculator' do
101
275
  et.class.should == Puppet::Pops::Types::PStringType
102
276
  end
103
277
 
104
- it 'with array of string values and array of fixnums translates to PArrayType[PArrayType[PLiteralType]]' do
278
+ it 'with array of string values and array of fixnums translates to PArrayType[PArrayType[PScalarType]]' do
105
279
  et = calculator.infer([['first' 'array'], [1,2]])
106
280
  et.class.should == Puppet::Pops::Types::PArrayType
107
281
  et = et.element_type
108
282
  et.class.should == Puppet::Pops::Types::PArrayType
109
283
  et = et.element_type
110
- et.class.should == Puppet::Pops::Types::PLiteralType
284
+ et.class.should == Puppet::Pops::Types::PScalarType
111
285
  end
112
286
 
113
287
  it 'with hashes of string values translates to PArrayType[PHashType[PStringType]]' do
@@ -119,13 +293,13 @@ describe 'The type calculator' do
119
293
  et.class.should == Puppet::Pops::Types::PStringType
120
294
  end
121
295
 
122
- it 'with hash of string values and hash of fixnums translates to PArrayType[PHashType[PLiteralType]]' do
296
+ it 'with hash of string values and hash of fixnums translates to PArrayType[PHashType[PScalarType]]' do
123
297
  et = calculator.infer([{:first => 'first', :second => 'second' }, {:first => 1, :second => 2 }])
124
298
  et.class.should == Puppet::Pops::Types::PArrayType
125
299
  et = et.element_type
126
300
  et.class.should == Puppet::Pops::Types::PHashType
127
301
  et = et.element_type
128
- et.class.should == Puppet::Pops::Types::PLiteralType
302
+ et.class.should == Puppet::Pops::Types::PScalarType
129
303
  end
130
304
  end
131
305
 
@@ -148,178 +322,490 @@ describe 'The type calculator' do
148
322
  calculator.infer({:first => 1, :second => 2}).element_type.class.should == Puppet::Pops::Types::PIntegerType
149
323
  end
150
324
  end
325
+
151
326
  end
152
327
 
153
- context 'when testing if x is assignable to y' do
154
- it 'should allow all object types to PObjectType' do
155
- t = Puppet::Pops::Types::PObjectType.new()
156
- calculator.assignable?(t, t).should() == true
157
- calculator.assignable?(t,Puppet::Pops::Types::PNilType.new()).should() == true
158
- calculator.assignable?(t,Puppet::Pops::Types::PDataType.new()).should() == true
159
- calculator.assignable?(t,Puppet::Pops::Types::PLiteralType.new()).should() == true
160
- calculator.assignable?(t,Puppet::Pops::Types::PStringType.new()).should() == true
161
- calculator.assignable?(t,Puppet::Pops::Types::PNumericType.new()).should() == true
162
- calculator.assignable?(t,Puppet::Pops::Types::PIntegerType.new()).should() == true
163
- calculator.assignable?(t,Puppet::Pops::Types::PFloatType.new()).should() == true
164
- calculator.assignable?(t,Puppet::Pops::Types::PPatternType.new()).should() == true
165
- calculator.assignable?(t,Puppet::Pops::Types::PBooleanType.new()).should() == true
166
- calculator.assignable?(t,Puppet::Pops::Types::PCollectionType.new()).should() == true
167
- calculator.assignable?(t,Puppet::Pops::Types::PArrayType.new()).should() == true
168
- calculator.assignable?(t,Puppet::Pops::Types::PHashType.new()).should() == true
169
- calculator.assignable?(t,Puppet::Pops::Types::PRubyType.new()).should() == true
170
- end
171
-
172
- it 'should reject PObjectType to less generic types' do
173
- t = Puppet::Pops::Types::PObjectType.new()
174
- calculator.assignable?(Puppet::Pops::Types::PDataType.new(), t).should() == false
175
- calculator.assignable?(Puppet::Pops::Types::PLiteralType.new(), t).should() == false
176
- calculator.assignable?(Puppet::Pops::Types::PStringType.new(), t).should() == false
177
- calculator.assignable?(Puppet::Pops::Types::PNumericType.new(), t).should() == false
178
- calculator.assignable?(Puppet::Pops::Types::PIntegerType.new(), t).should() == false
179
- calculator.assignable?(Puppet::Pops::Types::PFloatType.new(), t).should() == false
180
- calculator.assignable?(Puppet::Pops::Types::PPatternType.new(), t).should() == false
181
- calculator.assignable?(Puppet::Pops::Types::PBooleanType.new(), t).should() == false
182
- calculator.assignable?(Puppet::Pops::Types::PCollectionType.new(), t).should() == false
183
- calculator.assignable?(Puppet::Pops::Types::PArrayType.new(), t).should() == false
184
- calculator.assignable?(Puppet::Pops::Types::PHashType.new(), t).should() == false
185
- calculator.assignable?(Puppet::Pops::Types::PRubyType.new(), t).should() == false
186
- end
187
-
188
- it 'should allow all data types, array, and hash to PDataType' do
189
- t = Puppet::Pops::Types::PDataType.new()
190
- calculator.assignable?(t, t).should() == true
191
- calculator.assignable?(t,Puppet::Pops::Types::PLiteralType.new()).should() == true
192
- calculator.assignable?(t,Puppet::Pops::Types::PStringType.new()).should() == true
193
- calculator.assignable?(t,Puppet::Pops::Types::PNumericType.new()).should() == true
194
- calculator.assignable?(t,Puppet::Pops::Types::PIntegerType.new()).should() == true
195
- calculator.assignable?(t,Puppet::Pops::Types::PFloatType.new()).should() == true
196
- calculator.assignable?(t,Puppet::Pops::Types::PPatternType.new()).should() == true
197
- calculator.assignable?(t,Puppet::Pops::Types::PBooleanType.new()).should() == true
198
- calculator.assignable?(t,Puppet::Pops::Types::PArrayType.new()).should() == true
199
- calculator.assignable?(t,Puppet::Pops::Types::PHashType.new()).should() == true
200
- end
201
-
202
- it 'should reject PDataType to less generic data types' do
203
- t = Puppet::Pops::Types::PDataType.new()
204
- calculator.assignable?(Puppet::Pops::Types::PLiteralType.new(), t).should() == false
205
- calculator.assignable?(Puppet::Pops::Types::PStringType.new(), t).should() == false
206
- calculator.assignable?(Puppet::Pops::Types::PNumericType.new(), t).should() == false
207
- calculator.assignable?(Puppet::Pops::Types::PIntegerType.new(), t).should() == false
208
- calculator.assignable?(Puppet::Pops::Types::PFloatType.new(), t).should() == false
209
- calculator.assignable?(Puppet::Pops::Types::PPatternType.new(), t).should() == false
210
- calculator.assignable?(Puppet::Pops::Types::PBooleanType.new(), t).should() == false
211
- end
212
-
213
- it 'should reject PDataType to non data types' do
214
- t = Puppet::Pops::Types::PDataType.new()
215
- calculator.assignable?(Puppet::Pops::Types::PCollectionType.new(),t).should() == false
216
- calculator.assignable?(Puppet::Pops::Types::PArrayType.new(),t).should() == false
217
- calculator.assignable?(Puppet::Pops::Types::PHashType.new(),t).should() == false
218
- calculator.assignable?(Puppet::Pops::Types::PRubyType.new(), t).should() == false
219
- end
220
-
221
- it 'should allow all literal types to PLiteralType' do
222
- t = Puppet::Pops::Types::PLiteralType.new()
223
- calculator.assignable?(t, t).should() == true
224
- calculator.assignable?(t,Puppet::Pops::Types::PStringType.new()).should() == true
225
- calculator.assignable?(t,Puppet::Pops::Types::PNumericType.new()).should() == true
226
- calculator.assignable?(t,Puppet::Pops::Types::PIntegerType.new()).should() == true
227
- calculator.assignable?(t,Puppet::Pops::Types::PFloatType.new()).should() == true
228
- calculator.assignable?(t,Puppet::Pops::Types::PPatternType.new()).should() == true
229
- calculator.assignable?(t,Puppet::Pops::Types::PBooleanType.new()).should() == true
230
- end
231
-
232
- it 'should reject PLiteralType to less generic literal types' do
233
- t = Puppet::Pops::Types::PLiteralType.new()
234
- calculator.assignable?(Puppet::Pops::Types::PStringType.new(), t).should() == false
235
- calculator.assignable?(Puppet::Pops::Types::PNumericType.new(), t).should() == false
236
- calculator.assignable?(Puppet::Pops::Types::PIntegerType.new(), t).should() == false
237
- calculator.assignable?(Puppet::Pops::Types::PFloatType.new(), t).should() == false
238
- calculator.assignable?(Puppet::Pops::Types::PPatternType.new(), t).should() == false
239
- calculator.assignable?(Puppet::Pops::Types::PBooleanType.new(), t).should() == false
240
- end
241
-
242
- it 'should reject PLiteralType to non literal types' do
243
- t = Puppet::Pops::Types::PLiteralType.new()
244
- calculator.assignable?(Puppet::Pops::Types::PCollectionType.new(), t).should() == false
245
- calculator.assignable?(Puppet::Pops::Types::PArrayType.new(), t).should() == false
246
- calculator.assignable?(Puppet::Pops::Types::PHashType.new(), t).should() == false
247
- calculator.assignable?(Puppet::Pops::Types::PRubyType.new(), t).should() == false
248
- end
249
-
250
- it 'should allow all numeric types to PNumericType' do
251
- t = Puppet::Pops::Types::PNumericType.new()
252
- calculator.assignable?(t, t).should() == true
253
- calculator.assignable?(t, Puppet::Pops::Types::PIntegerType.new()).should() == true
254
- calculator.assignable?(t, Puppet::Pops::Types::PFloatType.new()).should() == true
255
- end
256
-
257
- it 'should reject PNumericType to less generic numeric types' do
258
- t = Puppet::Pops::Types::PNumericType.new()
259
- calculator.assignable?(Puppet::Pops::Types::PIntegerType.new(), t).should() == false
260
- calculator.assignable?(Puppet::Pops::Types::PFloatType.new(), t).should() == false
261
- end
262
-
263
- it 'should reject PNumericType to non numeric types' do
264
- t = Puppet::Pops::Types::PNumericType.new()
265
- calculator.assignable?(Puppet::Pops::Types::PStringType.new(), t).should() == false
266
- calculator.assignable?(Puppet::Pops::Types::PPatternType.new(), t).should() == false
267
- calculator.assignable?(Puppet::Pops::Types::PBooleanType.new(), t).should() == false
268
- calculator.assignable?(Puppet::Pops::Types::PCollectionType.new(), t).should() == false
269
- calculator.assignable?(Puppet::Pops::Types::PArrayType.new(), t).should() == false
270
- calculator.assignable?(Puppet::Pops::Types::PHashType.new(), t).should() == false
271
- calculator.assignable?(Puppet::Pops::Types::PRubyType.new(), t).should() == false
272
- end
273
-
274
- it 'should allow all collection types to PCollectionType' do
275
- t = Puppet::Pops::Types::PCollectionType.new()
276
- calculator.assignable?(t, t).should() == true
277
- calculator.assignable?(t, Puppet::Pops::Types::PArrayType.new()).should() == true
278
- calculator.assignable?(t, Puppet::Pops::Types::PHashType.new()).should() == true
279
- end
280
-
281
- it 'should reject PCollectionType to less generic collection types' do
282
- t = Puppet::Pops::Types::PCollectionType.new()
283
- calculator.assignable?(Puppet::Pops::Types::PArrayType.new(), t).should() == false
284
- calculator.assignable?(Puppet::Pops::Types::PHashType.new(), t).should() == false
285
- end
286
-
287
- it 'should reject PCollectionType to non collection types' do
288
- t = Puppet::Pops::Types::PCollectionType.new()
289
- calculator.assignable?(Puppet::Pops::Types::PDataType.new(), t).should() == false
290
- calculator.assignable?(Puppet::Pops::Types::PLiteralType.new(), t).should() == false
291
- calculator.assignable?(Puppet::Pops::Types::PStringType.new(), t).should() == false
292
- calculator.assignable?(Puppet::Pops::Types::PNumericType.new(), t).should() == false
293
- calculator.assignable?(Puppet::Pops::Types::PIntegerType.new(), t).should() == false
294
- calculator.assignable?(Puppet::Pops::Types::PFloatType.new(), t).should() == false
295
- calculator.assignable?(Puppet::Pops::Types::PPatternType.new(), t).should() == false
296
- calculator.assignable?(Puppet::Pops::Types::PBooleanType.new(), t).should() == false
297
- calculator.assignable?(Puppet::Pops::Types::PRubyType.new(), t).should() == false
298
- end
299
-
300
- it 'should reject PArrayType to non array type collections' do
301
- t = Puppet::Pops::Types::PArrayType.new()
302
- calculator.assignable?(Puppet::Pops::Types::PHashType.new(), t).should() == false
328
+ context 'patterns' do
329
+ it "constructs a PPatternType" do
330
+ t = pattern_t('a(b)c')
331
+ t.class.should == Puppet::Pops::Types::PPatternType
332
+ t.patterns.size.should == 1
333
+ t.patterns[0].class.should == Puppet::Pops::Types::PRegexpType
334
+ t.patterns[0].pattern.should == 'a(b)c'
335
+ t.patterns[0].regexp.match('abc')[1].should == 'b'
303
336
  end
304
337
 
305
- it 'should reject PHashType to non hash type collections' do
306
- t = Puppet::Pops::Types::PHashType.new()
307
- calculator.assignable?(Puppet::Pops::Types::PArrayType.new(), t).should() == false
338
+ it "constructs a PStringType with multiple strings" do
339
+ t = string_t('a', 'b', 'c', 'abc')
340
+ t.values.should == ['a', 'b', 'c', 'abc']
341
+ end
342
+ end
343
+
344
+ # Deal with cases not covered by computing common type
345
+ context 'when computing common type' do
346
+ it 'computes given resource type commonality' do
347
+ r1 = Puppet::Pops::Types::PResourceType.new()
348
+ r1.type_name = 'File'
349
+ r2 = Puppet::Pops::Types::PResourceType.new()
350
+ r2.type_name = 'File'
351
+ calculator.string(calculator.common_type(r1, r2)).should == "File"
352
+
353
+ r2 = Puppet::Pops::Types::PResourceType.new()
354
+ r2.type_name = 'File'
355
+ r2.title = '/tmp/foo'
356
+ calculator.string(calculator.common_type(r1, r2)).should == "File"
357
+
358
+ r1 = Puppet::Pops::Types::PResourceType.new()
359
+ r1.type_name = 'File'
360
+ r1.title = '/tmp/foo'
361
+ calculator.string(calculator.common_type(r1, r2)).should == "File['/tmp/foo']"
362
+
363
+ r1 = Puppet::Pops::Types::PResourceType.new()
364
+ r1.type_name = 'File'
365
+ r1.title = '/tmp/bar'
366
+ calculator.string(calculator.common_type(r1, r2)).should == "File"
367
+
368
+ r2 = Puppet::Pops::Types::PResourceType.new()
369
+ r2.type_name = 'Package'
370
+ r2.title = 'apache'
371
+ calculator.string(calculator.common_type(r1, r2)).should == "Resource"
372
+ end
373
+
374
+ it 'computes given hostclass type commonality' do
375
+ r1 = Puppet::Pops::Types::PHostClassType.new()
376
+ r1.class_name = 'foo'
377
+ r2 = Puppet::Pops::Types::PHostClassType.new()
378
+ r2.class_name = 'foo'
379
+ calculator.string(calculator.common_type(r1, r2)).should == "Class[foo]"
380
+
381
+ r2 = Puppet::Pops::Types::PHostClassType.new()
382
+ r2.class_name = 'bar'
383
+ calculator.string(calculator.common_type(r1, r2)).should == "Class"
384
+
385
+ r2 = Puppet::Pops::Types::PHostClassType.new()
386
+ calculator.string(calculator.common_type(r1, r2)).should == "Class"
387
+
388
+ r1 = Puppet::Pops::Types::PHostClassType.new()
389
+ calculator.string(calculator.common_type(r1, r2)).should == "Class"
390
+ end
391
+
392
+ it 'computes pattern commonality' do
393
+ t1 = pattern_t('abc')
394
+ t2 = pattern_t('xyz')
395
+ common_t = calculator.common_type(t1,t2)
396
+ common_t.class.should == Puppet::Pops::Types::PPatternType
397
+ common_t.patterns.map { |pr| pr.pattern }.should == ['abc', 'xyz']
398
+ calculator.string(common_t).should == "Pattern[/abc/, /xyz/]"
399
+ end
400
+
401
+ it 'computes enum commonality to value set sum' do
402
+ t1 = enum_t('a', 'b', 'c')
403
+ t2 = enum_t('x', 'y', 'z')
404
+ common_t = calculator.common_type(t1, t2)
405
+ common_t.should == enum_t('a', 'b', 'c', 'x', 'y', 'z')
406
+ end
407
+
408
+ it 'computed variant commonality to type union where added types are not sub-types' do
409
+ a_t1 = integer_t()
410
+ a_t2 = enum_t('b')
411
+ v_a = variant_t(a_t1, a_t2)
412
+ b_t1 = enum_t('a')
413
+ v_b = variant_t(b_t1)
414
+ common_t = calculator.common_type(v_a, v_b)
415
+ common_t.class.should == Puppet::Pops::Types::PVariantType
416
+ Set.new(common_t.types).should == Set.new([a_t1, a_t2, b_t1])
417
+ end
418
+
419
+ it 'computed variant commonality to type union where added types are sub-types' do
420
+ a_t1 = integer_t()
421
+ a_t2 = string_t()
422
+ v_a = variant_t(a_t1, a_t2)
423
+ b_t1 = enum_t('a')
424
+ v_b = variant_t(b_t1)
425
+ common_t = calculator.common_type(v_a, v_b)
426
+ common_t.class.should == Puppet::Pops::Types::PVariantType
427
+ Set.new(common_t.types).should == Set.new([a_t1, a_t2])
428
+ end
429
+ end
430
+
431
+ context 'computes assignability' do
432
+ include_context "types_setup"
433
+
434
+ context "for Object, such that" do
435
+ it 'all types are assignable to Object' do
436
+ t = Puppet::Pops::Types::PObjectType.new()
437
+ all_types.each { |t2| t2.new.should be_assignable_to(t) }
438
+ end
439
+
440
+ it 'Object is not assignable to anything but Object' do
441
+ tested_types = all_types() - [Puppet::Pops::Types::PObjectType]
442
+ t = Puppet::Pops::Types::PObjectType.new()
443
+ tested_types.each { |t2| t.should_not be_assignable_to(t2.new) }
444
+ end
445
+ end
446
+
447
+ context "for Data, such that" do
448
+ it 'all scalars + array and hash are assignable to Data' do
449
+ t = Puppet::Pops::Types::PDataType.new()
450
+ data_compatible_types.each { |t2|
451
+ type_from_class(t2).should be_assignable_to(t)
452
+ }
453
+ end
454
+
455
+ it 'a Variant of scalar, hash, or array is assignable to Data' do
456
+ t = Puppet::Pops::Types::PDataType.new()
457
+ data_compatible_types.each { |t2| variant_t(type_from_class(t2)).should be_assignable_to(t) }
458
+ end
459
+
460
+ it 'Data is not assignable to any of its subtypes' do
461
+ t = Puppet::Pops::Types::PDataType.new()
462
+ types_to_test = data_compatible_types- [Puppet::Pops::Types::PDataType]
463
+ types_to_test.each {|t2| t.should_not be_assignable_to(type_from_class(t2)) }
464
+ end
465
+
466
+ it 'Data is not assignable to a Variant of Data subtype' do
467
+ t = Puppet::Pops::Types::PDataType.new()
468
+ types_to_test = data_compatible_types- [Puppet::Pops::Types::PDataType]
469
+ types_to_test.each { |t2| t.should_not be_assignable_to(variant_t(type_from_class(t2))) }
470
+ end
471
+
472
+ it 'Data is not assignable to any disjunct type' do
473
+ tested_types = all_types - [Puppet::Pops::Types::PObjectType, Puppet::Pops::Types::PDataType] - scalar_types
474
+ t = Puppet::Pops::Types::PDataType.new()
475
+ tested_types.each {|t2| t.should_not be_assignable_to(t2.new) }
476
+ end
477
+ end
478
+
479
+ context "for Scalar, such that" do
480
+ it "all scalars are assignable to Scalar" do
481
+ t = Puppet::Pops::Types::PScalarType.new()
482
+ scalar_types.each {|t2| t2.new.should be_assignable_to(t) }
483
+ end
484
+
485
+ it 'Scalar is not assignable to any of its subtypes' do
486
+ t = Puppet::Pops::Types::PScalarType.new()
487
+ types_to_test = scalar_types - [Puppet::Pops::Types::PScalarType]
488
+ types_to_test.each {|t2| t.should_not be_assignable_to(t2.new) }
489
+ end
490
+
491
+ it 'Scalar is not assignable to any disjunct type' do
492
+ tested_types = all_types - [Puppet::Pops::Types::PObjectType, Puppet::Pops::Types::PDataType] - scalar_types
493
+ t = Puppet::Pops::Types::PScalarType.new()
494
+ tested_types.each {|t2| t.should_not be_assignable_to(t2.new) }
495
+ end
496
+ end
497
+
498
+ context "for Numeric, such that" do
499
+ it "all numerics are assignable to Numeric" do
500
+ t = Puppet::Pops::Types::PNumericType.new()
501
+ numeric_types.each {|t2| t2.new.should be_assignable_to(t) }
502
+ end
503
+
504
+ it 'Numeric is not assignable to any of its subtypes' do
505
+ t = Puppet::Pops::Types::PNumericType.new()
506
+ types_to_test = numeric_types - [Puppet::Pops::Types::PNumericType]
507
+ types_to_test.each {|t2| t.should_not be_assignable_to(t2.new) }
508
+ end
509
+
510
+ it 'Numeric is not assignable to any disjunct type' do
511
+ tested_types = all_types - [
512
+ Puppet::Pops::Types::PObjectType,
513
+ Puppet::Pops::Types::PDataType,
514
+ Puppet::Pops::Types::PScalarType,
515
+ ] - numeric_types
516
+ t = Puppet::Pops::Types::PNumericType.new()
517
+ tested_types.each {|t2| t.should_not be_assignable_to(t2.new) }
518
+ end
519
+ end
520
+
521
+ context "for Collection, such that" do
522
+ it "all collections are assignable to Collection" do
523
+ t = Puppet::Pops::Types::PCollectionType.new()
524
+ collection_types.each {|t2| t2.new.should be_assignable_to(t) }
525
+ end
526
+
527
+ it 'Collection is not assignable to any of its subtypes' do
528
+ t = Puppet::Pops::Types::PCollectionType.new()
529
+ types_to_test = collection_types - [Puppet::Pops::Types::PCollectionType]
530
+ types_to_test.each {|t2| t.should_not be_assignable_to(t2.new) }
531
+ end
532
+
533
+ it 'Collection is not assignable to any disjunct type' do
534
+ tested_types = all_types - [Puppet::Pops::Types::PObjectType] - collection_types
535
+ t = Puppet::Pops::Types::PCollectionType.new()
536
+ tested_types.each {|t2| t.should_not be_assignable_to(t2.new) }
537
+ end
538
+ end
539
+
540
+ context "for Array, such that" do
541
+ it "Array is not assignable to non Array based Collection type" do
542
+ t = Puppet::Pops::Types::PArrayType.new()
543
+ tested_types = collection_types - [
544
+ Puppet::Pops::Types::PCollectionType,
545
+ Puppet::Pops::Types::PArrayType,
546
+ Puppet::Pops::Types::PTupleType]
547
+ tested_types.each {|t2| t.should_not be_assignable_to(t2.new) }
548
+ end
549
+
550
+ it 'Array is not assignable to any disjunct type' do
551
+ tested_types = all_types - [
552
+ Puppet::Pops::Types::PObjectType,
553
+ Puppet::Pops::Types::PDataType] - collection_types
554
+ t = Puppet::Pops::Types::PArrayType.new()
555
+ tested_types.each {|t2| t.should_not be_assignable_to(t2.new) }
556
+ end
557
+ end
558
+
559
+ context "for Hash, such that" do
560
+ it "Hash is not assignable to any other Collection type" do
561
+ t = Puppet::Pops::Types::PHashType.new()
562
+ tested_types = collection_types - [
563
+ Puppet::Pops::Types::PCollectionType,
564
+ Puppet::Pops::Types::PStructType,
565
+ Puppet::Pops::Types::PHashType]
566
+ tested_types.each {|t2| t.should_not be_assignable_to(t2.new) }
567
+ end
568
+
569
+ it 'Hash is not assignable to any disjunct type' do
570
+ tested_types = all_types - [
571
+ Puppet::Pops::Types::PObjectType,
572
+ Puppet::Pops::Types::PDataType] - collection_types
573
+ t = Puppet::Pops::Types::PHashType.new()
574
+ tested_types.each {|t2| t.should_not be_assignable_to(t2.new) }
575
+ end
576
+ end
577
+
578
+ context "for Tuple, such that" do
579
+ it "Tuple is not assignable to any other non Array based Collection type" do
580
+ t = Puppet::Pops::Types::PTupleType.new()
581
+ tested_types = collection_types - [
582
+ Puppet::Pops::Types::PCollectionType,
583
+ Puppet::Pops::Types::PTupleType,
584
+ Puppet::Pops::Types::PArrayType]
585
+ tested_types.each {|t2| t.should_not be_assignable_to(t2.new) }
586
+ end
587
+
588
+ it 'Tuple is not assignable to any disjunct type' do
589
+ tested_types = all_types - [
590
+ Puppet::Pops::Types::PObjectType,
591
+ Puppet::Pops::Types::PDataType] - collection_types
592
+ t = Puppet::Pops::Types::PTupleType.new()
593
+ tested_types.each {|t2| t.should_not be_assignable_to(t2.new) }
594
+ end
595
+ end
596
+
597
+ context "for Struct, such that" do
598
+ it "Struct is not assignable to any other non Hashed based Collection type" do
599
+ t = Puppet::Pops::Types::PStructType.new()
600
+ tested_types = collection_types - [
601
+ Puppet::Pops::Types::PCollectionType,
602
+ Puppet::Pops::Types::PStructType,
603
+ Puppet::Pops::Types::PHashType]
604
+ tested_types.each {|t2| t.should_not be_assignable_to(t2.new) }
605
+ end
606
+
607
+ it 'Struct is not assignable to any disjunct type' do
608
+ tested_types = all_types - [
609
+ Puppet::Pops::Types::PObjectType,
610
+ Puppet::Pops::Types::PDataType] - collection_types
611
+ t = Puppet::Pops::Types::PStructType.new()
612
+ tested_types.each {|t2| t.should_not be_assignable_to(t2.new) }
613
+ end
614
+ end
615
+
616
+ it 'should recognize mapped ruby types' do
617
+ { Integer => Puppet::Pops::Types::PIntegerType.new,
618
+ Fixnum => Puppet::Pops::Types::PIntegerType.new,
619
+ Bignum => Puppet::Pops::Types::PIntegerType.new,
620
+ Float => Puppet::Pops::Types::PFloatType.new,
621
+ Numeric => Puppet::Pops::Types::PNumericType.new,
622
+ NilClass => Puppet::Pops::Types::PNilType.new,
623
+ TrueClass => Puppet::Pops::Types::PBooleanType.new,
624
+ FalseClass => Puppet::Pops::Types::PBooleanType.new,
625
+ String => Puppet::Pops::Types::PStringType.new,
626
+ Regexp => Puppet::Pops::Types::PRegexpType.new,
627
+ Regexp => Puppet::Pops::Types::PRegexpType.new,
628
+ Array => Puppet::Pops::Types::TypeFactory.array_of_data(),
629
+ Hash => Puppet::Pops::Types::TypeFactory.hash_of_data()
630
+ }.each do |ruby_type, puppet_type |
631
+ ruby_type.should be_assignable_to(puppet_type)
632
+ end
633
+ end
634
+
635
+ context 'when dealing with integer ranges' do
636
+ it 'should accept an equal range' do
637
+ calculator.assignable?(range_t(2,5), range_t(2,5)).should == true
638
+ end
639
+
640
+ it 'should accept an equal reverse range' do
641
+ calculator.assignable?(range_t(2,5), range_t(5,2)).should == true
642
+ end
643
+
644
+ it 'should accept a narrower range' do
645
+ calculator.assignable?(range_t(2,10), range_t(3,5)).should == true
646
+ end
647
+
648
+ it 'should accept a narrower reverse range' do
649
+ calculator.assignable?(range_t(2,10), range_t(5,3)).should == true
650
+ end
651
+
652
+ it 'should reject a wider range' do
653
+ calculator.assignable?(range_t(3,5), range_t(2,10)).should == false
654
+ end
655
+
656
+ it 'should reject a wider reverse range' do
657
+ calculator.assignable?(range_t(3,5), range_t(10,2)).should == false
658
+ end
659
+
660
+ it 'should reject a partially overlapping range' do
661
+ calculator.assignable?(range_t(3,5), range_t(2,4)).should == false
662
+ calculator.assignable?(range_t(3,5), range_t(4,6)).should == false
663
+ end
664
+
665
+ it 'should reject a partially overlapping reverse range' do
666
+ calculator.assignable?(range_t(3,5), range_t(4,2)).should == false
667
+ calculator.assignable?(range_t(3,5), range_t(6,4)).should == false
668
+ end
669
+ end
670
+
671
+ context 'when dealing with patterns' do
672
+ it 'should accept a string matching a pattern' do
673
+ p_t = pattern_t('abc')
674
+ p_s = string_t('XabcY')
675
+ calculator.assignable?(p_t, p_s).should == true
676
+ end
677
+
678
+ it 'should accept a regexp matching a pattern' do
679
+ p_t = pattern_t(/abc/)
680
+ p_s = string_t('XabcY')
681
+ calculator.assignable?(p_t, p_s).should == true
682
+ end
683
+
684
+ it 'should accept a pattern matching a pattern' do
685
+ p_t = pattern_t(pattern_t('abc'))
686
+ p_s = string_t('XabcY')
687
+ calculator.assignable?(p_t, p_s).should == true
688
+ end
689
+
690
+ it 'should accept a regexp matching a pattern' do
691
+ p_t = pattern_t(regexp_t('abc'))
692
+ p_s = string_t('XabcY')
693
+ calculator.assignable?(p_t, p_s).should == true
694
+ end
695
+
696
+ it 'should accept a string matching all patterns' do
697
+ p_t = pattern_t('abc', 'ab', 'c')
698
+ p_s = string_t('XabcY')
699
+ calculator.assignable?(p_t, p_s).should == true
700
+ end
701
+
702
+ it 'should accept multiple strings if they all match any patterns' do
703
+ p_t = pattern_t('X', 'Y', 'abc')
704
+ p_s = string_t('Xa', 'aY', 'abc')
705
+ calculator.assignable?(p_t, p_s).should == true
706
+ end
707
+
708
+ it 'should reject a string not matching any patterns' do
709
+ p_t = pattern_t('abc', 'ab', 'c')
710
+ p_s = string_t('XqqqY')
711
+ calculator.assignable?(p_t, p_s).should == false
712
+ end
713
+
714
+ it 'should reject multiple strings if not all match any patterns' do
715
+ p_t = pattern_t('abc', 'ab', 'c', 'q')
716
+ p_s = string_t('X', 'Y', 'Z')
717
+ calculator.assignable?(p_t, p_s).should == false
718
+ end
719
+
720
+ it 'should accept enum matching patterns as instanceof' do
721
+ enum = enum_t('XS', 'S', 'M', 'L' 'XL', 'XXL')
722
+ pattern = pattern_t('S', 'M', 'L')
723
+ calculator.assignable?(pattern, enum).should == true
724
+ end
725
+
308
726
  end
309
727
 
310
- it 'should recognize mapped ruby types' do
311
- calculator.assignable?(Puppet::Pops::Types::PIntegerType.new(), Integer).should == true
312
- calculator.assignable?(Puppet::Pops::Types::PIntegerType.new(), Fixnum).should == true
313
- calculator.assignable?(Puppet::Pops::Types::PIntegerType.new(), Bignum).should == true
314
- calculator.assignable?(Puppet::Pops::Types::PFloatType.new(), Float).should == true
315
- calculator.assignable?(Puppet::Pops::Types::PNumericType.new(), Numeric).should == true
316
- calculator.assignable?(Puppet::Pops::Types::PNilType.new(), NilClass).should == true
317
- calculator.assignable?(Puppet::Pops::Types::PBooleanType.new(), FalseClass).should == true
318
- calculator.assignable?(Puppet::Pops::Types::PBooleanType.new(), TrueClass).should == true
319
- calculator.assignable?(Puppet::Pops::Types::PStringType.new(), String).should == true
320
- calculator.assignable?(Puppet::Pops::Types::PPatternType.new(), Regexp).should == true
321
- calculator.assignable?(Puppet::Pops::Types::TypeFactory.array_of_data(), Array).should == true
322
- calculator.assignable?(Puppet::Pops::Types::TypeFactory.hash_of_data(), Hash).should == true
728
+ context 'when dealing with tuples' do
729
+ it 'should accept matching tuples' do
730
+ tuple1 = tuple_t(1,2)
731
+ tuple2 = tuple_t(Integer,Integer)
732
+ calculator.assignable?(tuple1, tuple2).should == true
733
+ calculator.assignable?(tuple2, tuple1).should == true
734
+ end
735
+
736
+ it 'should accept matching tuples where one is more general than the other' do
737
+ tuple1 = tuple_t(1,2)
738
+ tuple2 = tuple_t(Numeric,Numeric)
739
+ calculator.assignable?(tuple1, tuple2).should == false
740
+ calculator.assignable?(tuple2, tuple1).should == true
741
+ end
742
+
743
+ it 'should accept ranged tuples' do
744
+ tuple1 = tuple_t(1)
745
+ factory.constrain_size(tuple1, 5, 5)
746
+ tuple2 = tuple_t(Integer,Integer, Integer, Integer, Integer)
747
+ calculator.assignable?(tuple1, tuple2).should == true
748
+ calculator.assignable?(tuple2, tuple1).should == true
749
+ end
750
+
751
+ it 'should reject ranged tuples when ranges does not match' do
752
+ tuple1 = tuple_t(1)
753
+ factory.constrain_size(tuple1, 4, 5)
754
+ tuple2 = tuple_t(Integer,Integer, Integer, Integer, Integer)
755
+ calculator.assignable?(tuple1, tuple2).should == true
756
+ calculator.assignable?(tuple2, tuple1).should == false
757
+ end
758
+
759
+ it 'should reject ranged tuples when ranges does not match (using infinite upper bound)' do
760
+ tuple1 = tuple_t(1)
761
+ factory.constrain_size(tuple1, 4, :default)
762
+ tuple2 = tuple_t(Integer,Integer, Integer, Integer, Integer)
763
+ calculator.assignable?(tuple1, tuple2).should == true
764
+ calculator.assignable?(tuple2, tuple1).should == false
765
+ end
766
+
767
+ it 'should accept matching tuples with optional entries' do
768
+ tuple1 = tuple_t(1,2)
769
+ factory.constrain_size(tuple1, 0, :default)
770
+ tuple2 = tuple_t(Numeric,Numeric)
771
+ factory.constrain_size(tuple2, 0, :default)
772
+ calculator.assignable?(tuple1, tuple2).should == false
773
+ calculator.assignable?(tuple2, tuple1).should == true
774
+ end
775
+
776
+ it 'should accept matching array' do
777
+ tuple1 = tuple_t(1,2)
778
+ array = array_t(Integer)
779
+ factory.constrain_size(array, 2, 2)
780
+ calculator.assignable?(tuple1, array).should == true
781
+ calculator.assignable?(array, tuple1).should == true
782
+ end
783
+ end
784
+
785
+ context 'when dealing with structs' do
786
+ it 'should accept matching structs' do
787
+ struct1 = struct_t({'a'=>Integer, 'b'=>Integer})
788
+ struct2 = struct_t({'a'=>Integer, 'b'=>Integer})
789
+ calculator.assignable?(struct1, struct2).should == true
790
+ calculator.assignable?(struct2, struct1).should == true
791
+ end
792
+
793
+ it 'should accept matching structs where one is more general than the other' do
794
+ struct1 = struct_t({'a'=>Integer, 'b'=>Integer})
795
+ struct2 = struct_t({'a'=>Numeric, 'b'=>Numeric})
796
+ calculator.assignable?(struct1, struct2).should == false
797
+ calculator.assignable?(struct2, struct1).should == true
798
+ end
799
+
800
+ it 'should accept matching hash' do
801
+ struct1 = struct_t({'a'=>Integer, 'b'=>Integer})
802
+ non_empty_string = string_t()
803
+ non_empty_string.size_type = range_t(1, nil)
804
+ hsh = hash_t(non_empty_string, Integer)
805
+ factory.constrain_size(hsh, 2, 2)
806
+ calculator.assignable?(struct1, hsh).should == true
807
+ calculator.assignable?(hsh, struct1).should == true
808
+ end
323
809
  end
324
810
 
325
811
  it 'should recognize ruby type inheritance' do
@@ -341,15 +827,209 @@ describe 'The type calculator' do
341
827
  calculator.assignable?(barType, fooType).should == false
342
828
  calculator.assignable?(Bar, fooType).should == false
343
829
  end
830
+
831
+ it "should allow host class with same name" do
832
+ hc1 = Puppet::Pops::Types::TypeFactory.host_class('the_name')
833
+ hc2 = Puppet::Pops::Types::TypeFactory.host_class('the_name')
834
+ calculator.assignable?(hc1, hc2).should == true
835
+ end
836
+
837
+ it "should allow host class with name assigned to hostclass without name" do
838
+ hc1 = Puppet::Pops::Types::TypeFactory.host_class()
839
+ hc2 = Puppet::Pops::Types::TypeFactory.host_class('the_name')
840
+ calculator.assignable?(hc1, hc2).should == true
841
+ end
842
+
843
+ it "should reject host classes with different names" do
844
+ hc1 = Puppet::Pops::Types::TypeFactory.host_class('the_name')
845
+ hc2 = Puppet::Pops::Types::TypeFactory.host_class('another_name')
846
+ calculator.assignable?(hc1, hc2).should == false
847
+ end
848
+
849
+ it "should reject host classes without name assigned to host class with name" do
850
+ hc1 = Puppet::Pops::Types::TypeFactory.host_class('the_name')
851
+ hc2 = Puppet::Pops::Types::TypeFactory.host_class()
852
+ calculator.assignable?(hc1, hc2).should == false
853
+ end
854
+
855
+ it "should allow resource with same type_name and title" do
856
+ r1 = Puppet::Pops::Types::TypeFactory.resource('file', 'foo')
857
+ r2 = Puppet::Pops::Types::TypeFactory.resource('file', 'foo')
858
+ calculator.assignable?(r1, r2).should == true
859
+ end
860
+
861
+ it "should allow more specific resource assignment" do
862
+ r1 = Puppet::Pops::Types::TypeFactory.resource()
863
+ r2 = Puppet::Pops::Types::TypeFactory.resource('file')
864
+ calculator.assignable?(r1, r2).should == true
865
+ r2 = Puppet::Pops::Types::TypeFactory.resource('file', '/tmp/foo')
866
+ calculator.assignable?(r1, r2).should == true
867
+ r1 = Puppet::Pops::Types::TypeFactory.resource('file')
868
+ calculator.assignable?(r1, r2).should == true
869
+ end
870
+
871
+ it "should reject less specific resource assignment" do
872
+ r1 = Puppet::Pops::Types::TypeFactory.resource('file', '/tmp/foo')
873
+ r2 = Puppet::Pops::Types::TypeFactory.resource('file')
874
+ calculator.assignable?(r1, r2).should == false
875
+ r2 = Puppet::Pops::Types::TypeFactory.resource()
876
+ calculator.assignable?(r1, r2).should == false
877
+ end
878
+
344
879
  end
345
880
 
346
881
  context 'when testing if x is instance of type t' do
882
+ include_context "types_setup"
883
+
884
+ it 'should consider undef to be instance of Object and NilType' do
885
+ calculator.instance?(Puppet::Pops::Types::PNilType.new(), nil).should == true
886
+ calculator.instance?(Puppet::Pops::Types::PObjectType.new(), nil).should == true
887
+ end
888
+
889
+ it 'should not consider undef to be an instance of any other type than Object and NilType and Data' do
890
+ types_to_test = all_types - [
891
+ Puppet::Pops::Types::PObjectType,
892
+ Puppet::Pops::Types::PNilType,
893
+ Puppet::Pops::Types::PDataType]
894
+
895
+ types_to_test.each {|t| calculator.instance?(t.new, nil).should == false }
896
+ types_to_test.each {|t| calculator.instance?(t.new, :undef).should == false }
897
+ end
898
+
347
899
  it 'should consider fixnum instanceof PIntegerType' do
348
- calculator.instance?(Puppet::Pops::Types::PIntegerType.new(), 1)
900
+ calculator.instance?(Puppet::Pops::Types::PIntegerType.new(), 1).should == true
349
901
  end
350
902
 
351
903
  it 'should consider fixnum instanceof Fixnum' do
352
- calculator.instance?(Fixnum, 1)
904
+ calculator.instance?(Fixnum, 1).should == true
905
+ end
906
+
907
+ it 'should consider integer in range' do
908
+ range = range_t(0,10)
909
+ calculator.instance?(range, 1).should == true
910
+ calculator.instance?(range, 10).should == true
911
+ calculator.instance?(range, -1).should == false
912
+ calculator.instance?(range, 11).should == false
913
+ end
914
+
915
+ it 'should consider string in length range' do
916
+ range = factory.constrain_size(string_t, 1,3)
917
+ calculator.instance?(range, 'a').should == true
918
+ calculator.instance?(range, 'abc').should == true
919
+ calculator.instance?(range, '').should == false
920
+ calculator.instance?(range, 'abcd').should == false
921
+ end
922
+
923
+ it 'should consider array in length range' do
924
+ range = factory.constrain_size(array_t(integer_t), 1,3)
925
+ calculator.instance?(range, [1]).should == true
926
+ calculator.instance?(range, [1,2,3]).should == true
927
+ calculator.instance?(range, []).should == false
928
+ calculator.instance?(range, [1,2,3,4]).should == false
929
+ end
930
+
931
+ it 'should consider hash in length range' do
932
+ range = factory.constrain_size(hash_t(integer_t, integer_t), 1,2)
933
+ calculator.instance?(range, {1=>1}).should == true
934
+ calculator.instance?(range, {1=>1, 2=>2}).should == true
935
+ calculator.instance?(range, {}).should == false
936
+ calculator.instance?(range, {1=>1, 2=>2, 3=>3}).should == false
937
+ end
938
+
939
+ it 'should consider collection in length range for array ' do
940
+ range = factory.constrain_size(collection_t, 1,3)
941
+ calculator.instance?(range, [1]).should == true
942
+ calculator.instance?(range, [1,2,3]).should == true
943
+ calculator.instance?(range, []).should == false
944
+ calculator.instance?(range, [1,2,3,4]).should == false
945
+ end
946
+
947
+ it 'should consider collection in length range for hash' do
948
+ range = factory.constrain_size(collection_t, 1,2)
949
+ calculator.instance?(range, {1=>1}).should == true
950
+ calculator.instance?(range, {1=>1, 2=>2}).should == true
951
+ calculator.instance?(range, {}).should == false
952
+ calculator.instance?(range, {1=>1, 2=>2, 3=>3}).should == false
953
+ end
954
+
955
+ it 'should consider string matching enum as instanceof' do
956
+ enum = enum_t('XS', 'S', 'M', 'L', 'XL', '0')
957
+ calculator.instance?(enum, 'XS').should == true
958
+ calculator.instance?(enum, 'S').should == true
959
+ calculator.instance?(enum, 'XXL').should == false
960
+ calculator.instance?(enum, '').should == false
961
+ calculator.instance?(enum, '0').should == true
962
+ calculator.instance?(enum, 0).should == false
963
+ end
964
+
965
+ it 'should consider array[string] as instance of Array[Enum] when strings are instance of Enum' do
966
+ enum = enum_t('XS', 'S', 'M', 'L', 'XL', '0')
967
+ array = array_t(enum)
968
+ calculator.instance?(array, ['XS', 'S', 'XL']).should == true
969
+ calculator.instance?(array, ['XS', 'S', 'XXL']).should == false
970
+ end
971
+
972
+ it 'should consider array[mixed] as instance of Variant[mixed] when mixed types are listed in Variant' do
973
+ enum = enum_t('XS', 'S', 'M', 'L', 'XL')
974
+ sizes = range_t(30, 50)
975
+ array = array_t(variant_t(enum, sizes))
976
+ calculator.instance?(array, ['XS', 'S', 30, 50]).should == true
977
+ calculator.instance?(array, ['XS', 'S', 'XXL']).should == false
978
+ calculator.instance?(array, ['XS', 'S', 29]).should == false
979
+ end
980
+
981
+ it 'should consider array[seq] as instance of Tuple[seq] when elements of seq are instance of' do
982
+ tuple = tuple_t(Integer, String, Float)
983
+ calculator.instance?(tuple, [1, 'a', 3.14]).should == true
984
+ calculator.instance?(tuple, [1.2, 'a', 3.14]).should == false
985
+ calculator.instance?(tuple, [1, 1, 3.14]).should == false
986
+ calculator.instance?(tuple, [1, 'a', 1]).should == false
987
+ end
988
+
989
+ it 'should consider hash[cont] as instance of Struct[cont-t]' do
990
+ struct = struct_t({'a'=>Integer, 'b'=>String, 'c'=>Float})
991
+ calculator.instance?(struct, {'a'=>1, 'b'=>'a', 'c'=>3.14}).should == true
992
+ calculator.instance?(struct, {'a'=>1.2, 'b'=>'a', 'c'=>3.14}).should == false
993
+ calculator.instance?(struct, {'a'=>1, 'b'=>1, 'c'=>3.14}).should == false
994
+ calculator.instance?(struct, {'a'=>1, 'b'=>'a', 'c'=>1}).should == false
995
+ end
996
+
997
+ context 'and t is Data' do
998
+ it 'undef should be considered instance of Data' do
999
+ calculator.instance?(data_t, :undef).should == true
1000
+ end
1001
+
1002
+ it 'other symbols should not be considered instance of Data' do
1003
+ calculator.instance?(data_t, :love).should == false
1004
+ end
1005
+
1006
+ it 'an empty array should be considered instance of Data' do
1007
+ calculator.instance?(data_t, []).should == true
1008
+ end
1009
+
1010
+ it 'an empty hash should be considered instance of Data' do
1011
+ calculator.instance?(data_t, {}).should == true
1012
+ end
1013
+
1014
+ it 'a hash with nil/undef data should be considered instance of Data' do
1015
+ calculator.instance?(data_t, {'a' => nil}).should == true
1016
+ calculator.instance?(data_t, {'a' => :undef}).should == true
1017
+ end
1018
+
1019
+ it 'a hash with nil/undef key should not considered instance of Data' do
1020
+ calculator.instance?(data_t, {nil => 10}).should == false
1021
+ calculator.instance?(data_t, {:undef => 10}).should == false
1022
+ end
1023
+
1024
+ it 'an array with undef entries should be considered instance of Data' do
1025
+ calculator.instance?(data_t, [:undef]).should == true
1026
+ calculator.instance?(data_t, [nil]).should == true
1027
+ end
1028
+
1029
+ it 'an array with undef / data entries should be considered instance of Data' do
1030
+ calculator.instance?(data_t, [1, :undef, 'a']).should == true
1031
+ calculator.instance?(data_t, [1, nil, 'a']).should == true
1032
+ end
353
1033
  end
354
1034
  end
355
1035
 
@@ -378,8 +1058,8 @@ describe 'The type calculator' do
378
1058
  calculator.type(String).class.should == Puppet::Pops::Types::PStringType
379
1059
  end
380
1060
 
381
- it 'should yield \'PPatternType\' for Regexp' do
382
- calculator.type(Regexp).class.should == Puppet::Pops::Types::PPatternType
1061
+ it 'should yield \'PRegexpType\' for Regexp' do
1062
+ calculator.type(Regexp).class.should == Puppet::Pops::Types::PRegexpType
383
1063
  end
384
1064
 
385
1065
  it 'should yield \'PArrayType[PDataType]\' for Array' do
@@ -388,10 +1068,10 @@ describe 'The type calculator' do
388
1068
  t.element_type.class.should == Puppet::Pops::Types::PDataType
389
1069
  end
390
1070
 
391
- it 'should yield \'PHashType[PLiteralType,PDataType]\' for Hash' do
1071
+ it 'should yield \'PHashType[PScalarType,PDataType]\' for Hash' do
392
1072
  t = calculator.type(Hash)
393
1073
  t.class.should == Puppet::Pops::Types::PHashType
394
- t.key_type.class.should == Puppet::Pops::Types::PLiteralType
1074
+ t.key_type.class.should == Puppet::Pops::Types::PScalarType
395
1075
  t.element_type.class.should == Puppet::Pops::Types::PDataType
396
1076
  end
397
1077
  end
@@ -405,8 +1085,8 @@ describe 'The type calculator' do
405
1085
  calculator.string(Puppet::Pops::Types::PObjectType.new()).should == 'Object'
406
1086
  end
407
1087
 
408
- it 'should yield \'Literal\' for PLiteralType' do
409
- calculator.string(Puppet::Pops::Types::PLiteralType.new()).should == 'Literal'
1088
+ it 'should yield \'Scalar\' for PScalarType' do
1089
+ calculator.string(Puppet::Pops::Types::PScalarType.new()).should == 'Scalar'
410
1090
  end
411
1091
 
412
1092
  it 'should yield \'Boolean\' for PBooleanType' do
@@ -421,34 +1101,178 @@ describe 'The type calculator' do
421
1101
  calculator.string(Puppet::Pops::Types::PNumericType.new()).should == 'Numeric'
422
1102
  end
423
1103
 
424
- it 'should yield \'Integer\' for PIntegerType' do
425
- calculator.string(Puppet::Pops::Types::PIntegerType.new()).should == 'Integer'
1104
+ it 'should yield \'Integer\' and from/to for PIntegerType' do
1105
+ int_T = Puppet::Pops::Types::PIntegerType
1106
+ calculator.string(int_T.new()).should == 'Integer'
1107
+ int = int_T.new()
1108
+ int.from = 1
1109
+ int.to = 1
1110
+ calculator.string(int).should == 'Integer[1, 1]'
1111
+ int = int_T.new()
1112
+ int.from = 1
1113
+ int.to = 2
1114
+ calculator.string(int).should == 'Integer[1, 2]'
1115
+ int = int_T.new()
1116
+ int.from = nil
1117
+ int.to = 2
1118
+ calculator.string(int).should == 'Integer[default, 2]'
1119
+ int = int_T.new()
1120
+ int.from = 2
1121
+ int.to = nil
1122
+ calculator.string(int).should == 'Integer[2, default]'
426
1123
  end
427
1124
 
428
1125
  it 'should yield \'Float\' for PFloatType' do
429
1126
  calculator.string(Puppet::Pops::Types::PFloatType.new()).should == 'Float'
430
1127
  end
431
1128
 
432
- it 'should yield \'Pattern\' for PPatternType' do
433
- calculator.string(Puppet::Pops::Types::PPatternType.new()).should == 'Pattern'
1129
+ it 'should yield \'Regexp\' for PRegexpType' do
1130
+ calculator.string(Puppet::Pops::Types::PRegexpType.new()).should == 'Regexp'
1131
+ end
1132
+
1133
+ it 'should yield \'Regexp[/pat/]\' for parameterized PRegexpType' do
1134
+ t = Puppet::Pops::Types::PRegexpType.new()
1135
+ t.pattern = ('a/b')
1136
+ calculator.string(Puppet::Pops::Types::PRegexpType.new()).should == 'Regexp'
434
1137
  end
435
1138
 
436
1139
  it 'should yield \'String\' for PStringType' do
437
1140
  calculator.string(Puppet::Pops::Types::PStringType.new()).should == 'String'
438
1141
  end
439
1142
 
1143
+ it 'should yield \'String\' for PStringType with multiple values' do
1144
+ calculator.string(string_t('a', 'b', 'c')).should == 'String'
1145
+ end
1146
+
1147
+ it 'should yield \'String\' and from/to for PStringType' do
1148
+ string_T = Puppet::Pops::Types::PStringType
1149
+ calculator.string(factory.constrain_size(string_T.new(), 1,1)).should == 'String[1, 1]'
1150
+ calculator.string(factory.constrain_size(string_T.new(), 1,2)).should == 'String[1, 2]'
1151
+ calculator.string(factory.constrain_size(string_T.new(), :default, 2)).should == 'String[default, 2]'
1152
+ calculator.string(factory.constrain_size(string_T.new(), 2, :default)).should == 'String[2, default]'
1153
+ end
1154
+
440
1155
  it 'should yield \'Array[Integer]\' for PArrayType[PIntegerType]' do
441
1156
  t = Puppet::Pops::Types::PArrayType.new()
442
1157
  t.element_type = Puppet::Pops::Types::PIntegerType.new()
443
1158
  calculator.string(t).should == 'Array[Integer]'
444
1159
  end
445
1160
 
1161
+ it 'should yield \'Collection\' and from/to for PCollectionType' do
1162
+ col = collection_t()
1163
+ calculator.string(factory.constrain_size(col.copy, 1,1)).should == 'Collection[1, 1]'
1164
+ calculator.string(factory.constrain_size(col.copy, 1,2)).should == 'Collection[1, 2]'
1165
+ calculator.string(factory.constrain_size(col.copy, :default, 2)).should == 'Collection[default, 2]'
1166
+ calculator.string(factory.constrain_size(col.copy, 2, :default)).should == 'Collection[2, default]'
1167
+ end
1168
+
1169
+ it 'should yield \'Array\' and from/to for PArrayType' do
1170
+ arr = array_t(string_t)
1171
+ calculator.string(factory.constrain_size(arr.copy, 1,1)).should == 'Array[String, 1, 1]'
1172
+ calculator.string(factory.constrain_size(arr.copy, 1,2)).should == 'Array[String, 1, 2]'
1173
+ calculator.string(factory.constrain_size(arr.copy, :default, 2)).should == 'Array[String, default, 2]'
1174
+ calculator.string(factory.constrain_size(arr.copy, 2, :default)).should == 'Array[String, 2, default]'
1175
+ end
1176
+
1177
+ it 'should yield \'Tuple[Integer]\' for PTupleType[PIntegerType]' do
1178
+ t = Puppet::Pops::Types::PTupleType.new()
1179
+ t.addTypes(Puppet::Pops::Types::PIntegerType.new())
1180
+ calculator.string(t).should == 'Tuple[Integer]'
1181
+ end
1182
+
1183
+ it 'should yield \'Tuple[T, T,..]\' for PTupleType[T, T, ...]' do
1184
+ t = Puppet::Pops::Types::PTupleType.new()
1185
+ t.addTypes(Puppet::Pops::Types::PIntegerType.new())
1186
+ t.addTypes(Puppet::Pops::Types::PIntegerType.new())
1187
+ t.addTypes(Puppet::Pops::Types::PStringType.new())
1188
+ calculator.string(t).should == 'Tuple[Integer, Integer, String]'
1189
+ end
1190
+
1191
+ it 'should yield \'Tuple\' and from/to for PTupleType' do
1192
+ tuple_t = tuple_t(string_t)
1193
+ calculator.string(factory.constrain_size(tuple_t.copy, 1,1)).should == 'Tuple[String, 1, 1]'
1194
+ calculator.string(factory.constrain_size(tuple_t.copy, 1,2)).should == 'Tuple[String, 1, 2]'
1195
+ calculator.string(factory.constrain_size(tuple_t.copy, :default, 2)).should == 'Tuple[String, default, 2]'
1196
+ calculator.string(factory.constrain_size(tuple_t.copy, 2, :default)).should == 'Tuple[String, 2, default]'
1197
+ end
1198
+
1199
+ it 'should yield \'Struct\' and details for PStructType' do
1200
+ struct_t = struct_t({'a'=>Integer, 'b'=>String})
1201
+ s = calculator.string(struct_t)
1202
+ # Ruby 1.8.7 - noone likes you...
1203
+ (s == "Struct[{'a'=>Integer, 'b'=>String}]" || s == "Struct[{'b'=>String, 'a'=>Integer}]").should == true
1204
+ struct_t = struct_t({})
1205
+ calculator.string(struct_t).should == "Struct"
1206
+ end
1207
+
446
1208
  it 'should yield \'Hash[String, Integer]\' for PHashType[PStringType, PIntegerType]' do
447
1209
  t = Puppet::Pops::Types::PHashType.new()
448
1210
  t.key_type = Puppet::Pops::Types::PStringType.new()
449
1211
  t.element_type = Puppet::Pops::Types::PIntegerType.new()
450
1212
  calculator.string(t).should == 'Hash[String, Integer]'
451
1213
  end
1214
+
1215
+ it 'should yield \'Hash\' and from/to for PHashType' do
1216
+ hsh = hash_t(string_t, string_t)
1217
+ calculator.string(factory.constrain_size(hsh.copy, 1,1)).should == 'Hash[String, String, 1, 1]'
1218
+ calculator.string(factory.constrain_size(hsh.copy, 1,2)).should == 'Hash[String, String, 1, 2]'
1219
+ calculator.string(factory.constrain_size(hsh.copy, :default, 2)).should == 'Hash[String, String, default, 2]'
1220
+ calculator.string(factory.constrain_size(hsh.copy, 2, :default)).should == 'Hash[String, String, 2, default]'
1221
+ end
1222
+
1223
+ it "should yield 'Class' for a PHostClassType" do
1224
+ t = Puppet::Pops::Types::PHostClassType.new()
1225
+ calculator.string(t).should == 'Class'
1226
+ end
1227
+
1228
+ it "should yield 'Class[x]' for a PHostClassType[x]" do
1229
+ t = Puppet::Pops::Types::PHostClassType.new()
1230
+ t.class_name = 'x'
1231
+ calculator.string(t).should == 'Class[x]'
1232
+ end
1233
+
1234
+ it "should yield 'Resource' for a PResourceType" do
1235
+ t = Puppet::Pops::Types::PResourceType.new()
1236
+ calculator.string(t).should == 'Resource'
1237
+ end
1238
+
1239
+ it 'should yield \'File\' for a PResourceType[\'File\']' do
1240
+ t = Puppet::Pops::Types::PResourceType.new()
1241
+ t.type_name = 'File'
1242
+ calculator.string(t).should == 'File'
1243
+ end
1244
+
1245
+ it "should yield 'File['/tmp/foo']' for a PResourceType['File', '/tmp/foo']" do
1246
+ t = Puppet::Pops::Types::PResourceType.new()
1247
+ t.type_name = 'File'
1248
+ t.title = '/tmp/foo'
1249
+ calculator.string(t).should == "File['/tmp/foo']"
1250
+ end
1251
+
1252
+ it "should yield 'Enum[s,...]' for a PEnumType[s,...]" do
1253
+ t = enum_t('a', 'b', 'c')
1254
+ calculator.string(t).should == "Enum['a', 'b', 'c']"
1255
+ end
1256
+
1257
+ it "should yield 'Pattern[/pat/,...]' for a PPatternType['pat',...]" do
1258
+ t = pattern_t('a')
1259
+ t2 = pattern_t('a', 'b', 'c')
1260
+ calculator.string(t).should == "Pattern[/a/]"
1261
+ calculator.string(t2).should == "Pattern[/a/, /b/, /c/]"
1262
+ end
1263
+
1264
+ it "should escape special characters in the string for a PPatternType['pat',...]" do
1265
+ t = pattern_t('a/b')
1266
+ calculator.string(t).should == "Pattern[/a\\/b/]"
1267
+ end
1268
+
1269
+ it "should yield 'Variant[t1,t2,...]' for a PVariantType[t1, t2,...]" do
1270
+ t1 = string_t()
1271
+ t2 = integer_t()
1272
+ t3 = pattern_t('a')
1273
+ t = variant_t(t1, t2, t3)
1274
+ calculator.string(t).should == "Variant[String, Integer, Pattern[/a/]]"
1275
+ end
452
1276
  end
453
1277
 
454
1278
  context 'when processing meta type' do
@@ -456,17 +1280,53 @@ describe 'The type calculator' do
456
1280
  ptype = Puppet::Pops::Types::PType
457
1281
  calculator.infer(Puppet::Pops::Types::PNilType.new() ).is_a?(ptype).should() == true
458
1282
  calculator.infer(Puppet::Pops::Types::PDataType.new() ).is_a?(ptype).should() == true
459
- calculator.infer(Puppet::Pops::Types::PLiteralType.new() ).is_a?(ptype).should() == true
1283
+ calculator.infer(Puppet::Pops::Types::PScalarType.new() ).is_a?(ptype).should() == true
460
1284
  calculator.infer(Puppet::Pops::Types::PStringType.new() ).is_a?(ptype).should() == true
461
1285
  calculator.infer(Puppet::Pops::Types::PNumericType.new() ).is_a?(ptype).should() == true
462
1286
  calculator.infer(Puppet::Pops::Types::PIntegerType.new() ).is_a?(ptype).should() == true
463
1287
  calculator.infer(Puppet::Pops::Types::PFloatType.new() ).is_a?(ptype).should() == true
464
- calculator.infer(Puppet::Pops::Types::PPatternType.new() ).is_a?(ptype).should() == true
1288
+ calculator.infer(Puppet::Pops::Types::PRegexpType.new() ).is_a?(ptype).should() == true
465
1289
  calculator.infer(Puppet::Pops::Types::PBooleanType.new() ).is_a?(ptype).should() == true
466
1290
  calculator.infer(Puppet::Pops::Types::PCollectionType.new()).is_a?(ptype).should() == true
467
1291
  calculator.infer(Puppet::Pops::Types::PArrayType.new() ).is_a?(ptype).should() == true
468
1292
  calculator.infer(Puppet::Pops::Types::PHashType.new() ).is_a?(ptype).should() == true
469
1293
  calculator.infer(Puppet::Pops::Types::PRubyType.new() ).is_a?(ptype).should() == true
1294
+ calculator.infer(Puppet::Pops::Types::PHostClassType.new() ).is_a?(ptype).should() == true
1295
+ calculator.infer(Puppet::Pops::Types::PResourceType.new() ).is_a?(ptype).should() == true
1296
+ calculator.infer(Puppet::Pops::Types::PEnumType.new() ).is_a?(ptype).should() == true
1297
+ calculator.infer(Puppet::Pops::Types::PPatternType.new() ).is_a?(ptype).should() == true
1298
+ calculator.infer(Puppet::Pops::Types::PVariantType.new() ).is_a?(ptype).should() == true
1299
+ calculator.infer(Puppet::Pops::Types::PTupleType.new() ).is_a?(ptype).should() == true
1300
+ end
1301
+
1302
+ it 'should infer PType as the type of all other types' do
1303
+ ptype = Puppet::Pops::Types::PType
1304
+ calculator.string(calculator.infer(Puppet::Pops::Types::PNilType.new() )).should == "Type[Undef]"
1305
+ calculator.string(calculator.infer(Puppet::Pops::Types::PDataType.new() )).should == "Type[Data]"
1306
+ calculator.string(calculator.infer(Puppet::Pops::Types::PScalarType.new() )).should == "Type[Scalar]"
1307
+ calculator.string(calculator.infer(Puppet::Pops::Types::PStringType.new() )).should == "Type[String]"
1308
+ calculator.string(calculator.infer(Puppet::Pops::Types::PNumericType.new() )).should == "Type[Numeric]"
1309
+ calculator.string(calculator.infer(Puppet::Pops::Types::PIntegerType.new() )).should == "Type[Integer]"
1310
+ calculator.string(calculator.infer(Puppet::Pops::Types::PFloatType.new() )).should == "Type[Float]"
1311
+ calculator.string(calculator.infer(Puppet::Pops::Types::PRegexpType.new() )).should == "Type[Regexp]"
1312
+ calculator.string(calculator.infer(Puppet::Pops::Types::PBooleanType.new() )).should == "Type[Boolean]"
1313
+ calculator.string(calculator.infer(Puppet::Pops::Types::PCollectionType.new())).should == "Type[Collection]"
1314
+ calculator.string(calculator.infer(Puppet::Pops::Types::PArrayType.new() )).should == "Type[Array[?]]"
1315
+ calculator.string(calculator.infer(Puppet::Pops::Types::PHashType.new() )).should == "Type[Hash[?, ?]]"
1316
+ calculator.string(calculator.infer(Puppet::Pops::Types::PRubyType.new() )).should == "Type[Ruby[?]]"
1317
+ calculator.string(calculator.infer(Puppet::Pops::Types::PHostClassType.new() )).should == "Type[Class]"
1318
+ calculator.string(calculator.infer(Puppet::Pops::Types::PResourceType.new() )).should == "Type[Resource]"
1319
+ calculator.string(calculator.infer(Puppet::Pops::Types::PEnumType.new() )).should == "Type[Enum]"
1320
+ calculator.string(calculator.infer(Puppet::Pops::Types::PVariantType.new() )).should == "Type[Variant]"
1321
+ calculator.string(calculator.infer(Puppet::Pops::Types::PPatternType.new() )).should == "Type[Pattern]"
1322
+ calculator.string(calculator.infer(Puppet::Pops::Types::PTupleType.new() )).should == "Type[Tuple]"
1323
+ end
1324
+
1325
+ it "computes the common type of PType's type parameter" do
1326
+ int_t = Puppet::Pops::Types::PIntegerType.new()
1327
+ string_t = Puppet::Pops::Types::PStringType.new()
1328
+ calculator.string(calculator.infer([int_t])).should == "Array[Type[Integer], 1, 1]"
1329
+ calculator.string(calculator.infer([int_t, string_t])).should == "Array[Type[Scalar], 2, 2]"
470
1330
  end
471
1331
 
472
1332
  it 'should infer PType as the type of ruby classes' do
@@ -480,5 +1340,120 @@ describe 'The type calculator' do
480
1340
  it 'should infer PType as the type of PType (meta regression short-circuit)' do
481
1341
  calculator.infer(Puppet::Pops::Types::PType.new()).is_a?(Puppet::Pops::Types::PType).should() == true
482
1342
  end
1343
+
1344
+ it 'computes instance? to be true if parameterized and type match' do
1345
+ int_t = Puppet::Pops::Types::PIntegerType.new()
1346
+ type_t = Puppet::Pops::Types::TypeFactory.type_type(int_t)
1347
+ type_type_t = Puppet::Pops::Types::TypeFactory.type_type(type_t)
1348
+ calculator.instance?(type_type_t, type_t).should == true
1349
+ end
1350
+
1351
+ it 'computes instance? to be false if parameterized and type do not match' do
1352
+ int_t = Puppet::Pops::Types::PIntegerType.new()
1353
+ string_t = Puppet::Pops::Types::PStringType.new()
1354
+ type_t = Puppet::Pops::Types::TypeFactory.type_type(int_t)
1355
+ type_t2 = Puppet::Pops::Types::TypeFactory.type_type(string_t)
1356
+ type_type_t = Puppet::Pops::Types::TypeFactory.type_type(type_t)
1357
+ # i.e. Type[Integer] =~ Type[Type[Integer]] # false
1358
+ calculator.instance?(type_type_t, type_t2).should == false
1359
+ end
1360
+
1361
+ it 'computes instance? to be true if unparameterized and matched against a type[?]' do
1362
+ int_t = Puppet::Pops::Types::PIntegerType.new()
1363
+ type_t = Puppet::Pops::Types::TypeFactory.type_type(int_t)
1364
+ calculator.instance?(Puppet::Pops::Types::PType.new, type_t).should == true
1365
+ end
483
1366
  end
1367
+
1368
+ context "when asking for an enumerable " do
1369
+ it "should produce an enumerable for an Integer range that is not infinite" do
1370
+ t = Puppet::Pops::Types::PIntegerType.new()
1371
+ t.from = 1
1372
+ t.to = 10
1373
+ calculator.enumerable(t).respond_to?(:each).should == true
1374
+ end
1375
+
1376
+ it "should not produce an enumerable for an Integer range that has an infinite side" do
1377
+ t = Puppet::Pops::Types::PIntegerType.new()
1378
+ t.from = nil
1379
+ t.to = 10
1380
+ calculator.enumerable(t).should == nil
1381
+
1382
+ t = Puppet::Pops::Types::PIntegerType.new()
1383
+ t.from = 1
1384
+ t.to = nil
1385
+ calculator.enumerable(t).should == nil
1386
+ end
1387
+
1388
+ it "all but Integer range are not enumerable" do
1389
+ [Object, Numeric, Float, String, Regexp, Array, Hash].each do |t|
1390
+ calculator.enumerable(calculator.type(t)).should == nil
1391
+ end
1392
+ end
1393
+ end
1394
+
1395
+ context "when dealing with different types of inference" do
1396
+ it "an instance specific inference is produced by infer" do
1397
+ calculator.infer(['a','b']).element_type.values.should == ['a', 'b']
1398
+ end
1399
+
1400
+ it "a generic inference is produced using infer_generic" do
1401
+ calculator.infer_generic(['a','b']).element_type.values.should == []
1402
+ end
1403
+
1404
+ it "a generic result is created by generalize! given an instance specific result for an Array" do
1405
+ generic = calculator.infer(['a','b'])
1406
+ generic.element_type.values.should == ['a', 'b']
1407
+ calculator.generalize!(generic)
1408
+ generic.element_type.values.should == []
1409
+ end
1410
+
1411
+ it "a generic result is created by generalize! given an instance specific result for a Hash" do
1412
+ generic = calculator.infer({'a' =>1,'b' => 2})
1413
+ generic.key_type.values.sort.should == ['a', 'b']
1414
+ generic.element_type.from.should == 1
1415
+ generic.element_type.to.should == 2
1416
+ calculator.generalize!(generic)
1417
+ generic.key_type.values.should == []
1418
+ generic.element_type.from.should == nil
1419
+ generic.element_type.to.should == nil
1420
+ end
1421
+
1422
+ it "does not reduce by combining types when using infer_set" do
1423
+ element_type = calculator.infer(['a','b',1,2]).element_type
1424
+ element_type.class.should == Puppet::Pops::Types::PScalarType
1425
+ element_type = calculator.infer_set(['a','b',1,2]).element_type
1426
+ element_type.class.should == Puppet::Pops::Types::PVariantType
1427
+ element_type.types[0].class.should == Puppet::Pops::Types::PStringType
1428
+ element_type.types[1].class.should == Puppet::Pops::Types::PStringType
1429
+ element_type.types[2].class.should == Puppet::Pops::Types::PIntegerType
1430
+ element_type.types[3].class.should == Puppet::Pops::Types::PIntegerType
1431
+ end
1432
+
1433
+ it "does not reduce by combining types when using infer_set and values are undef" do
1434
+ element_type = calculator.infer(['a',nil]).element_type
1435
+ element_type.class.should == Puppet::Pops::Types::PStringType
1436
+ element_type = calculator.infer_set(['a',nil]).element_type
1437
+ element_type.class.should == Puppet::Pops::Types::PVariantType
1438
+ element_type.types[0].class.should == Puppet::Pops::Types::PStringType
1439
+ element_type.types[1].class.should == Puppet::Pops::Types::PNilType
1440
+ end
1441
+ end
1442
+
1443
+ matcher :be_assignable_to do |type|
1444
+ calc = Puppet::Pops::Types::TypeCalculator.new
1445
+
1446
+ match do |actual|
1447
+ calc.assignable?(type, actual)
1448
+ end
1449
+
1450
+ failure_message_for_should do |actual|
1451
+ "#{calc.string(actual)} should be assignable to #{calc.string(type)}"
1452
+ end
1453
+
1454
+ failure_message_for_should_not do |actual|
1455
+ "#{calc.string(actual)} is assignable to #{calc.string(type)} when it should not"
1456
+ end
1457
+ end
1458
+
484
1459
  end