puppet 3.5.1-x86-mingw32 → 3.6.0.rc1-x86-mingw32

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of puppet might be problematic. Click here for more details.

Files changed (342) hide show
  1. data/CONTRIBUTING.md +5 -0
  2. data/Gemfile +17 -9
  3. data/README.md +1 -0
  4. data/conf/fileserver.conf +4 -3
  5. data/ext/README.environment +8 -0
  6. data/ext/build_defaults.yaml +1 -1
  7. data/ext/debian/control +2 -2
  8. data/ext/debian/puppet-common.dirs +4 -0
  9. data/ext/debian/rules +4 -0
  10. data/ext/emacs/puppet-mode-init.el +1 -1
  11. data/ext/emacs/puppet-mode.el +36 -17
  12. data/ext/redhat/client.init +3 -3
  13. data/ext/redhat/puppet.spec.erb +9 -0
  14. data/ext/systemd/puppet.service +3 -4
  15. data/ext/systemd/puppetmaster.service +1 -3
  16. data/install.rb +1 -1
  17. data/lib/puppet.rb +2 -1
  18. data/lib/puppet/agent.rb +1 -1
  19. data/lib/puppet/application.rb +17 -17
  20. data/lib/puppet/application/doc.rb +1 -1
  21. data/lib/puppet/configurer.rb +4 -1
  22. data/lib/puppet/configurer/downloader.rb +13 -12
  23. data/lib/puppet/configurer/plugin_handler.rb +3 -3
  24. data/lib/puppet/context.rb +6 -1
  25. data/lib/puppet/defaults.rb +82 -12
  26. data/lib/puppet/environments.rb +169 -13
  27. data/lib/puppet/external/nagios/grammar.ry +2 -0
  28. data/lib/puppet/external/nagios/parser.rb +28 -19
  29. data/lib/puppet/face/config.rb +19 -6
  30. data/lib/puppet/face/module/generate.rb +209 -7
  31. data/lib/puppet/face/module/install.rb +17 -16
  32. data/lib/puppet/face/module/list.rb +83 -82
  33. data/lib/puppet/face/module/search.rb +1 -1
  34. data/lib/puppet/face/module/upgrade.rb +10 -9
  35. data/lib/puppet/face/parser.rb +3 -2
  36. data/lib/puppet/face/plugin.rb +8 -4
  37. data/lib/puppet/file_bucket/dipper.rb +6 -3
  38. data/lib/puppet/file_bucket/file.rb +4 -2
  39. data/lib/puppet/file_serving/metadata.rb +1 -1
  40. data/lib/puppet/file_system/memory_file.rb +27 -1
  41. data/lib/puppet/file_system/memory_impl.rb +15 -1
  42. data/lib/puppet/forge.rb +148 -52
  43. data/lib/puppet/forge/cache.rb +5 -1
  44. data/lib/puppet/forge/errors.rb +10 -0
  45. data/lib/puppet/forge/repository.rb +61 -26
  46. data/lib/puppet/functions.rb +548 -0
  47. data/lib/puppet/functions/assert_type.rb +42 -0
  48. data/lib/puppet/functions/import.rb +7 -0
  49. data/lib/puppet/indirector/facts/facter.rb +1 -1
  50. data/lib/puppet/indirector/file_bucket_file/file.rb +3 -2
  51. data/lib/puppet/indirector/rest.rb +18 -0
  52. data/lib/puppet/loaders.rb +20 -0
  53. data/lib/puppet/module.rb +2 -2
  54. data/lib/puppet/module_tool.rb +40 -14
  55. data/lib/puppet/module_tool/applications.rb +0 -1
  56. data/lib/puppet/module_tool/applications/application.rb +35 -26
  57. data/lib/puppet/module_tool/applications/builder.rb +16 -6
  58. data/lib/puppet/module_tool/applications/checksummer.rb +25 -19
  59. data/lib/puppet/module_tool/applications/installer.rb +196 -35
  60. data/lib/puppet/module_tool/applications/searcher.rb +1 -0
  61. data/lib/puppet/module_tool/applications/uninstaller.rb +7 -1
  62. data/lib/puppet/module_tool/applications/unpacker.rb +57 -31
  63. data/lib/puppet/module_tool/applications/upgrader.rb +221 -65
  64. data/lib/puppet/module_tool/checksums.rb +5 -8
  65. data/lib/puppet/module_tool/errors/installer.rb +12 -44
  66. data/lib/puppet/module_tool/errors/shared.rb +84 -11
  67. data/lib/puppet/module_tool/errors/upgrader.rb +16 -45
  68. data/lib/puppet/module_tool/install_directory.rb +7 -6
  69. data/lib/puppet/module_tool/installed_modules.rb +92 -0
  70. data/lib/puppet/module_tool/local_tarball.rb +91 -0
  71. data/lib/puppet/module_tool/metadata.rb +119 -115
  72. data/lib/puppet/module_tool/modulefile.rb +9 -9
  73. data/lib/puppet/module_tool/shared_behaviors.rb +19 -7
  74. data/lib/puppet/module_tool/skeleton/templates/generator/README.md.erb +79 -0
  75. data/lib/puppet/module_tool/skeleton/templates/generator/Rakefile +18 -0
  76. data/lib/puppet/module_tool/skeleton/templates/generator/metadata.json.erb +1 -0
  77. data/lib/puppet/module_tool/skeleton/templates/generator/spec/classes/init_spec.rb.erb +7 -0
  78. data/lib/puppet/module_tool/tar.rb +3 -7
  79. data/lib/puppet/module_tool/tar/gnu.rb +21 -9
  80. data/lib/puppet/module_tool/tar/mini.rb +2 -8
  81. data/lib/puppet/network/http/api/v1.rb +1 -1
  82. data/lib/puppet/network/http/api/v2/authorization.rb +4 -2
  83. data/lib/puppet/network/http/issues.rb +1 -0
  84. data/lib/puppet/network/http_pool.rb +15 -6
  85. data/lib/puppet/node/environment.rb +91 -20
  86. data/lib/puppet/parser/ast/pops_bridge.rb +44 -3
  87. data/lib/puppet/parser/collector.rb +1 -1
  88. data/lib/puppet/parser/compiler.rb +50 -7
  89. data/lib/puppet/parser/functions.rb +6 -0
  90. data/lib/puppet/parser/functions/generate.rb +1 -1
  91. data/lib/puppet/parser/resource.rb +1 -1
  92. data/lib/puppet/pops.rb +22 -1
  93. data/lib/puppet/pops/adapters.rb +8 -1
  94. data/lib/puppet/pops/binder/bindings_composer.rb +1 -1
  95. data/lib/puppet/pops/binder/bindings_factory.rb +1 -1
  96. data/lib/puppet/pops/binder/config/binder_config_checker.rb +1 -1
  97. data/lib/puppet/pops/binder/producers.rb +2 -2
  98. data/lib/puppet/pops/evaluator/access_operator.rb +65 -25
  99. data/lib/puppet/pops/evaluator/callable_signature.rb +101 -0
  100. data/lib/puppet/pops/evaluator/closure.rb +57 -2
  101. data/lib/puppet/pops/evaluator/compare_operator.rb +1 -1
  102. data/lib/puppet/pops/evaluator/evaluator_impl.rb +9 -11
  103. data/lib/puppet/pops/evaluator/runtime3_support.rb +72 -21
  104. data/lib/puppet/pops/functions/dispatch.rb +71 -0
  105. data/lib/puppet/pops/functions/dispatcher.rb +237 -0
  106. data/lib/puppet/pops/functions/function.rb +77 -0
  107. data/lib/puppet/pops/issues.rb +12 -0
  108. data/lib/puppet/pops/loader/base_loader.rb +102 -0
  109. data/lib/puppet/pops/loader/dependency_loader.rb +60 -0
  110. data/lib/puppet/pops/loader/gem_support.rb +49 -0
  111. data/lib/puppet/pops/loader/loader.rb +180 -0
  112. data/lib/puppet/pops/loader/loader_paths.rb +137 -0
  113. data/lib/puppet/pops/loader/module_loaders.rb +242 -0
  114. data/lib/puppet/pops/loader/null_loader.rb +44 -0
  115. data/lib/puppet/pops/loader/ruby_function_instantiator.rb +34 -0
  116. data/lib/puppet/pops/loader/ruby_legacy_function_instantiator.rb +109 -0
  117. data/lib/puppet/pops/loader/simple_environment_loader.rb +20 -0
  118. data/lib/puppet/pops/loader/static_loader.rb +69 -0
  119. data/lib/puppet/pops/loader/uri_helper.rb +22 -0
  120. data/lib/puppet/pops/loaders.rb +240 -0
  121. data/lib/puppet/pops/model/factory.rb +13 -5
  122. data/lib/puppet/pops/model/model_tree_dumper.rb +12 -4
  123. data/lib/puppet/pops/parser/egrammar.ra +31 -18
  124. data/lib/puppet/pops/parser/eparser.rb +1137 -1106
  125. data/lib/puppet/pops/parser/lexer2.rb +17 -16
  126. data/lib/puppet/pops/semantic_error.rb +17 -0
  127. data/lib/puppet/pops/types/type_calculator.rb +150 -15
  128. data/lib/puppet/pops/types/type_factory.rb +69 -0
  129. data/lib/puppet/pops/types/type_parser.rb +9 -0
  130. data/lib/puppet/pops/types/types.rb +65 -4
  131. data/lib/puppet/pops/validation/checker4_0.rb +1 -1
  132. data/lib/puppet/pops/validation/validator_factory_4_0.rb +1 -1
  133. data/lib/puppet/property/list.rb +1 -1
  134. data/lib/puppet/provider/augeas/augeas.rb +2 -2
  135. data/lib/puppet/provider/cron/crontab.rb +13 -2
  136. data/lib/puppet/provider/package.rb +24 -0
  137. data/lib/puppet/provider/package/apt.rb +6 -1
  138. data/lib/puppet/provider/package/gem.rb +8 -2
  139. data/lib/puppet/provider/package/msi.rb +0 -15
  140. data/lib/puppet/provider/package/openbsd.rb +0 -24
  141. data/lib/puppet/provider/package/rpm.rb +3 -29
  142. data/lib/puppet/provider/package/windows.rb +0 -15
  143. data/lib/puppet/provider/package/yum.rb +101 -24
  144. data/lib/puppet/provider/package/yumhelper.py +31 -1
  145. data/lib/puppet/provider/package/zypper.rb +10 -28
  146. data/lib/puppet/provider/service/debian.rb +1 -1
  147. data/lib/puppet/provider/service/init.rb +3 -0
  148. data/lib/puppet/provider/service/openbsd.rb +318 -0
  149. data/lib/puppet/provider/service/redhat.rb +6 -3
  150. data/lib/puppet/provider/service/systemd.rb +2 -2
  151. data/lib/puppet/provider/yumrepo/inifile.rb +115 -42
  152. data/lib/puppet/resource.rb +13 -9
  153. data/lib/puppet/resource/catalog.rb +12 -6
  154. data/lib/puppet/resource/type_collection.rb +3 -3
  155. data/lib/puppet/settings.rb +57 -36
  156. data/lib/puppet/settings/config_file.rb +5 -0
  157. data/lib/puppet/settings/environment_conf.rb +147 -0
  158. data/lib/puppet/settings/ttl_setting.rb +48 -0
  159. data/lib/puppet/ssl/certificate_authority.rb +2 -3
  160. data/lib/puppet/ssl/certificate_authority/autosign_command.rb +1 -1
  161. data/lib/puppet/ssl/certificate_request.rb +4 -4
  162. data/lib/puppet/ssl/validator/default_validator.rb +2 -2
  163. data/lib/puppet/status.rb +1 -1
  164. data/lib/puppet/test/test_helper.rb +1 -0
  165. data/lib/puppet/type/augeas.rb +13 -1
  166. data/lib/puppet/type/cron.rb +32 -18
  167. data/lib/puppet/type/file.rb +4 -2
  168. data/lib/puppet/type/file/checksum.rb +15 -5
  169. data/lib/puppet/type/file/content.rb +3 -1
  170. data/lib/puppet/type/file/source.rb +5 -5
  171. data/lib/puppet/type/package.rb +12 -17
  172. data/lib/puppet/type/resources.rb +3 -1
  173. data/lib/puppet/type/scheduled_task.rb +4 -5
  174. data/lib/puppet/type/service.rb +12 -2
  175. data/lib/puppet/type/user.rb +106 -0
  176. data/lib/puppet/type/yumrepo.rb +9 -1
  177. data/lib/puppet/util/checksums.rb +60 -1
  178. data/lib/puppet/util/diff.rb +3 -1
  179. data/lib/puppet/util/execution.rb +20 -16
  180. data/lib/puppet/util/feature.rb +3 -0
  181. data/lib/puppet/util/logging.rb +19 -12
  182. data/lib/puppet/util/rubygems.rb +10 -0
  183. data/lib/puppet/util/watched_file.rb +1 -1
  184. data/lib/puppet/util/windows/security.rb +5 -3
  185. data/lib/puppet/vendor/load_semantic.rb +1 -0
  186. data/lib/puppet/vendor/require_vendored.rb +2 -0
  187. data/lib/puppet/vendor/semantic/Gemfile +20 -0
  188. data/lib/puppet/vendor/semantic/Rakefile +69 -0
  189. data/lib/puppet/vendor/semantic/lib/semantic.rb +7 -0
  190. data/lib/puppet/vendor/semantic/lib/semantic/dependency.rb +181 -0
  191. data/lib/puppet/vendor/semantic/lib/semantic/dependency/graph.rb +60 -0
  192. data/lib/puppet/vendor/semantic/lib/semantic/dependency/graph_node.rb +117 -0
  193. data/lib/puppet/vendor/semantic/lib/semantic/dependency/module_release.rb +46 -0
  194. data/lib/puppet/vendor/semantic/lib/semantic/dependency/source.rb +25 -0
  195. data/lib/puppet/vendor/semantic/lib/semantic/dependency/unsatisfiable_graph.rb +31 -0
  196. data/lib/puppet/vendor/semantic/lib/semantic/version.rb +168 -0
  197. data/lib/puppet/vendor/semantic/lib/semantic/version_range.rb +424 -0
  198. data/lib/puppet/vendor/semantic/spec/spec_helper.rb +24 -0
  199. data/lib/puppet/vendor/semantic/spec/unit/semantic/dependency/graph_node_spec.rb +141 -0
  200. data/lib/puppet/vendor/semantic/spec/unit/semantic/dependency/graph_spec.rb +162 -0
  201. data/lib/puppet/vendor/semantic/spec/unit/semantic/dependency/module_release_spec.rb +143 -0
  202. data/lib/puppet/vendor/semantic/spec/unit/semantic/dependency/source_spec.rb +5 -0
  203. data/lib/puppet/vendor/semantic/spec/unit/semantic/dependency/unsatisfiable_graph_spec.rb +44 -0
  204. data/lib/puppet/vendor/semantic/spec/unit/semantic/dependency_spec.rb +383 -0
  205. data/lib/puppet/vendor/semantic/spec/unit/semantic/version_range_spec.rb +307 -0
  206. data/lib/puppet/vendor/semantic/spec/unit/semantic/version_spec.rb +608 -0
  207. data/lib/puppet/version.rb +1 -1
  208. data/spec/fixtures/java.tgz +0 -0
  209. data/spec/fixtures/stdlib.tgz +0 -0
  210. data/spec/fixtures/unit/pops/loaders/loaders/dependent_modules_with_metadata/usee/lib/puppet/functions/usee/callee.rb +5 -0
  211. data/spec/fixtures/unit/pops/loaders/loaders/dependent_modules_with_metadata/user/lib/puppet/functions/user/caller.rb +5 -0
  212. data/spec/fixtures/unit/pops/loaders/loaders/dependent_modules_with_metadata/user/metadata.json +9 -0
  213. data/spec/fixtures/unit/pops/loaders/loaders/single_module/modules/modulea/lib/puppet/functions/modulea/rb_func_a.rb +5 -0
  214. data/spec/fixtures/unit/pops/loaders/loaders/single_module/modules/modulea/lib/puppet/functions/rb_func_a.rb +5 -0
  215. data/spec/fixtures/unit/pops/loaders/loaders/single_module/modules/modulea/manifests/init.pp +3 -0
  216. data/spec/fixtures/unit/pops/loaders/loaders/single_module/modules/modulea/metadata.json +19 -0
  217. data/spec/fixtures/unit/pops/loaders/loaders/wo_metadata_module/modules/moduleb/lib/puppet/functions/moduleb/rb_func_b.rb +6 -0
  218. data/spec/fixtures/unit/pops/loaders/loaders/wo_metadata_module/modules/moduleb/manifests/init.pp +3 -0
  219. data/spec/fixtures/unit/provider/naginator/define_empty_param +6 -0
  220. data/spec/fixtures/unit/provider/service/systemd/list_unit_files_services +7 -0
  221. data/spec/fixtures/unit/type/user/authorized_keys +5 -0
  222. data/spec/integration/application/apply_spec.rb +1 -2
  223. data/spec/integration/configurer_spec.rb +2 -2
  224. data/spec/integration/faces/plugin_spec.rb +62 -0
  225. data/spec/integration/indirector/catalog/compiler_spec.rb +1 -1
  226. data/spec/integration/indirector/catalog/queue_spec.rb +1 -1
  227. data/spec/integration/node/environment_spec.rb +2 -2
  228. data/spec/integration/parser/future_compiler_spec.rb +96 -142
  229. data/spec/integration/parser/ruby_manifest_spec.rb +0 -5
  230. data/spec/integration/provider/cron/crontab_spec.rb +35 -0
  231. data/spec/integration/type/file_spec.rb +74 -72
  232. data/spec/integration/util/windows/security_spec.rb +17 -0
  233. data/spec/lib/matchers/resource.rb +45 -13
  234. data/spec/lib/puppet_spec/files.rb +18 -0
  235. data/spec/lib/puppet_spec/module_tool/shared_functions.rb +56 -0
  236. data/spec/lib/puppet_spec/module_tool/stub_source.rb +133 -0
  237. data/spec/shared_contexts/checksums.rb +55 -0
  238. data/spec/unit/application/apply_spec.rb +10 -7
  239. data/spec/unit/application/doc_spec.rb +17 -10
  240. data/spec/unit/application/indirection_base_spec.rb +18 -10
  241. data/spec/unit/application/inspect_spec.rb +22 -20
  242. data/spec/unit/configurer/downloader_spec.rb +7 -6
  243. data/spec/unit/configurer/plugin_handler_spec.rb +5 -8
  244. data/spec/unit/configurer_spec.rb +1 -1
  245. data/spec/unit/context_spec.rb +23 -0
  246. data/spec/unit/environments_spec.rb +274 -16
  247. data/spec/unit/face/config_spec.rb +111 -11
  248. data/spec/unit/face/module/install_spec.rb +14 -85
  249. data/spec/unit/face/module/list_spec.rb +108 -62
  250. data/spec/unit/face/module/search_spec.rb +1 -1
  251. data/spec/unit/face/module/uninstall_spec.rb +21 -42
  252. data/spec/unit/face/parser_spec.rb +5 -2
  253. data/spec/unit/file_bucket/dipper_spec.rb +92 -86
  254. data/spec/unit/file_bucket/file_spec.rb +23 -75
  255. data/spec/unit/file_serving/metadata_spec.rb +74 -74
  256. data/spec/unit/forge/module_release_spec.rb +131 -0
  257. data/spec/unit/forge/repository_spec.rb +21 -20
  258. data/spec/unit/forge_spec.rb +99 -23
  259. data/spec/unit/functions/assert_type_spec.rb +59 -0
  260. data/spec/unit/functions4_spec.rb +671 -0
  261. data/spec/unit/indirector/catalog/static_compiler_spec.rb +2 -2
  262. data/spec/unit/indirector/facts/facter_spec.rb +9 -3
  263. data/spec/unit/indirector/file_bucket_file/file_spec.rb +156 -155
  264. data/spec/unit/indirector/rest_spec.rb +8 -0
  265. data/spec/unit/interface/face_collection_spec.rb +35 -23
  266. data/spec/unit/module_spec.rb +20 -8
  267. data/spec/unit/module_tool/applications/builder_spec.rb +40 -12
  268. data/spec/unit/module_tool/applications/checksummer_spec.rb +86 -105
  269. data/spec/unit/module_tool/applications/installer_spec.rb +293 -261
  270. data/spec/unit/module_tool/applications/searcher_spec.rb +1 -1
  271. data/spec/unit/module_tool/applications/uninstaller_spec.rb +90 -154
  272. data/spec/unit/module_tool/applications/unpacker_spec.rb +12 -12
  273. data/spec/unit/module_tool/applications/upgrader_spec.rb +286 -18
  274. data/spec/unit/module_tool/metadata_spec.rb +223 -14
  275. data/spec/unit/module_tool/tar/gnu_spec.rb +12 -9
  276. data/spec/unit/module_tool/tar/mini_spec.rb +1 -1
  277. data/spec/unit/module_tool/tar_spec.rb +4 -18
  278. data/spec/unit/module_tool_spec.rb +123 -27
  279. data/spec/unit/network/formats_spec.rb +2 -2
  280. data/spec/unit/network/http_pool_spec.rb +21 -0
  281. data/spec/unit/network/rights_spec.rb +10 -8
  282. data/spec/unit/node/environment_spec.rb +27 -2
  283. data/spec/unit/parser/collector_spec.rb +1 -1
  284. data/spec/unit/parser/compiler_spec.rb +1 -1
  285. data/spec/unit/parser/functions/generate_spec.rb +4 -0
  286. data/spec/unit/pops/evaluator/access_ops_spec.rb +50 -11
  287. data/spec/unit/pops/evaluator/evaluating_parser_spec.rb +25 -0
  288. data/spec/unit/pops/loaders/dependency_loader_spec.rb +44 -0
  289. data/spec/unit/pops/loaders/loader_paths_spec.rb +66 -0
  290. data/spec/unit/pops/loaders/loaders_spec.rb +105 -0
  291. data/spec/unit/pops/loaders/module_loaders_spec.rb +119 -0
  292. data/spec/unit/pops/loaders/static_loader_spec.rb +46 -0
  293. data/spec/unit/pops/types/type_calculator_spec.rb +145 -10
  294. data/spec/unit/pops/types/type_factory_spec.rb +101 -0
  295. data/spec/unit/pops/types/type_parser_spec.rb +22 -0
  296. data/spec/unit/property/list_spec.rb +9 -1
  297. data/spec/unit/provider/augeas/augeas_spec.rb +58 -11
  298. data/spec/unit/provider/cron/crontab_spec.rb +1 -0
  299. data/spec/unit/provider/cron/parsed_spec.rb +15 -0
  300. data/spec/unit/provider/naginator_spec.rb +14 -0
  301. data/spec/unit/provider/package/apt_spec.rb +78 -64
  302. data/spec/unit/provider/package/gem_spec.rb +15 -0
  303. data/spec/unit/provider/package/rpm_spec.rb +6 -6
  304. data/spec/unit/provider/package/windows_spec.rb +1 -1
  305. data/spec/unit/provider/package/yum_spec.rb +199 -104
  306. data/spec/unit/provider/package/zypper_spec.rb +41 -15
  307. data/spec/unit/provider/service/openbsd_spec.rb +129 -22
  308. data/spec/unit/provider/service/redhat_spec.rb +18 -4
  309. data/spec/unit/provider/service/systemd_spec.rb +5 -9
  310. data/spec/unit/provider/service/upstart_spec.rb +1 -1
  311. data/spec/unit/provider/user/directoryservice_spec.rb +10 -0
  312. data/spec/unit/provider/yumrepo/inifile_spec.rb +171 -15
  313. data/spec/unit/resource/catalog_spec.rb +20 -104
  314. data/spec/unit/resource/type_collection_spec.rb +10 -9
  315. data/spec/unit/settings/config_file_spec.rb +29 -6
  316. data/spec/unit/settings/environment_conf_spec.rb +51 -0
  317. data/spec/unit/settings_spec.rb +97 -12
  318. data/spec/unit/ssl/certificate_authority_spec.rb +2 -0
  319. data/spec/unit/type/augeas_spec.rb +1 -1
  320. data/spec/unit/type/cron_spec.rb +6 -7
  321. data/spec/unit/type/file/checksum_spec.rb +6 -0
  322. data/spec/unit/type/file/content_spec.rb +277 -207
  323. data/spec/unit/type/file_spec.rb +9 -7
  324. data/spec/unit/type/user_spec.rb +106 -18
  325. data/spec/unit/type/yumrepo_spec.rb +8 -0
  326. data/spec/unit/util/checksums_spec.rb +12 -5
  327. data/spec/unit/util/diff_spec.rb +8 -0
  328. data/spec/unit/util/execution_spec.rb +4 -4
  329. data/spec/unit/util/feature_spec.rb +2 -0
  330. data/spec/unit/util/logging_spec.rb +14 -4
  331. data/spec/unit/util/rdoc/parser_spec.rb +5 -4
  332. data/spec/unit/util/rubygems_spec.rb +14 -0
  333. data/tasks/parallel.rake +2 -2
  334. metadata +154 -21
  335. checksums.yaml +0 -7
  336. data/lib/puppet/module_tool/applications/generator.rb +0 -142
  337. data/lib/puppet/module_tool/skeleton.rb +0 -37
  338. data/lib/puppet/module_tool/skeleton/templates/generator/Modulefile.erb +0 -11
  339. data/lib/puppet/module_tool/skeleton/templates/generator/README.erb +0 -16
  340. data/lib/puppet/module_tool/tar/solaris.rb +0 -5
  341. data/spec/fixtures/unit/provider/service/systemd/list_units_services +0 -17
  342. data/spec/unit/module_tool/tar/solaris_spec.rb +0 -22
@@ -0,0 +1,162 @@
1
+ require 'spec_helper'
2
+ require 'semantic/dependency/graph'
3
+
4
+ describe Semantic::Dependency::Graph do
5
+ Graph = Semantic::Dependency::Graph
6
+ GraphNode = Semantic::Dependency::GraphNode
7
+ ModuleRelease = Semantic::Dependency::ModuleRelease
8
+ Version = Semantic::Version
9
+ VersionRange = Semantic::VersionRange
10
+
11
+ describe '#initialize' do
12
+ it 'can be called without arguments' do
13
+ expect { Graph.new }.to_not raise_error
14
+ end
15
+
16
+ it 'implements the GraphNode protocol' do
17
+ expect(Graph.new).to be_a GraphNode
18
+ end
19
+
20
+ it 'adds constraints for every key in the passed hash' do
21
+ graph = Graph.new('foo' => 1, 'bar' => 2, 'baz' => 3)
22
+ expect(graph.constraints.keys).to match_array %w[ foo bar baz ]
23
+ end
24
+
25
+ it 'adds the named dependencies for every key in the passed hash' do
26
+ graph = Graph.new('foo' => 1, 'bar' => 2, 'baz' => 3)
27
+ expect(graph.dependency_names).to match_array %w[ foo bar baz ]
28
+ end
29
+ end
30
+
31
+ describe '#add_constraint' do
32
+ let(:graph) { Graph.new }
33
+
34
+ it 'can create a new constraint on a module' do
35
+ expect(graph.constraints.keys).to be_empty
36
+
37
+ graph.add_constraint('test', 'module-name', 'nil') { }
38
+ expect(graph.constraints.keys).to match_array %w[ module-name ]
39
+ end
40
+
41
+ it 'permits multiple constraints against the same module name' do
42
+ expect(graph.constraints.keys).to be_empty
43
+
44
+ graph.add_constraint('test', 'module-name', 'nil') { }
45
+ graph.add_constraint('test', 'module-name', 'nil') { }
46
+
47
+ expect(graph.constraints.keys).to match_array %w[ module-name ]
48
+ end
49
+ end
50
+
51
+ describe '#satisfies_dependency?' do
52
+ it 'is not satisfied by modules it does not depend on' do
53
+ graph = Graph.new('foo' => VersionRange.parse('1.x'))
54
+ release = ModuleRelease.new(nil, 'bar', Version.parse('1.0.0'))
55
+
56
+ expect(graph.satisfies_dependency?(release)).to_not be true
57
+ end
58
+
59
+ it 'is not satisfied by modules that do not fulfill the constraint' do
60
+ graph = Graph.new('foo' => VersionRange.parse('1.x'))
61
+ release = ModuleRelease.new(nil, 'foo', Version.parse('2.3.1'))
62
+
63
+ expect(graph.satisfies_dependency?(release)).to_not be true
64
+ end
65
+
66
+ it 'is not satisfied by modules that do not fulfill all the constraints' do
67
+ graph = Graph.new('foo' => VersionRange.parse('1.x'))
68
+ graph.add_constraint('me', 'foo', '1.2.3') do |node|
69
+ node.version.to_s == '1.2.3'
70
+ end
71
+
72
+ release = ModuleRelease.new(nil, 'foo', Version.parse('1.2.1'))
73
+
74
+ expect(graph.satisfies_dependency?(release)).to_not be true
75
+ end
76
+
77
+ it 'is satisfied by modules that do fulfill all the constraints' do
78
+ graph = Graph.new('foo' => VersionRange.parse('1.x'))
79
+ graph.add_constraint('me', 'foo', '1.2.3') do |node|
80
+ node.version.to_s == '1.2.3'
81
+ end
82
+
83
+ release = ModuleRelease.new(nil, 'foo', Version.parse('1.2.3'))
84
+
85
+ expect(graph.satisfies_dependency?(release)).to be true
86
+ end
87
+ end
88
+
89
+ describe '#add_graph_constraint' do
90
+ let(:graph) { Graph.new }
91
+
92
+ it 'can create a new constraint on a graph' do
93
+ expect(graph.constraints.keys).to be_empty
94
+
95
+ graph.add_graph_constraint('test') { }
96
+ expect(graph.constraints.keys).to match_array [ :graph ]
97
+ end
98
+
99
+ it 'permits multiple graph constraints' do
100
+ expect(graph.constraints.keys).to be_empty
101
+
102
+ graph.add_graph_constraint('test') { }
103
+ graph.add_graph_constraint('test') { }
104
+
105
+ expect(graph.constraints.keys).to match_array [ :graph ]
106
+ end
107
+ end
108
+
109
+ describe '#satisfies_graph?' do
110
+ it 'returns false if the solution violates a graph constraint' do
111
+ graph = Graph.new
112
+ graph.add_graph_constraint('me') do |nodes|
113
+ nodes.none? { |node| node.name =~ /z/ }
114
+ end
115
+
116
+ releases = [
117
+ double('Node', :name => 'foo'),
118
+ double('Node', :name => 'bar'),
119
+ double('Node', :name => 'baz'),
120
+ ]
121
+
122
+ expect(graph.satisfies_graph?(releases)).to_not be true
123
+ end
124
+
125
+ it 'returns false if the solution violates any graph constraint' do
126
+ graph = Graph.new
127
+ graph.add_graph_constraint('me') do |nodes|
128
+ nodes.all? { |node| node.name.length < 5 }
129
+ end
130
+ graph.add_graph_constraint('me') do |nodes|
131
+ nodes.none? { |node| node.name =~ /z/ }
132
+ end
133
+
134
+ releases = [
135
+ double('Node', :name => 'foo'),
136
+ double('Node', :name => 'bar'),
137
+ double('Node', :name => 'bangerang'),
138
+ ]
139
+
140
+ expect(graph.satisfies_graph?(releases)).to_not be true
141
+ end
142
+
143
+ it 'returns true if the solution violates no graph constraints' do
144
+ graph = Graph.new
145
+ graph.add_graph_constraint('me') do |nodes|
146
+ nodes.all? { |node| node.name.length < 5 }
147
+ end
148
+ graph.add_graph_constraint('me') do |nodes|
149
+ nodes.none? { |node| node.name =~ /z/ }
150
+ end
151
+
152
+ releases = [
153
+ double('Node', :name => 'foo'),
154
+ double('Node', :name => 'bar'),
155
+ double('Node', :name => 'boom'),
156
+ ]
157
+
158
+ expect(graph.satisfies_graph?(releases)).to be true
159
+ end
160
+ end
161
+
162
+ end
@@ -0,0 +1,143 @@
1
+ require 'spec_helper'
2
+ require 'semantic/dependency/module_release'
3
+
4
+ describe Semantic::Dependency::ModuleRelease do
5
+ def source
6
+ @source ||= Semantic::Dependency::Source.new
7
+ end
8
+
9
+ def make_release(name, version, deps = {})
10
+ source.create_release(name, version, deps)
11
+ end
12
+
13
+ let(:no_dependencies) do
14
+ make_release('module', '1.2.3')
15
+ end
16
+
17
+ let(:one_dependency) do
18
+ make_release('module', '1.2.3', 'foo' => '1.0.0')
19
+ end
20
+
21
+ let(:three_dependencies) do
22
+ dependencies = { 'foo' => '1.0.0', 'bar' => '2.0.0', 'baz' => '3.0.0' }
23
+ make_release('module', '1.2.3', dependencies)
24
+ end
25
+
26
+ describe '#dependency_names' do
27
+
28
+ it "lists the names of all the release's dependencies" do
29
+ expect(no_dependencies.dependency_names).to match_array %w[]
30
+ expect(one_dependency.dependency_names).to match_array %w[foo]
31
+ expect(three_dependencies.dependency_names).to match_array %w[foo bar baz]
32
+ end
33
+
34
+ end
35
+
36
+ describe '#to_s' do
37
+
38
+ let(:name) { 'foobarbaz' }
39
+ let(:version) { '1.2.3' }
40
+
41
+ subject { make_release(name, version).to_s }
42
+
43
+ it { should =~ /#{name}/ }
44
+ it { should =~ /#{version}/ }
45
+
46
+ end
47
+
48
+ describe '#<<' do
49
+
50
+ it 'marks matching dependencies as satisfied' do
51
+ one_dependency << make_release('foo', '1.0.0')
52
+ expect(one_dependency).to be_satisfied
53
+ end
54
+
55
+ it 'does not mark mis-matching dependency names as satisfied' do
56
+ one_dependency << make_release('WAT', '1.0.0')
57
+ expect(one_dependency).to_not be_satisfied
58
+ end
59
+
60
+ it 'does not mark mis-matching dependency versions as satisfied' do
61
+ one_dependency << make_release('foo', '0.0.1')
62
+ expect(one_dependency).to_not be_satisfied
63
+ end
64
+
65
+ end
66
+
67
+ describe '#<=>' do
68
+
69
+ it 'considers releases with greater version numbers greater' do
70
+ expect(make_release('foo', '1.0.0')).to be > make_release('foo', '0.1.0')
71
+ end
72
+
73
+ it 'considers releases with lesser version numbers lesser' do
74
+ expect(make_release('foo', '0.1.0')).to be < make_release('foo', '1.0.0')
75
+ end
76
+
77
+ it 'orders releases with different names lexographically' do
78
+ expect(make_release('bar', '1.0.0')).to be < make_release('foo', '1.0.0')
79
+ end
80
+
81
+ it 'orders releases by name first' do
82
+ expect(make_release('bar', '2.0.0')).to be < make_release('foo', '1.0.0')
83
+ end
84
+
85
+ end
86
+
87
+ describe '#satisfied?' do
88
+
89
+ it 'returns true when there are no dependencies to satisfy' do
90
+ expect(no_dependencies).to be_satisfied
91
+ end
92
+
93
+ it 'returns false when no dependencies have been satisified' do
94
+ expect(one_dependency).to_not be_satisfied
95
+ end
96
+
97
+ it 'returns false when not all dependencies have been satisified' do
98
+ releases = %w[ 0.9.0 1.0.0 1.0.1 ].map { |ver| make_release('foo', ver) }
99
+ three_dependencies << releases
100
+
101
+ expect(three_dependencies).to_not be_satisfied
102
+ end
103
+
104
+ it 'returns false when not all dependency versions have been satisified' do
105
+ releases = %w[ 0.9.0 1.0.1 ].map { |ver| make_release('foo', ver) }
106
+ one_dependency << releases
107
+
108
+ expect(one_dependency).to_not be_satisfied
109
+ end
110
+
111
+ it 'returns true when all dependencies have been satisified' do
112
+ releases = %w[ 0.9.0 1.0.0 1.0.1 ].map { |ver| make_release('foo', ver) }
113
+ one_dependency << releases
114
+
115
+ expect(one_dependency).to be_satisfied
116
+ end
117
+
118
+ end
119
+
120
+ describe '#satisfies_dependency?' do
121
+
122
+ it 'returns false when there are no dependencies to satisfy' do
123
+ release = make_release('foo', '1.0.0')
124
+ expect(no_dependencies.satisfies_dependency?(release)).to_not be true
125
+ end
126
+
127
+ it 'returns false when the release does not match the dependency name' do
128
+ release = make_release('bar', '1.0.0')
129
+ expect(one_dependency.satisfies_dependency?(release)).to_not be true
130
+ end
131
+
132
+ it 'returns false when the release does not match the dependency version' do
133
+ release = make_release('foo', '4.0.0')
134
+ expect(one_dependency.satisfies_dependency?(release)).to_not be true
135
+ end
136
+
137
+ it 'returns true when the release matches the dependency' do
138
+ release = make_release('foo', '1.0.0')
139
+ expect(one_dependency.satisfies_dependency?(release)).to be true
140
+ end
141
+
142
+ end
143
+ end
@@ -0,0 +1,5 @@
1
+ require 'spec_helper'
2
+ require 'semantic/dependency/source'
3
+
4
+ describe Semantic::Dependency::Source do
5
+ end
@@ -0,0 +1,44 @@
1
+ require 'spec_helper'
2
+ require 'semantic/dependency/unsatisfiable_graph'
3
+
4
+ describe Semantic::Dependency::UnsatisfiableGraph do
5
+
6
+ let(:modules) { %w[ foo bar baz ] }
7
+ let(:graph) { double('Graph', :modules => modules) }
8
+ let(:instance) { described_class.new(graph) }
9
+
10
+ subject { instance }
11
+
12
+ describe '#message' do
13
+ subject { instance.message }
14
+
15
+ it { should match /#{instance.send(:sentence_from_list, modules)}/ }
16
+ end
17
+
18
+ describe '#sentence_from_list' do
19
+
20
+ subject { instance.send(:sentence_from_list, modules) }
21
+
22
+ context 'with a list of one item' do
23
+ let(:modules) { %w[ foo ] }
24
+ it { should eql 'foo' }
25
+ end
26
+
27
+ context 'with a list of two items' do
28
+ let(:modules) { %w[ foo bar ] }
29
+ it { should eql 'foo and bar' }
30
+ end
31
+
32
+ context 'with a list of three items' do
33
+ let(:modules) { %w[ foo bar baz ] }
34
+ it { should eql 'foo, bar, and baz' }
35
+ end
36
+
37
+ context 'with a list of more than three items' do
38
+ let(:modules) { %w[ foo bar baz quux ] }
39
+ it { should eql 'foo, bar, baz, and quux' }
40
+ end
41
+
42
+ end
43
+
44
+ end
@@ -0,0 +1,383 @@
1
+ require 'spec_helper'
2
+ require 'semantic/dependency'
3
+
4
+ describe Semantic::Dependency do
5
+ def create_release(source, name, version, deps = {})
6
+ Semantic::Dependency::ModuleRelease.new(
7
+ source,
8
+ name,
9
+ Semantic::Version.parse(version),
10
+ Hash[deps.map { |k, v| [k, Semantic::VersionRange.parse(v) ] }]
11
+ )
12
+ end
13
+
14
+ describe '.sources' do
15
+ it 'defaults to an empty list' do
16
+ expect(subject.sources).to be_empty
17
+ end
18
+
19
+ it 'is frozen' do
20
+ expect(subject.sources).to be_frozen
21
+ end
22
+
23
+ it 'can be modified by using #add_source' do
24
+ subject.add_source(Semantic::Dependency::Source.new)
25
+ expect(subject.sources).to_not be_empty
26
+ end
27
+
28
+ it 'can be emptied by using #clear_sources' do
29
+ subject.add_source(Semantic::Dependency::Source.new)
30
+ subject.clear_sources
31
+ expect(subject.sources).to be_empty
32
+ end
33
+ end
34
+
35
+ describe '.query' do
36
+ context 'without sources' do
37
+ it 'returns an unsatisfied ModuleRelease' do
38
+ expect(subject.query('module_name' => '1.0.0')).to_not be_satisfied
39
+ end
40
+ end
41
+
42
+ context 'with one source' do
43
+ let(:source) { double('Source') }
44
+
45
+ before { Semantic::Dependency.add_source(source) }
46
+
47
+ it 'queries the source for release information' do
48
+ source.should_receive(:fetch).with('module_name').and_return([])
49
+
50
+ Semantic::Dependency.query('module_name' => '1.0.0')
51
+ end
52
+
53
+ it 'queries the source for each dependency' do
54
+ source.should_receive(:fetch).with('module_name').and_return([
55
+ create_release(source, 'module_name', '1.0.0', 'bar' => '1.0.0')
56
+ ])
57
+ source.should_receive(:fetch).with('bar').and_return([])
58
+
59
+ Semantic::Dependency.query('module_name' => '1.0.0')
60
+ end
61
+
62
+ it 'queries the source for each dependency only once' do
63
+ source.should_receive(:fetch).with('module_name').and_return([
64
+ create_release(
65
+ source,
66
+ 'module_name',
67
+ '1.0.0',
68
+ 'bar' => '1.0.0', 'baz' => '0.0.2'
69
+ )
70
+ ])
71
+ source.should_receive(:fetch).with('bar').and_return([
72
+ create_release(source, 'bar', '1.0.0', 'baz' => '0.0.3')
73
+ ])
74
+ source.should_receive(:fetch).with('baz').once.and_return([])
75
+
76
+ Semantic::Dependency.query('module_name' => '1.0.0')
77
+ end
78
+
79
+ it 'returns a ModuleRelease with the requested dependencies' do
80
+ source.stub(:fetch).and_return([])
81
+
82
+ result = Semantic::Dependency.query('foo' => '1.0.0', 'bar' => '1.0.0')
83
+ expect(result.dependency_names).to match_array %w[ foo bar ]
84
+ end
85
+
86
+ it 'populates the returned ModuleRelease with related dependencies' do
87
+ source.stub(:fetch).and_return(
88
+ [ foo = create_release(source, 'foo', '1.0.0', 'bar' => '1.0.0') ],
89
+ [ bar = create_release(source, 'bar', '1.0.0') ]
90
+ )
91
+
92
+ result = Semantic::Dependency.query('foo' => '1.0.0', 'bar' => '1.0.0')
93
+ expect(result.dependencies['foo']).to eql SortedSet.new([ foo ])
94
+ expect(result.dependencies['bar']).to eql SortedSet.new([ bar ])
95
+ end
96
+
97
+ it 'populates all returned ModuleReleases with related dependencies' do
98
+ source.stub(:fetch).and_return(
99
+ [ foo = create_release(source, 'foo', '1.0.0', 'bar' => '1.0.0') ],
100
+ [ bar = create_release(source, 'bar', '1.0.0', 'baz' => '0.1.0') ],
101
+ [ baz = create_release(source, 'baz', '0.1.0', 'baz' => '1.0.0') ]
102
+ )
103
+
104
+ result = Semantic::Dependency.query('foo' => '1.0.0')
105
+ expect(result.dependencies['foo']).to eql SortedSet.new([ foo ])
106
+ expect(foo.dependencies['bar']).to eql SortedSet.new([ bar ])
107
+ expect(bar.dependencies['baz']).to eql SortedSet.new([ baz ])
108
+ end
109
+ end
110
+
111
+ context 'with multiple sources' do
112
+ let(:source1) { double('SourceOne') }
113
+ let(:source2) { double('SourceTwo') }
114
+ let(:source3) { double('SourceThree') }
115
+
116
+ before do
117
+ Semantic::Dependency.add_source(source1)
118
+ Semantic::Dependency.add_source(source2)
119
+ Semantic::Dependency.add_source(source3)
120
+ end
121
+
122
+ it 'queries each source in turn' do
123
+ source1.should_receive(:fetch).with('module_name').and_return([])
124
+ source2.should_receive(:fetch).with('module_name').and_return([])
125
+ source3.should_receive(:fetch).with('module_name').and_return([])
126
+
127
+ Semantic::Dependency.query('module_name' => '1.0.0')
128
+ end
129
+
130
+ it 'resolves all dependencies against all sources' do
131
+ source1.should_receive(:fetch).with('module_name').and_return([
132
+ create_release(source1, 'module_name', '1.0.0', 'bar' => '1.0.0')
133
+ ])
134
+ source2.should_receive(:fetch).with('module_name').and_return([])
135
+ source3.should_receive(:fetch).with('module_name').and_return([])
136
+
137
+ source1.should_receive(:fetch).with('bar').and_return([])
138
+ source2.should_receive(:fetch).with('bar').and_return([])
139
+ source3.should_receive(:fetch).with('bar').and_return([])
140
+
141
+ Semantic::Dependency.query('module_name' => '1.0.0')
142
+ end
143
+ end
144
+ end
145
+
146
+ describe '.resolve' do
147
+ def add_source_modules(name, versions, deps = {})
148
+ versions = Array(versions)
149
+ releases = versions.map { |ver| create_release(source, name, ver, deps) }
150
+ source.stub(:fetch).with(name).and_return(modules[name].concat(releases))
151
+ end
152
+
153
+ def subject(specs)
154
+ graph = Semantic::Dependency.query(specs)
155
+ yield graph if block_given?
156
+ expect(graph.dependencies).to_not be_empty
157
+ result = Semantic::Dependency.resolve(graph)
158
+ expect(graph.dependencies).to_not be_empty
159
+ result.map { |rel| [ rel.name, rel.version.to_s ] }
160
+ end
161
+
162
+ let(:modules) { Hash.new { |h,k| h[k] = [] }}
163
+ let(:source) { double('Source', :priority => 0) }
164
+
165
+ before { Semantic::Dependency.add_source(source) }
166
+
167
+ context 'for a module without dependencies' do
168
+ def foo(range)
169
+ subject('foo' => range).map { |x| x.last }
170
+ end
171
+
172
+ it 'returns the greatest release matching the version range' do
173
+ add_source_modules('foo', %w[ 0.9.0 1.0.0 1.1.0 2.0.0 ])
174
+
175
+ expect(foo('1.x')).to eql %w[ 1.1.0 ]
176
+ end
177
+
178
+ context 'when the query includes both stable and prerelease versions' do
179
+ it 'returns the greatest stable release matching the range' do
180
+ add_source_modules('foo', %w[ 0.9.0 1.0.0 1.1.0 1.2.0-pre 2.0.0 ])
181
+
182
+ expect(foo('1.x')).to eql %w[ 1.1.0 ]
183
+ end
184
+ end
185
+
186
+ context 'when the query omits all stable versions' do
187
+ it 'returns the greatest prerelease version matching the range' do
188
+ add_source_modules('foo', %w[ 1.0.0 1.1.0-a 1.1.0-b 2.0.0 ])
189
+
190
+ expect(foo('1.1.x')).to eql %w[ 1.1.0-b ]
191
+ expect(foo('1.1.0-a')).to eql %w[ 1.1.0-a ]
192
+ end
193
+ end
194
+
195
+ context 'when the query omits all versions' do
196
+ it 'fails with an appropriate message' do
197
+ add_source_modules('foo', %w[ 1.0.0 1.1.0-a 1.1.0 ])
198
+
199
+ with_message = /Could not find satisfying releases/
200
+ expect { foo('2.x') }.to raise_exception with_message
201
+ expect { foo('2.x') }.to raise_exception /\bfoo\b/
202
+ end
203
+ end
204
+ end
205
+
206
+ context 'for a module with dependencies' do
207
+ def foo(range)
208
+ subject('foo' => range)
209
+ end
210
+
211
+ it 'returns the greatest releases matching the dependency range' do
212
+ add_source_modules('foo', '1.1.0', 'bar' => '1.x')
213
+ add_source_modules('bar', %w[ 0.9.0 1.0.0 1.1.0 1.2.0 2.0.0 ])
214
+
215
+ expect(foo('1.1.0')).to include %w[ foo 1.1.0 ], %w[ bar 1.2.0 ]
216
+ end
217
+
218
+ context 'when the dependency has both stable and prerelease versions' do
219
+ it 'returns the greatest stable release matching the range' do
220
+ add_source_modules('foo', '1.1.0', 'bar' => '1.x')
221
+ add_source_modules('bar', %w[ 0.9.0 1.0.0 1.1.0 1.2.0-pre 2.0.0 ])
222
+
223
+ expect(foo('1.1.0')).to include %w[ foo 1.1.0 ], %w[ bar 1.1.0 ]
224
+ end
225
+ end
226
+
227
+ context 'when the dependency has no stable versions' do
228
+ it 'returns the greatest prerelease version matching the range' do
229
+ add_source_modules('foo', '1.1.0', 'bar' => '1.1.x')
230
+ add_source_modules('foo', '1.1.1', 'bar' => '1.1.0-a')
231
+ add_source_modules('bar', %w[ 1.0.0 1.1.0-a 1.1.0-b 2.0.0 ])
232
+
233
+ expect(foo('1.1.0')).to include %w[ foo 1.1.0 ], %w[ bar 1.1.0-b ]
234
+ expect(foo('1.1.1')).to include %w[ foo 1.1.1 ], %w[ bar 1.1.0-a ]
235
+ end
236
+ end
237
+
238
+ context 'when the dependency cannot be satisfied' do
239
+ it 'fails with an appropriate message' do
240
+ add_source_modules('foo', %w[ 1.1.0 ], 'bar' => '1.x')
241
+ add_source_modules('bar', %w[ 0.0.1 0.1.0-a 0.1.0 ])
242
+
243
+ with_message = /Could not find satisfying releases/
244
+ expect { foo('1.1.0') }.to raise_exception with_message
245
+ expect { foo('1.1.0') }.to raise_exception /\bfoo\b/
246
+ end
247
+ end
248
+ end
249
+
250
+ context 'for a module with competing dependencies' do
251
+ def foo(range)
252
+ subject('foo' => range)
253
+ end
254
+
255
+ context 'that overlap' do
256
+ it 'returns the greatest release satisfying all dependencies' do
257
+ add_source_modules('foo', '1.1.0', 'bar' => '1.0.0', 'baz' => '1.0.0')
258
+ add_source_modules('bar', '1.0.0', 'quxx' => '1.x')
259
+ add_source_modules('baz', '1.0.0', 'quxx' => '1.1.x')
260
+ add_source_modules('quxx', %w[ 0.9.0 1.0.0 1.1.0 1.1.1 1.2.0 2.0.0 ])
261
+
262
+ expect(foo('1.1.0')).to_not include %w[ quxx 1.2.0 ]
263
+ expect(foo('1.1.0')).to include %w[ quxx 1.1.1 ]
264
+ end
265
+ end
266
+
267
+ context 'that do not overlap' do
268
+ it 'fails with an appropriate message' do
269
+ add_source_modules('foo','1.1.0', 'bar' => '1.0.0', 'baz' => '1.0.0')
270
+ add_source_modules('bar','1.0.0', 'quxx' => '1.x')
271
+ add_source_modules('baz','1.0.0', 'quxx' => '2.x')
272
+ add_source_modules('quxx', %w[ 0.9.0 1.0.0 1.1.0 1.1.1 1.2.0 2.0.0 ])
273
+
274
+ with_message = /Could not find satisfying releases/
275
+ expect { foo('1.1.0') }.to raise_exception with_message
276
+ expect { foo('1.1.0') }.to raise_exception /\bfoo\b/
277
+ end
278
+ end
279
+ end
280
+
281
+ context 'for a module with circular dependencies' do
282
+ def foo(range)
283
+ subject('foo' => range)
284
+ end
285
+
286
+ context 'that can be resolved' do
287
+ it 'terminates' do
288
+ add_source_modules('foo', '1.1.0', 'foo' => '1.x')
289
+
290
+ expect(foo('1.1.0')).to include %w[ foo 1.1.0 ]
291
+ end
292
+ end
293
+
294
+ context 'that cannot be resolved' do
295
+ it 'fails with an appropriate message' do
296
+ add_source_modules('foo', '1.1.0', 'foo' => '1.0.0')
297
+
298
+ with_message = /Could not find satisfying releases/
299
+ expect { foo('1.1.0') }.to raise_exception with_message
300
+ expect { foo('1.1.0') }.to raise_exception /\bfoo\b/
301
+ end
302
+ end
303
+ end
304
+
305
+ context 'for a module with dependencies' do
306
+ context 'that violate module constraints on the graph' do
307
+ def foo(range)
308
+ subject('foo' => range) do |graph|
309
+ graph.add_constraint('no downgrade', 'bar', '> 3.0.0') do |node|
310
+ Semantic::VersionRange.parse('> 3.0.0') === node.version
311
+ end
312
+ end
313
+ end
314
+
315
+ context 'that can be resolved' do
316
+ it 'terminates' do
317
+ add_source_modules('foo', '1.1.0', 'bar' => '1.x')
318
+ add_source_modules('foo', '1.2.0', 'bar' => '>= 2.0.0')
319
+ add_source_modules('bar', '1.0.0')
320
+ add_source_modules('bar', '2.0.0', 'baz' => '>= 1.0.0')
321
+ add_source_modules('bar', '3.0.0')
322
+ add_source_modules('bar', '3.0.1')
323
+ add_source_modules('baz', '1.0.0')
324
+
325
+ expect(foo('1.x')).to include %w[ foo 1.2.0 ], %w[ bar 3.0.1 ]
326
+ end
327
+ end
328
+
329
+ context 'that cannot be resolved' do
330
+ it 'fails with an appropriate message' do
331
+ add_source_modules('foo', '1.1.0', 'bar' => '1.x')
332
+ add_source_modules('foo', '1.2.0', 'bar' => '2.x')
333
+ add_source_modules('bar', '1.0.0', 'baz' => '1.x')
334
+ add_source_modules('bar', '2.0.0', 'baz' => '1.x')
335
+ add_source_modules('baz', '1.0.0')
336
+ add_source_modules('baz', '3.0.0')
337
+ add_source_modules('baz', '3.0.1')
338
+
339
+ with_message = /Could not find satisfying releases/
340
+ expect { foo('1.x') }.to raise_exception with_message
341
+ expect { foo('1.x') }.to raise_exception /\bfoo\b/
342
+ end
343
+ end
344
+ end
345
+ end
346
+
347
+ context 'that violate graph constraints' do
348
+ def foo(range)
349
+ subject('foo' => range) do |graph|
350
+ graph.add_graph_constraint('uniqueness') do |nodes|
351
+ nodes.none? { |node| node.name =~ /z/ }
352
+ end
353
+ end
354
+ end
355
+
356
+ context 'that can be resolved' do
357
+ it 'terminates' do
358
+ add_source_modules('foo', '1.1.0', 'bar' => '1.x')
359
+ add_source_modules('foo', '1.2.0', 'bar' => '2.x')
360
+ add_source_modules('bar', '1.0.0')
361
+ add_source_modules('bar', '2.0.0', 'baz' => '1.0.0')
362
+ add_source_modules('baz', '1.0.0')
363
+
364
+ expect(foo('1.x')).to include %w[ foo 1.1.0 ], %w[ bar 1.0.0 ]
365
+ end
366
+ end
367
+
368
+ context 'that cannot be resolved' do
369
+ it 'fails with an appropriate message' do
370
+ add_source_modules('foo', '1.1.0', 'bar' => '1.x')
371
+ add_source_modules('foo', '1.2.0', 'bar' => '2.x')
372
+ add_source_modules('bar', '1.0.0', 'baz' => '1.0.0')
373
+ add_source_modules('bar', '2.0.0', 'baz' => '1.0.0')
374
+ add_source_modules('baz', '1.0.0')
375
+
376
+ with_message = /Could not find satisfying releases/
377
+ expect { foo('1.1.0') }.to raise_exception with_message
378
+ expect { foo('1.1.0') }.to raise_exception /\bfoo\b/
379
+ end
380
+ end
381
+ end
382
+ end
383
+ end