chef 12.4.3-universal-mingw32 → 12.5.1-universal-mingw32

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (320) hide show
  1. checksums.yaml +4 -4
  2. data/CONTRIBUTING.md +21 -25
  3. data/Gemfile +46 -0
  4. data/README.md +4 -4
  5. data/Rakefile +4 -110
  6. data/bin/chef-service-manager +3 -1
  7. data/distro/common/html/knife_cookbook_site.html +18 -18
  8. data/distro/common/man/man1/knife-cookbook-site.1 +11 -11
  9. data/lib/chef.rb +1 -1
  10. data/lib/chef/application.rb +1 -1
  11. data/lib/chef/application/apply.rb +19 -1
  12. data/lib/chef/application/client.rb +11 -5
  13. data/lib/chef/application/knife.rb +2 -2
  14. data/lib/chef/application/solo.rb +1 -1
  15. data/lib/chef/application/windows_service_manager.rb +19 -12
  16. data/lib/chef/chef_class.rb +46 -0
  17. data/lib/chef/chef_fs/config.rb +22 -24
  18. data/lib/chef/chef_fs/data_handler/client_data_handler.rb +3 -1
  19. data/lib/chef/chef_fs/file_pattern.rb +4 -15
  20. data/lib/chef/chef_fs/file_system/acl_dir.rb +3 -4
  21. data/lib/chef/chef_fs/file_system/acls_dir.rb +5 -1
  22. data/lib/chef/chef_fs/file_system/base_fs_dir.rb +0 -5
  23. data/lib/chef/chef_fs/file_system/base_fs_object.rb +5 -2
  24. data/lib/chef/chef_fs/file_system/chef_repository_file_system_cookbook_dir.rb +2 -9
  25. data/lib/chef/chef_fs/file_system/chef_repository_file_system_cookbook_entry.rb +2 -9
  26. data/lib/chef/chef_fs/file_system/chef_repository_file_system_cookbooks_dir.rb +10 -17
  27. data/lib/chef/chef_fs/file_system/chef_repository_file_system_entry.rb +1 -12
  28. data/lib/chef/chef_fs/file_system/chef_repository_file_system_root_dir.rb +15 -11
  29. data/lib/chef/chef_fs/file_system/chef_server_root_dir.rb +8 -2
  30. data/lib/chef/chef_fs/file_system/cookbook_dir.rb +4 -4
  31. data/lib/chef/chef_fs/file_system/cookbooks_acl_dir.rb +1 -1
  32. data/lib/chef/chef_fs/file_system/cookbooks_dir.rb +3 -11
  33. data/lib/chef/chef_fs/file_system/data_bags_dir.rb +3 -5
  34. data/lib/chef/chef_fs/file_system/environments_dir.rb +1 -1
  35. data/lib/chef/chef_fs/file_system/file_system_entry.rb +7 -4
  36. data/lib/chef/chef_fs/file_system/memory_dir.rb +2 -3
  37. data/lib/chef/chef_fs/file_system/multiplexed_dir.rb +15 -0
  38. data/lib/chef/chef_fs/file_system/nodes_dir.rb +1 -1
  39. data/lib/chef/chef_fs/file_system/organization_members_entry.rb +2 -2
  40. data/lib/chef/chef_fs/file_system/rest_list_dir.rb +4 -9
  41. data/lib/chef/chef_fs/knife.rb +35 -7
  42. data/lib/chef/chef_fs/path_utils.rb +65 -34
  43. data/lib/chef/client.rb +2 -3
  44. data/lib/chef/config.rb +34 -2
  45. data/lib/chef/{mixin/wstring.rb → constants.rb} +9 -13
  46. data/lib/chef/cookbook/metadata.rb +25 -3
  47. data/lib/chef/cookbook/synchronizer.rb +1 -1
  48. data/lib/chef/cookbook_site_streaming_uploader.rb +1 -1
  49. data/lib/chef/cookbook_version.rb +3 -3
  50. data/lib/chef/delayed_evaluator.rb +21 -0
  51. data/lib/chef/deprecation/mixin/template.rb +1 -2
  52. data/lib/chef/deprecation/provider/cookbook_file.rb +1 -1
  53. data/lib/chef/deprecation/provider/file.rb +1 -1
  54. data/lib/chef/deprecation/provider/remote_directory.rb +52 -0
  55. data/lib/chef/deprecation/provider/remote_file.rb +1 -2
  56. data/lib/chef/deprecation/provider/template.rb +1 -1
  57. data/lib/chef/deprecation/warnings.rb +3 -4
  58. data/lib/chef/dsl/reboot_pending.rb +3 -2
  59. data/lib/chef/dsl/recipe.rb +26 -7
  60. data/lib/chef/dsl/resources.rb +2 -2
  61. data/lib/chef/event_dispatch/base.rb +51 -22
  62. data/lib/chef/event_dispatch/dispatcher.rb +21 -6
  63. data/lib/chef/event_dispatch/dsl.rb +64 -0
  64. data/lib/chef/exceptions.rb +28 -1
  65. data/lib/chef/file_content_management/tempfile.rb +1 -1
  66. data/lib/chef/formatters/base.rb +3 -0
  67. data/lib/chef/formatters/doc.rb +56 -6
  68. data/lib/chef/formatters/error_inspectors/compile_error_inspector.rb +36 -0
  69. data/lib/chef/formatters/minimal.rb +2 -2
  70. data/lib/chef/guard_interpreter/resource_guard_interpreter.rb +3 -1
  71. data/lib/chef/http/http_request.rb +1 -1
  72. data/lib/chef/knife.rb +35 -55
  73. data/lib/chef/knife/bootstrap.rb +41 -0
  74. data/lib/chef/knife/bootstrap/chef_vault_handler.rb +1 -0
  75. data/lib/chef/knife/bootstrap/client_builder.rb +16 -0
  76. data/lib/chef/knife/bootstrap/templates/README.md +3 -4
  77. data/lib/chef/knife/bootstrap/templates/chef-full.erb +1 -1
  78. data/lib/chef/knife/cookbook_create.rb +1 -1
  79. data/lib/chef/knife/cookbook_site_download.rb +1 -1
  80. data/lib/chef/knife/cookbook_site_install.rb +1 -1
  81. data/lib/chef/knife/cookbook_site_share.rb +6 -6
  82. data/lib/chef/knife/cookbook_site_unshare.rb +2 -2
  83. data/lib/chef/knife/core/bootstrap_context.rb +12 -4
  84. data/lib/chef/knife/core/custom_manifest_loader.rb +69 -0
  85. data/lib/chef/knife/core/gem_glob_loader.rb +138 -0
  86. data/lib/chef/knife/core/hashed_command_loader.rb +80 -0
  87. data/lib/chef/knife/core/node_presenter.rb +24 -1
  88. data/lib/chef/knife/core/object_loader.rb +1 -0
  89. data/lib/chef/knife/core/subcommand_loader.rb +131 -146
  90. data/lib/chef/knife/node_run_list_remove.rb +12 -1
  91. data/lib/chef/knife/null.rb +10 -0
  92. data/lib/chef/knife/rehash.rb +62 -0
  93. data/lib/chef/knife/search.rb +3 -3
  94. data/lib/chef/knife/ssh.rb +52 -30
  95. data/lib/chef/knife/ssl_check.rb +3 -2
  96. data/lib/chef/knife/user_edit.rb +1 -2
  97. data/lib/chef/local_mode.rb +5 -0
  98. data/lib/chef/log.rb +5 -1
  99. data/lib/chef/mixin/deprecation.rb +8 -8
  100. data/lib/chef/mixin/params_validate.rb +362 -135
  101. data/lib/chef/mixin/template.rb +48 -0
  102. data/lib/chef/mixin/which.rb +1 -1
  103. data/lib/chef/mixin/wide_string.rb +72 -0
  104. data/lib/chef/mixin/windows_architecture_helper.rb +15 -39
  105. data/lib/chef/mixin/windows_env_helper.rb +4 -1
  106. data/lib/chef/monkey_patches/webrick-utils.rb +51 -0
  107. data/lib/chef/monkey_patches/win32/registry.rb +72 -0
  108. data/lib/chef/node.rb +116 -3
  109. data/lib/chef/node_map.rb +2 -2
  110. data/lib/chef/platform/handler_map.rb +0 -5
  111. data/lib/chef/platform/provider_mapping.rb +5 -6
  112. data/lib/chef/platform/query_helpers.rb +46 -4
  113. data/lib/chef/platform/rebooter.rb +1 -1
  114. data/lib/chef/platform/service_helpers.rb +30 -32
  115. data/lib/chef/policy_builder.rb +1 -8
  116. data/lib/chef/policy_builder/dynamic.rb +186 -0
  117. data/lib/chef/policy_builder/expand_node_object.rb +30 -15
  118. data/lib/chef/policy_builder/policyfile.rb +155 -18
  119. data/lib/chef/property.rb +568 -0
  120. data/lib/chef/provider.rb +222 -13
  121. data/lib/chef/provider/batch.rb +8 -0
  122. data/lib/chef/provider/deploy.rb +5 -7
  123. data/lib/chef/provider/directory.rb +14 -2
  124. data/lib/chef/provider/dsc_resource.rb +5 -9
  125. data/lib/chef/provider/group/pw.rb +1 -1
  126. data/lib/chef/provider/ifconfig.rb +2 -2
  127. data/lib/chef/provider/lwrp_base.rb +1 -75
  128. data/lib/chef/provider/mount.rb +7 -3
  129. data/lib/chef/provider/package.rb +1 -1
  130. data/lib/chef/provider/package/dpkg.rb +5 -11
  131. data/lib/chef/provider/package/rpm.rb +2 -2
  132. data/lib/chef/provider/package/rubygems.rb +1 -1
  133. data/lib/chef/provider/package/windows/msi.rb +2 -2
  134. data/lib/chef/provider/package/yum.rb +17 -5
  135. data/lib/chef/provider/powershell_script.rb +59 -23
  136. data/lib/chef/provider/registry_key.rb +5 -5
  137. data/lib/chef/provider/remote_directory.rb +190 -102
  138. data/lib/chef/provider/service.rb +12 -2
  139. data/lib/chef/provider/service/aix.rb +1 -1
  140. data/lib/chef/provider/service/debian.rb +3 -5
  141. data/lib/chef/provider/service/freebsd.rb +1 -1
  142. data/lib/chef/provider/service/gentoo.rb +3 -3
  143. data/lib/chef/provider/service/init.rb +3 -3
  144. data/lib/chef/provider/service/insserv.rb +2 -4
  145. data/lib/chef/provider/service/invokercd.rb +2 -4
  146. data/lib/chef/provider/service/macosx.rb +5 -1
  147. data/lib/chef/provider/service/openbsd.rb +2 -1
  148. data/lib/chef/provider/service/redhat.rb +52 -16
  149. data/lib/chef/provider/service/simple.rb +2 -2
  150. data/lib/chef/provider/service/systemd.rb +3 -5
  151. data/lib/chef/provider/service/upstart.rb +4 -6
  152. data/lib/chef/provider/subversion.rb +13 -7
  153. data/lib/chef/provider/template/content.rb +16 -6
  154. data/lib/chef/provider/user/solaris.rb +32 -4
  155. data/lib/chef/provider/windows_script.rb +3 -5
  156. data/lib/chef/provider_resolver.rb +2 -2
  157. data/lib/chef/recipe.rb +1 -8
  158. data/lib/chef/resource.rb +563 -90
  159. data/lib/chef/resource/action_class.rb +83 -0
  160. data/lib/chef/resource/chef_gem.rb +3 -3
  161. data/lib/chef/resource/deploy.rb +8 -2
  162. data/lib/chef/resource/dsc_script.rb +2 -0
  163. data/lib/chef/resource/file/verification.rb +7 -1
  164. data/lib/chef/resource/lwrp_base.rb +1 -7
  165. data/lib/chef/resource/registry_key.rb +1 -1
  166. data/lib/chef/resource/service.rb +10 -2
  167. data/lib/chef/resource/subversion.rb +5 -0
  168. data/lib/chef/resource/windows_script.rb +6 -2
  169. data/lib/chef/resource/yum_package.rb +10 -1
  170. data/lib/chef/resource_resolver.rb +3 -3
  171. data/lib/chef/run_context.rb +402 -83
  172. data/lib/chef/run_list/versioned_recipe_list.rb +15 -0
  173. data/lib/chef/run_lock.rb +30 -21
  174. data/lib/chef/util/powershell/ps_credential.rb +4 -0
  175. data/lib/chef/util/windows.rb +0 -32
  176. data/lib/chef/util/windows/net_group.rb +85 -106
  177. data/lib/chef/util/windows/net_use.rb +35 -71
  178. data/lib/chef/util/windows/net_user.rb +0 -1
  179. data/lib/chef/util/windows/volume.rb +19 -19
  180. data/lib/chef/version.rb +3 -3
  181. data/lib/chef/win32/api.rb +1 -0
  182. data/lib/chef/win32/api/file.rb +20 -0
  183. data/lib/chef/win32/api/net.rb +163 -43
  184. data/lib/chef/win32/api/registry.rb +51 -0
  185. data/lib/chef/win32/api/system.rb +23 -0
  186. data/lib/chef/win32/api/unicode.rb +0 -43
  187. data/lib/chef/win32/crypto.rb +2 -1
  188. data/lib/chef/win32/file.rb +28 -3
  189. data/lib/chef/win32/mutex.rb +1 -2
  190. data/lib/chef/win32/net.rb +162 -8
  191. data/lib/chef/win32/process.rb +13 -0
  192. data/lib/chef/win32/registry.rb +35 -30
  193. data/lib/chef/win32/security.rb +1 -1
  194. data/lib/chef/win32/security/token.rb +1 -1
  195. data/lib/chef/win32/system.rb +62 -0
  196. data/lib/chef/win32/unicode.rb +7 -2
  197. data/lib/chef/win32/version.rb +0 -4
  198. data/lib/chef/workstation_config_loader.rb +3 -158
  199. data/spec/data/cookbooks/openldap/templates/default/helpers.erb +14 -0
  200. data/spec/data/cookbooks/openldap/templates/default/nested_openldap_partials.erb +1 -0
  201. data/spec/data/cookbooks/openldap/templates/default/nested_partial.erb +1 -0
  202. data/spec/data/dsc_lcm.pfx +0 -0
  203. data/spec/data/run_context/cookbooks/include/recipes/default.rb +24 -0
  204. data/spec/data/run_context/cookbooks/include/recipes/includee.rb +3 -0
  205. data/spec/functional/dsl/reboot_pending_spec.rb +33 -43
  206. data/spec/functional/knife/cookbook_delete_spec.rb +17 -7
  207. data/spec/functional/knife/ssh_spec.rb +16 -0
  208. data/spec/functional/rebooter_spec.rb +1 -1
  209. data/spec/functional/resource/deploy_revision_spec.rb +1 -1
  210. data/spec/functional/resource/dsc_resource_spec.rb +2 -0
  211. data/spec/functional/resource/dsc_script_spec.rb +91 -2
  212. data/spec/functional/resource/group_spec.rb +67 -44
  213. data/spec/functional/resource/{powershell_spec.rb → powershell_script_spec.rb} +107 -18
  214. data/spec/functional/resource/windows_service_spec.rb +1 -1
  215. data/spec/functional/run_lock_spec.rb +368 -189
  216. data/spec/functional/win32/{registry_helper_spec.rb → registry_spec.rb} +16 -23
  217. data/spec/functional/win32/service_manager_spec.rb +2 -2
  218. data/spec/integration/client/client_spec.rb +51 -0
  219. data/spec/integration/knife/chef_repo_path_spec.rb +13 -11
  220. data/spec/integration/knife/download_spec.rb +4 -0
  221. data/spec/integration/knife/list_spec.rb +8 -0
  222. data/spec/integration/knife/upload_spec.rb +1 -1
  223. data/spec/integration/recipes/recipe_dsl_spec.rb +1 -16
  224. data/spec/integration/recipes/remote_directory.rb +74 -0
  225. data/spec/integration/recipes/resource_action_spec.rb +363 -0
  226. data/spec/integration/recipes/resource_converge_if_changed_spec.rb +423 -0
  227. data/spec/integration/recipes/resource_load_spec.rb +206 -0
  228. data/spec/spec_helper.rb +9 -0
  229. data/spec/support/platform_helpers.rb +13 -0
  230. data/spec/support/shared/context/win32.rb +34 -0
  231. data/spec/support/shared/functional/win32_service.rb +2 -1
  232. data/spec/support/shared/functional/windows_script.rb +63 -26
  233. data/spec/support/shared/unit/mock_shellout.rb +46 -0
  234. data/spec/support/shared/unit/provider/file.rb +10 -4
  235. data/spec/unit/application/client_spec.rb +16 -3
  236. data/spec/unit/application/knife_spec.rb +2 -2
  237. data/spec/unit/application/solo_spec.rb +4 -3
  238. data/spec/unit/chef_class_spec.rb +23 -4
  239. data/spec/unit/chef_fs/path_util_spec.rb +108 -0
  240. data/spec/unit/client_spec.rb +6 -1
  241. data/spec/unit/config_spec.rb +31 -0
  242. data/spec/unit/cookbook/metadata_spec.rb +23 -3
  243. data/spec/unit/cookbook/syntax_check_spec.rb +3 -0
  244. data/spec/unit/deprecation_spec.rb +3 -6
  245. data/spec/unit/dsl/reboot_pending_spec.rb +12 -6
  246. data/spec/unit/event_dispatch/dispatcher_spec.rb +65 -3
  247. data/spec/unit/event_dispatch/dsl_spec.rb +83 -0
  248. data/spec/unit/formatters/doc_spec.rb +32 -0
  249. data/spec/unit/formatters/error_inspectors/compile_error_inspector_spec.rb +26 -0
  250. data/spec/unit/json_compat_spec.rb +4 -3
  251. data/spec/unit/knife/bootstrap/client_builder_spec.rb +27 -0
  252. data/spec/unit/knife/bootstrap_spec.rb +55 -3
  253. data/spec/unit/knife/cookbook_site_share_spec.rb +3 -3
  254. data/spec/unit/knife/core/bootstrap_context_spec.rb +21 -4
  255. data/spec/unit/knife/core/custom_manifest_loader_spec.rb +41 -0
  256. data/spec/unit/knife/core/gem_glob_loader_spec.rb +210 -0
  257. data/spec/unit/knife/core/hashed_command_loader_spec.rb +93 -0
  258. data/spec/unit/knife/core/subcommand_loader_spec.rb +16 -192
  259. data/spec/unit/knife/node_run_list_remove_spec.rb +17 -0
  260. data/spec/unit/knife/ssl_check_spec.rb +4 -0
  261. data/spec/unit/mixin/enforce_ownership_and_permissions_spec.rb +10 -10
  262. data/spec/unit/mixin/params_validate_spec.rb +4 -2
  263. data/spec/unit/mixin/template_spec.rb +5 -1
  264. data/spec/unit/mixin/windows_architecture_helper_spec.rb +13 -8
  265. data/spec/unit/node_spec.rb +220 -0
  266. data/spec/unit/platform/query_helpers_spec.rb +146 -3
  267. data/spec/unit/policy_builder/dynamic_spec.rb +275 -0
  268. data/spec/unit/policy_builder/expand_node_object_spec.rb +37 -38
  269. data/spec/unit/policy_builder/policyfile_spec.rb +260 -46
  270. data/spec/unit/property/state_spec.rb +506 -0
  271. data/spec/unit/property/validation_spec.rb +663 -0
  272. data/spec/unit/property_spec.rb +1094 -0
  273. data/spec/unit/provider/deploy_spec.rb +5 -5
  274. data/spec/unit/provider/directory_spec.rb +35 -0
  275. data/spec/unit/provider/dsc_resource_spec.rb +3 -10
  276. data/spec/unit/provider/ifconfig_spec.rb +22 -2
  277. data/spec/unit/provider/mount/aix_spec.rb +2 -1
  278. data/spec/unit/provider/mount/mount_spec.rb +6 -0
  279. data/spec/unit/provider/mount/windows_spec.rb +14 -0
  280. data/spec/unit/provider/mount_spec.rb +12 -1
  281. data/spec/unit/provider/package/dpkg_spec.rb +8 -1
  282. data/spec/unit/provider/package/rpm_spec.rb +18 -1
  283. data/spec/unit/provider/package/rubygems_spec.rb +18 -0
  284. data/spec/unit/provider/package/yum_spec.rb +97 -24
  285. data/spec/unit/provider/powershell_script_spec.rb +106 -0
  286. data/spec/unit/provider/registry_key_spec.rb +12 -0
  287. data/spec/unit/provider/remote_directory_spec.rb +1 -2
  288. data/spec/unit/provider/service/aix_service_spec.rb +3 -3
  289. data/spec/unit/provider/service/gentoo_service_spec.rb +4 -4
  290. data/spec/unit/provider/service/macosx_spec.rb +4 -4
  291. data/spec/unit/provider/service/openbsd_service_spec.rb +10 -8
  292. data/spec/unit/provider/service/redhat_spec.rb +88 -8
  293. data/spec/unit/provider/service/upstart_service_spec.rb +11 -7
  294. data/spec/unit/provider/service/windows_spec.rb +211 -200
  295. data/spec/unit/provider/subversion_spec.rb +50 -31
  296. data/spec/unit/provider/template/content_spec.rb +93 -2
  297. data/spec/unit/provider/user/solaris_spec.rb +66 -9
  298. data/spec/unit/provider_resolver_spec.rb +707 -650
  299. data/spec/unit/provider_spec.rb +1 -3
  300. data/spec/unit/recipe_spec.rb +0 -4
  301. data/spec/unit/resource/deploy_spec.rb +7 -1
  302. data/spec/unit/resource/dsc_script_spec.rb +4 -0
  303. data/spec/unit/resource/file/verification_spec.rb +33 -5
  304. data/spec/unit/resource/{powershell_spec.rb → powershell_script_spec.rb} +17 -13
  305. data/spec/unit/resource/service_spec.rb +4 -4
  306. data/spec/unit/resource/subversion_spec.rb +4 -0
  307. data/spec/unit/resource/yum_package_spec.rb +10 -1
  308. data/spec/unit/resource_spec.rb +2 -2
  309. data/spec/unit/run_context/child_run_context_spec.rb +133 -0
  310. data/spec/unit/run_context_spec.rb +7 -0
  311. data/spec/unit/run_list/versioned_recipe_list_spec.rb +5 -0
  312. data/spec/unit/win32/registry_spec.rb +394 -0
  313. data/tasks/external_tests.rb +47 -23
  314. data/tasks/maintainers.rb +155 -14
  315. metadata +64 -53
  316. data/lib/chef/knife/bootstrap/templates/archlinux-gems.erb +0 -76
  317. data/lib/chef/knife/bootstrap/templates/chef-aix.erb +0 -72
  318. data/spec/unit/provider/powershell_spec.rb +0 -80
  319. data/spec/unit/registry_helper_spec.rb +0 -376
  320. data/spec/unit/workstation_config_loader_spec.rb +0 -283
@@ -0,0 +1,1094 @@
1
+ require 'support/shared/integration/integration_helper'
2
+
3
+ describe "Chef::Resource.property" do
4
+ include IntegrationSupport
5
+
6
+ module Namer
7
+ @i = 0
8
+ def self.next_resource_name
9
+ "chef_resource_property_spec_#{@i += 1}"
10
+ end
11
+ def self.reset_index
12
+ @current_index = 0
13
+ end
14
+ def self.current_index
15
+ @current_index
16
+ end
17
+ def self.next_index
18
+ @current_index += 1
19
+ end
20
+ end
21
+
22
+ def lazy(&block)
23
+ Chef::DelayedEvaluator.new(&block)
24
+ end
25
+
26
+ before do
27
+ Namer.reset_index
28
+ end
29
+
30
+ def self.new_resource_name
31
+ Namer.next_resource_name
32
+ end
33
+
34
+ let(:resource_class) do
35
+ new_resource_name = self.class.new_resource_name
36
+ Class.new(Chef::Resource) do
37
+ resource_name new_resource_name
38
+ def next_index
39
+ Namer.next_index
40
+ end
41
+ end
42
+ end
43
+
44
+ let(:resource) do
45
+ resource_class.new("blah")
46
+ end
47
+
48
+ def self.english_join(values)
49
+ return '<nothing>' if values.size == 0
50
+ return values[0].inspect if values.size == 1
51
+ "#{values[0..-2].map { |v| v.inspect }.join(", ")} and #{values[-1].inspect}"
52
+ end
53
+
54
+ def self.with_property(*properties, &block)
55
+ tags_index = properties.find_index { |p| !p.is_a?(String)}
56
+ if tags_index
57
+ properties, tags = properties[0..tags_index-1], properties[tags_index..-1]
58
+ else
59
+ tags = []
60
+ end
61
+ if properties.size == 1
62
+ description = "With property #{properties.first}"
63
+ else
64
+ description = "With properties #{english_join(properties.map { |property| "#{property.inspect}" })}"
65
+ end
66
+ context description, *tags do
67
+ before do
68
+ properties.each do |property_str|
69
+ resource_class.class_eval("property #{property_str}", __FILE__, __LINE__)
70
+ end
71
+ end
72
+ instance_eval(&block)
73
+ end
74
+ end
75
+
76
+ # Basic properties
77
+ with_property ':bare_property' do
78
+ it "can be set" do
79
+ expect(resource.bare_property 10).to eq 10
80
+ expect(resource.bare_property).to eq 10
81
+ end
82
+ it "emits a deprecation warning and does a get, if set to nil" do
83
+ expect(resource.bare_property 10).to eq 10
84
+ expect { resource.bare_property nil }.to raise_error Chef::Exceptions::DeprecatedFeatureError
85
+ Chef::Config[:treat_deprecation_warnings_as_errors] = false
86
+ expect(resource.bare_property nil).to eq 10
87
+ expect(resource.bare_property).to eq 10
88
+ end
89
+ it "can be updated" do
90
+ expect(resource.bare_property 10).to eq 10
91
+ expect(resource.bare_property 20).to eq 20
92
+ expect(resource.bare_property).to eq 20
93
+ end
94
+ it "can be set with =" do
95
+ expect(resource.bare_property 10).to eq 10
96
+ expect(resource.bare_property).to eq 10
97
+ end
98
+ it "can be set to nil with =" do
99
+ expect(resource.bare_property 10).to eq 10
100
+ expect(resource.bare_property = nil).to be_nil
101
+ expect(resource.bare_property).to be_nil
102
+ end
103
+ it "can be updated with =" do
104
+ expect(resource.bare_property 10).to eq 10
105
+ expect(resource.bare_property = 20).to eq 20
106
+ expect(resource.bare_property).to eq 20
107
+ end
108
+ end
109
+
110
+ with_property ":x, name_property: true" do
111
+ context "and subclass" do
112
+ let(:subresource_class) do
113
+ new_resource_name = self.class.new_resource_name
114
+ Class.new(resource_class) do
115
+ resource_name new_resource_name
116
+ end
117
+ end
118
+ let(:subresource) do
119
+ subresource_class.new('blah')
120
+ end
121
+
122
+ context "with property :x on the subclass" do
123
+ before do
124
+ subresource_class.class_eval do
125
+ property :x
126
+ end
127
+ end
128
+
129
+ it "x is still name_property" do
130
+ expect(subresource.x).to eq 'blah'
131
+ end
132
+ end
133
+
134
+ context "with property :x, name_attribute: false on the subclass" do
135
+ before do
136
+ subresource_class.class_eval do
137
+ property :x, name_attribute: false
138
+ end
139
+ end
140
+
141
+ it "x is no longer name_property" do
142
+ expect(subresource.x).to be_nil
143
+ end
144
+ end
145
+
146
+ context "with property :x, default: 10 on the subclass" do
147
+ before do
148
+ subresource_class.class_eval do
149
+ property :x, default: 10
150
+ end
151
+ end
152
+
153
+ it "x is no longer name_property" do
154
+ expect(subresource.x).to eq(10)
155
+ end
156
+ end
157
+ end
158
+ end
159
+
160
+ with_property ":x, Integer" do
161
+ context "and subclass" do
162
+ let(:subresource_class) do
163
+ new_resource_name = self.class.new_resource_name
164
+ Class.new(resource_class) do
165
+ resource_name new_resource_name
166
+ end
167
+ end
168
+ let(:subresource) do
169
+ subresource_class.new('blah')
170
+ end
171
+
172
+ it "x is inherited" do
173
+ expect(subresource.x 10).to eq 10
174
+ expect(subresource.x).to eq 10
175
+ expect(subresource.x = 20).to eq 20
176
+ expect(subresource.x).to eq 20
177
+ expect(subresource_class.properties[:x]).not_to be_nil
178
+ end
179
+
180
+ it "x's validation is inherited" do
181
+ expect { subresource.x 'ohno' }.to raise_error Chef::Exceptions::ValidationFailed
182
+ end
183
+
184
+ context "with property :y on the subclass" do
185
+ before do
186
+ subresource_class.class_eval do
187
+ property :y
188
+ end
189
+ end
190
+
191
+ it "x is still there" do
192
+ expect(subresource.x 10).to eq 10
193
+ expect(subresource.x).to eq 10
194
+ expect(subresource.x = 20).to eq 20
195
+ expect(subresource.x).to eq 20
196
+ expect(subresource_class.properties[:x]).not_to be_nil
197
+ end
198
+ it "y is there" do
199
+ expect(subresource.y 10).to eq 10
200
+ expect(subresource.y).to eq 10
201
+ expect(subresource.y = 20).to eq 20
202
+ expect(subresource.y).to eq 20
203
+ expect(subresource_class.properties[:y]).not_to be_nil
204
+ end
205
+ it "y is not on the superclass" do
206
+ expect { resource_class.y 10 }.to raise_error
207
+ expect(resource_class.properties[:y]).to be_nil
208
+ end
209
+ end
210
+
211
+ context "with property :x on the subclass" do
212
+ before do
213
+ subresource_class.class_eval do
214
+ property :x
215
+ end
216
+ end
217
+
218
+ it "x is still there" do
219
+ expect(subresource.x 10).to eq 10
220
+ expect(subresource.x).to eq 10
221
+ expect(subresource.x = 20).to eq 20
222
+ expect(subresource.x).to eq 20
223
+ expect(subresource_class.properties[:x]).not_to be_nil
224
+ expect(subresource_class.properties[:x]).not_to eq resource_class.properties[:x]
225
+ end
226
+
227
+ it "x's validation is inherited" do
228
+ expect { subresource.x 'ohno' }.to raise_error Chef::Exceptions::ValidationFailed
229
+ end
230
+ end
231
+
232
+ context "with property :x, default: 80 on the subclass" do
233
+ before do
234
+ subresource_class.class_eval do
235
+ property :x, default: 80
236
+ end
237
+ end
238
+
239
+ it "x is still there" do
240
+ expect(subresource.x 10).to eq 10
241
+ expect(subresource.x).to eq 10
242
+ expect(subresource.x = 20).to eq 20
243
+ expect(subresource.x).to eq 20
244
+ expect(subresource_class.properties[:x]).not_to be_nil
245
+ expect(subresource_class.properties[:x]).not_to eq resource_class.properties[:x]
246
+ end
247
+
248
+ it "x defaults to 80" do
249
+ expect(subresource.x).to eq 80
250
+ end
251
+
252
+ it "x's validation is inherited" do
253
+ expect { subresource.x 'ohno' }.to raise_error Chef::Exceptions::ValidationFailed
254
+ end
255
+ end
256
+
257
+ context "with property :x, String on the subclass" do
258
+ before do
259
+ subresource_class.class_eval do
260
+ property :x, String
261
+ end
262
+ end
263
+
264
+ it "x is still there" do
265
+ expect(subresource.x "10").to eq "10"
266
+ expect(subresource.x).to eq "10"
267
+ expect(subresource.x = "20").to eq "20"
268
+ expect(subresource.x).to eq "20"
269
+ expect(subresource_class.properties[:x]).not_to be_nil
270
+ expect(subresource_class.properties[:x]).not_to eq resource_class.properties[:x]
271
+ end
272
+
273
+ it "x's validation is overwritten" do
274
+ expect { subresource.x 10 }.to raise_error Chef::Exceptions::ValidationFailed
275
+ expect(subresource.x 'ohno').to eq 'ohno'
276
+ expect(subresource.x).to eq 'ohno'
277
+ end
278
+
279
+ it "the superclass's validation for x is still there" do
280
+ expect { resource.x 'ohno' }.to raise_error Chef::Exceptions::ValidationFailed
281
+ expect(resource.x 10).to eq 10
282
+ expect(resource.x).to eq 10
283
+ end
284
+ end
285
+ end
286
+ end
287
+
288
+ context "Chef::Resource::Property#reset_property" do
289
+ it "when a resource is newly created, reset_property(:name) sets property to nil" do
290
+ expect(resource.property_is_set?(:name)).to be_truthy
291
+ resource.reset_property(:name)
292
+ expect(resource.property_is_set?(:name)).to be_falsey
293
+ expect(resource.name).to be_nil
294
+ end
295
+
296
+ it "when referencing an undefined property, reset_property(:x) raises an error" do
297
+ expect { resource.reset_property(:x) }.to raise_error(ArgumentError)
298
+ end
299
+
300
+ with_property ':x' do
301
+ it "when the resource is newly created, reset_property(:x) does nothing" do
302
+ expect(resource.property_is_set?(:x)).to be_falsey
303
+ resource.reset_property(:x)
304
+ expect(resource.property_is_set?(:x)).to be_falsey
305
+ expect(resource.x).to be_nil
306
+ end
307
+ it "when x is set, reset_property resets it" do
308
+ resource.x 10
309
+ expect(resource.property_is_set?(:x)).to be_truthy
310
+ resource.reset_property(:x)
311
+ expect(resource.property_is_set?(:x)).to be_falsey
312
+ expect(resource.x).to be_nil
313
+ end
314
+ end
315
+
316
+ with_property ':x, Integer' do
317
+ it "when the resource is newly created, reset_property(:x) does nothing" do
318
+ expect(resource.property_is_set?(:x)).to be_falsey
319
+ resource.reset_property(:x)
320
+ expect(resource.property_is_set?(:x)).to be_falsey
321
+ expect(resource.x).to be_nil
322
+ end
323
+ it "when x is set, reset_property resets it even though `nil` is technically invalid" do
324
+ resource.x 10
325
+ expect(resource.property_is_set?(:x)).to be_truthy
326
+ resource.reset_property(:x)
327
+ expect(resource.property_is_set?(:x)).to be_falsey
328
+ expect(resource.x).to be_nil
329
+ end
330
+ end
331
+
332
+ with_property ':x, default: 10' do
333
+ it "when the resource is newly created, reset_property(:x) does nothing" do
334
+ expect(resource.property_is_set?(:x)).to be_falsey
335
+ resource.reset_property(:x)
336
+ expect(resource.property_is_set?(:x)).to be_falsey
337
+ expect(resource.x).to eq 10
338
+ end
339
+ it "when x is set, reset_property resets it and it returns the default" do
340
+ resource.x 20
341
+ resource.reset_property(:x)
342
+ expect(resource.property_is_set?(:x)).to be_falsey
343
+ expect(resource.x).to eq 10
344
+ end
345
+ end
346
+
347
+ with_property ':x, default: lazy { 10 }' do
348
+ it "when the resource is newly created, reset_property(:x) does nothing" do
349
+ expect(resource.property_is_set?(:x)).to be_falsey
350
+ resource.reset_property(:x)
351
+ expect(resource.property_is_set?(:x)).to be_falsey
352
+ expect(resource.x).to eq 10
353
+ end
354
+ it "when x is set, reset_property resets it and it returns the default" do
355
+ resource.x 20
356
+ resource.reset_property(:x)
357
+ expect(resource.property_is_set?(:x)).to be_falsey
358
+ expect(resource.x).to eq 10
359
+ end
360
+ end
361
+ end
362
+
363
+ context "Chef::Resource::Property#property_is_set?" do
364
+ it "when a resource is newly created, property_is_set?(:name) is true" do
365
+ expect(resource.property_is_set?(:name)).to be_truthy
366
+ end
367
+
368
+ it "when referencing an undefined property, property_is_set?(:x) raises an error" do
369
+ expect { resource.property_is_set?(:x) }.to raise_error(ArgumentError)
370
+ end
371
+
372
+ with_property ':x' do
373
+ it "when the resource is newly created, property_is_set?(:x) is false" do
374
+ expect(resource.property_is_set?(:x)).to be_falsey
375
+ end
376
+ it "when x is set, property_is_set?(:x) is true" do
377
+ resource.x 10
378
+ expect(resource.property_is_set?(:x)).to be_truthy
379
+ end
380
+ it "when x is set with =, property_is_set?(:x) is true" do
381
+ resource.x = 10
382
+ expect(resource.property_is_set?(:x)).to be_truthy
383
+ end
384
+ it "when x is set to a lazy value, property_is_set?(:x) is true" do
385
+ resource.x lazy { 10 }
386
+ expect(resource.property_is_set?(:x)).to be_truthy
387
+ end
388
+ it "when x is retrieved, property_is_set?(:x) is false" do
389
+ resource.x
390
+ expect(resource.property_is_set?(:x)).to be_falsey
391
+ end
392
+ end
393
+
394
+ with_property ':x, default: 10' do
395
+ it "when the resource is newly created, property_is_set?(:x) is false" do
396
+ expect(resource.property_is_set?(:x)).to be_falsey
397
+ end
398
+ it "when x is set, property_is_set?(:x) is true" do
399
+ resource.x 10
400
+ expect(resource.property_is_set?(:x)).to be_truthy
401
+ end
402
+ it "when x is set with =, property_is_set?(:x) is true" do
403
+ resource.x = 10
404
+ expect(resource.property_is_set?(:x)).to be_truthy
405
+ end
406
+ it "when x is set to a lazy value, property_is_set?(:x) is true" do
407
+ resource.x lazy { 10 }
408
+ expect(resource.property_is_set?(:x)).to be_truthy
409
+ end
410
+ it "when x is retrieved, property_is_set?(:x) is false" do
411
+ resource.x
412
+ expect(resource.property_is_set?(:x)).to be_falsey
413
+ end
414
+ end
415
+
416
+ with_property ':x, default: nil' do
417
+ it "when the resource is newly created, property_is_set?(:x) is false" do
418
+ expect(resource.property_is_set?(:x)).to be_falsey
419
+ end
420
+ it "when x is set, property_is_set?(:x) is true" do
421
+ resource.x 10
422
+ expect(resource.property_is_set?(:x)).to be_truthy
423
+ end
424
+ it "when x is set with =, property_is_set?(:x) is true" do
425
+ resource.x = 10
426
+ expect(resource.property_is_set?(:x)).to be_truthy
427
+ end
428
+ it "when x is set to a lazy value, property_is_set?(:x) is true" do
429
+ resource.x lazy { 10 }
430
+ expect(resource.property_is_set?(:x)).to be_truthy
431
+ end
432
+ it "when x is retrieved, property_is_set?(:x) is false" do
433
+ resource.x
434
+ expect(resource.property_is_set?(:x)).to be_falsey
435
+ end
436
+ end
437
+
438
+ with_property ':x, default: lazy { 10 }' do
439
+ it "when the resource is newly created, property_is_set?(:x) is false" do
440
+ expect(resource.property_is_set?(:x)).to be_falsey
441
+ end
442
+ it "when x is set, property_is_set?(:x) is true" do
443
+ resource.x 10
444
+ expect(resource.property_is_set?(:x)).to be_truthy
445
+ end
446
+ it "when x is set with =, property_is_set?(:x) is true" do
447
+ resource.x = 10
448
+ expect(resource.property_is_set?(:x)).to be_truthy
449
+ end
450
+ it "when x is retrieved, property_is_set?(:x) is false" do
451
+ resource.x
452
+ expect(resource.property_is_set?(:x)).to be_falsey
453
+ end
454
+ end
455
+ end
456
+
457
+ context "Chef::Resource::Property#default" do
458
+ with_property ':x, default: 10' do
459
+ it "when x is set, it returns its value" do
460
+ expect(resource.x 20).to eq 20
461
+ expect(resource.property_is_set?(:x)).to be_truthy
462
+ expect(resource.x).to eq 20
463
+ end
464
+ it "when x is not set, it returns 10" do
465
+ expect(resource.x).to eq 10
466
+ end
467
+ it "when x is not set, it is not included in state" do
468
+ expect(resource.state_for_resource_reporter).to eq({})
469
+ end
470
+ it "when x is set to nil, it returns nil" do
471
+ resource.instance_eval { @x = nil }
472
+ expect(resource.x).to be_nil
473
+ end
474
+
475
+ context "With a subclass" do
476
+ let(:subresource_class) do
477
+ new_resource_name = self.class.new_resource_name
478
+ Class.new(resource_class) do
479
+ resource_name new_resource_name
480
+ end
481
+ end
482
+ let(:subresource) { subresource_class.new('blah') }
483
+ it "The default is inherited" do
484
+ expect(subresource.x).to eq 10
485
+ end
486
+ end
487
+ end
488
+
489
+ with_property ':x, default: 10, identity: true' do
490
+ it "when x is not set, it is included in identity" do
491
+ expect(resource.identity).to eq(10)
492
+ end
493
+ end
494
+
495
+ with_property ':x, default: 1, identity: true', ':y, default: 2, identity: true' do
496
+ it "when x is not set, it is still included in identity" do
497
+ resource.y 20
498
+ expect(resource.identity).to eq(x: 1, y: 20)
499
+ end
500
+ end
501
+
502
+ with_property ':x, default: nil' do
503
+ it "when x is not set, it returns nil" do
504
+ expect(resource.x).to be_nil
505
+ end
506
+ end
507
+
508
+ with_property ':x' do
509
+ it "when x is not set, it returns nil" do
510
+ expect(resource.x).to be_nil
511
+ end
512
+ end
513
+
514
+ context "hash default" do
515
+ context "(deprecations allowed)" do
516
+ before { Chef::Config[:treat_deprecation_warnings_as_errors] = false }
517
+
518
+ with_property ':x, default: {}' do
519
+ it "when x is not set, it returns {}" do
520
+ expect(resource.x).to eq({})
521
+ end
522
+ it "The same exact value is returned multiple times in a row" do
523
+ value = resource.x
524
+ expect(value).to eq({})
525
+ expect(resource.x.object_id).to eq(value.object_id)
526
+ end
527
+ it "Multiple instances of x receive the exact same value" do
528
+ expect(resource.x.object_id).to eq(resource_class.new('blah2').x.object_id)
529
+ end
530
+ end
531
+ end
532
+
533
+ with_property ':x, default: lazy { {} }' do
534
+ it "when x is not set, it returns {}" do
535
+ expect(resource.x).to eq({})
536
+ end
537
+ # it "The value is different each time it is called" do
538
+ # value = resource.x
539
+ # expect(value).to eq({})
540
+ # expect(resource.x.object_id).not_to eq(value.object_id)
541
+ # end
542
+ it "Multiple instances of x receive different values" do
543
+ expect(resource.x.object_id).not_to eq(resource_class.new('blah2').x.object_id)
544
+ end
545
+ end
546
+ end
547
+
548
+ context "with a class with 'blah' as both class and instance methods" do
549
+ before do
550
+ resource_class.class_eval do
551
+ def self.blah
552
+ 'class'
553
+ end
554
+ def blah
555
+ "#{name}#{next_index}"
556
+ end
557
+ end
558
+ end
559
+
560
+ with_property ':x, default: lazy { blah }' do
561
+ it "x is run in context of the instance" do
562
+ expect(resource.x).to eq "blah1"
563
+ end
564
+ it "x is run in the context of each instance it is run in" do
565
+ expect(resource.x).to eq "blah1"
566
+ expect(resource_class.new('another').x).to eq "another2"
567
+ # expect(resource.x).to eq "blah3"
568
+ end
569
+ end
570
+
571
+ with_property ':x, default: lazy { |x| "#{blah}#{x.blah}" }' do
572
+ it "x is run in context of the class (where it was defined) and passed the instance" do
573
+ expect(resource.x).to eq "classblah1"
574
+ end
575
+ it "x is passed the value of each instance it is run in" do
576
+ expect(resource.x).to eq "classblah1"
577
+ expect(resource_class.new('another').x).to eq "classanother2"
578
+ # expect(resource.x).to eq "classblah3"
579
+ end
580
+ end
581
+ end
582
+
583
+ context "validation of defaults" do
584
+ with_property ':x, String, default: 10' do
585
+ it "when the resource is created, no error is raised" do
586
+ resource
587
+ end
588
+ it "when x is set, no error is raised" do
589
+ expect(resource.x 'hi').to eq 'hi'
590
+ expect(resource.x).to eq 'hi'
591
+ end
592
+ it "when x is retrieved, no validation error is raised" do
593
+ expect(resource.x).to eq 10
594
+ end
595
+ # it "when x is retrieved, a validation error is raised" do
596
+ # expect { resource.x }.to raise_error Chef::Exceptions::ValidationFailed
597
+ # end
598
+ end
599
+
600
+ with_property ":x, String, default: lazy { Namer.next_index }" do
601
+ it "when the resource is created, no error is raised" do
602
+ resource
603
+ end
604
+ it "when x is set, no error is raised" do
605
+ expect(resource.x 'hi').to eq 'hi'
606
+ expect(resource.x).to eq 'hi'
607
+ end
608
+ it "when x is retrieved, no validation error is raised" do
609
+ expect(resource.x).to eq 1
610
+ expect(Namer.current_index).to eq 1
611
+ end
612
+ # it "when x is retrieved, a validation error is raised" do
613
+ # expect { resource.x }.to raise_error Chef::Exceptions::ValidationFailed
614
+ # expect(Namer.current_index).to eq 1
615
+ # end
616
+ end
617
+
618
+ with_property ":x, default: lazy { Namer.next_index.to_s }, is: proc { |v| Namer.next_index; true }" do
619
+ it "validation is not run at all on the default value" do
620
+ expect(resource.x).to eq '1'
621
+ expect(Namer.current_index).to eq 1
622
+ end
623
+ # it "validation is run each time" do
624
+ # expect(resource.x).to eq '1'
625
+ # expect(Namer.current_index).to eq 2
626
+ # expect(resource.x).to eq '1'
627
+ # expect(Namer.current_index).to eq 2
628
+ # end
629
+ end
630
+
631
+ with_property ":x, default: lazy { Namer.next_index.to_s.freeze }, is: proc { |v| Namer.next_index; true }" do
632
+ it "validation is not run at all on the default value" do
633
+ expect(resource.x).to eq '1'
634
+ expect(Namer.current_index).to eq 1
635
+ end
636
+ # it "validation is only run the first time" do
637
+ # expect(resource.x).to eq '1'
638
+ # expect(Namer.current_index).to eq 2
639
+ # expect(resource.x).to eq '1'
640
+ # expect(Namer.current_index).to eq 2
641
+ # end
642
+ end
643
+ end
644
+
645
+ context "coercion of defaults" do
646
+ # Frozen default, non-frozen coerce
647
+ with_property ':x, coerce: proc { |v| "#{v}#{next_index}" }, default: 10' do
648
+ it "when the resource is created, the proc is not yet run" do
649
+ resource
650
+ expect(Namer.current_index).to eq 0
651
+ end
652
+ it "when x is set, coercion is run" do
653
+ expect(resource.x 'hi').to eq 'hi1'
654
+ expect(resource.x).to eq 'hi1'
655
+ expect(Namer.current_index).to eq 1
656
+ end
657
+ it "when x is retrieved, coercion is run exactly once" do
658
+ expect(resource.x).to eq '101'
659
+ expect(resource.x).to eq '101'
660
+ expect(Namer.current_index).to eq 1
661
+ end
662
+ end
663
+
664
+ # Frozen default, frozen coerce
665
+ with_property ':x, coerce: proc { |v| "#{v}#{next_index}".freeze }, default: 10' do
666
+ it "when the resource is created, the proc is not yet run" do
667
+ resource
668
+ expect(Namer.current_index).to eq 0
669
+ end
670
+ it "when x is set, coercion is run" do
671
+ expect(resource.x 'hi').to eq 'hi1'
672
+ expect(resource.x).to eq 'hi1'
673
+ expect(Namer.current_index).to eq 1
674
+ end
675
+ it "when x is retrieved, coercion is run each time" do
676
+ expect(resource.x).to eq '101'
677
+ expect(resource.x).to eq '102'
678
+ expect(Namer.current_index).to eq 2
679
+ end
680
+ end
681
+
682
+ # Frozen lazy default, non-frozen coerce
683
+ with_property ':x, coerce: proc { |v| "#{v}#{next_index}" }, default: lazy { 10 }' do
684
+ it "when the resource is created, the proc is not yet run" do
685
+ resource
686
+ expect(Namer.current_index).to eq 0
687
+ end
688
+ it "when x is set, coercion is run" do
689
+ expect(resource.x 'hi').to eq 'hi1'
690
+ expect(resource.x).to eq 'hi1'
691
+ expect(Namer.current_index).to eq 1
692
+ end
693
+ it "when x is retrieved, coercion is run exactly once" do
694
+ expect(resource.x).to eq '101'
695
+ expect(resource.x).to eq '101'
696
+ expect(Namer.current_index).to eq 1
697
+ end
698
+ end
699
+
700
+ # Non-frozen lazy default, frozen coerce
701
+ with_property ':x, coerce: proc { |v| "#{v}#{next_index}".freeze }, default: lazy { "10" }' do
702
+ it "when the resource is created, the proc is not yet run" do
703
+ resource
704
+ expect(Namer.current_index).to eq 0
705
+ end
706
+ it "when x is set, coercion is run" do
707
+ expect(resource.x 'hi').to eq 'hi1'
708
+ expect(resource.x).to eq 'hi1'
709
+ expect(Namer.current_index).to eq 1
710
+ end
711
+ it "when x is retrieved, coercion is run each time" do
712
+ expect(resource.x).to eq '101'
713
+ expect(resource.x).to eq '102'
714
+ expect(Namer.current_index).to eq 2
715
+ end
716
+ end
717
+
718
+ with_property ':x, proc { |v| Namer.next_index; true }, coerce: proc { |v| "#{v}#{next_index}" }, default: lazy { 10 }' do
719
+ it "coercion is only run the first time x is retrieved, and validation is not run" do
720
+ expect(Namer.current_index).to eq 0
721
+ expect(resource.x).to eq '101'
722
+ expect(Namer.current_index).to eq 1
723
+ expect(resource.x).to eq '101'
724
+ expect(Namer.current_index).to eq 1
725
+ end
726
+ end
727
+
728
+ context "validation and coercion of defaults" do
729
+ with_property ':x, String, coerce: proc { |v| "#{v}#{next_index}" }, default: 10' do
730
+ it "when x is retrieved, it is coerced before validating and passes" do
731
+ expect(resource.x).to eq '101'
732
+ end
733
+ end
734
+ with_property ':x, Integer, coerce: proc { |v| "#{v}#{next_index}" }, default: 10' do
735
+ it "when x is retrieved, it is coerced and not validated" do
736
+ expect(resource.x).to eq '101'
737
+ end
738
+ # it "when x is retrieved, it is coerced before validating and fails" do
739
+ # expect { resource.x }.to raise_error Chef::Exceptions::ValidationFailed
740
+ # end
741
+ end
742
+ with_property ':x, String, coerce: proc { |v| "#{v}#{next_index}" }, default: lazy { 10 }' do
743
+ it "when x is retrieved, it is coerced before validating and passes" do
744
+ expect(resource.x).to eq '101'
745
+ end
746
+ end
747
+ with_property ':x, Integer, coerce: proc { |v| "#{v}#{next_index}" }, default: lazy { 10 }' do
748
+ it "when x is retrieved, it is coerced and not validated" do
749
+ expect(resource.x).to eq '101'
750
+ end
751
+ # it "when x is retrieved, it is coerced before validating and fails" do
752
+ # expect { resource.x }.to raise_error Chef::Exceptions::ValidationFailed
753
+ # end
754
+ end
755
+ with_property ':x, proc { |v| Namer.next_index; true }, coerce: proc { |v| "#{v}#{next_index}" }, default: lazy { 10 }' do
756
+ it "coercion is only run the first time x is retrieved, and validation is not run" do
757
+ expect(Namer.current_index).to eq 0
758
+ expect(resource.x).to eq '101'
759
+ expect(Namer.current_index).to eq 1
760
+ expect(resource.x).to eq '101'
761
+ expect(Namer.current_index).to eq 1
762
+ end
763
+ end
764
+ end
765
+ end
766
+ end
767
+
768
+ context "Chef::Resource#lazy" do
769
+ with_property ':x' do
770
+ it "setting x to a lazy value does not run it immediately" do
771
+ resource.x lazy { Namer.next_index }
772
+ expect(Namer.current_index).to eq 0
773
+ end
774
+ it "you can set x to a lazy value in the instance" do
775
+ resource.instance_eval do
776
+ x lazy { Namer.next_index }
777
+ end
778
+ expect(resource.x).to eq 1
779
+ expect(Namer.current_index).to eq 1
780
+ end
781
+ it "retrieving a lazy value pops it open" do
782
+ resource.x lazy { Namer.next_index }
783
+ expect(resource.x).to eq 1
784
+ expect(Namer.current_index).to eq 1
785
+ end
786
+ it "retrieving a lazy value twice evaluates it twice" do
787
+ resource.x lazy { Namer.next_index }
788
+ expect(resource.x).to eq 1
789
+ expect(resource.x).to eq 2
790
+ expect(Namer.current_index).to eq 2
791
+ end
792
+ it "setting the same lazy value on two different instances runs it on each instancee" do
793
+ resource2 = resource_class.new("blah2")
794
+ l = lazy { Namer.next_index }
795
+ resource.x l
796
+ resource2.x l
797
+ expect(resource2.x).to eq 1
798
+ expect(resource.x).to eq 2
799
+ expect(resource2.x).to eq 3
800
+ end
801
+
802
+ context "when the class has a class and instance method named blah" do
803
+ before do
804
+ resource_class.class_eval do
805
+ def self.blah
806
+ "class"
807
+ end
808
+ def blah
809
+ "#{name}#{Namer.next_index}"
810
+ end
811
+ end
812
+ end
813
+ def blah
814
+ "example"
815
+ end
816
+ # it "retrieving lazy { blah } gets the instance variable" do
817
+ # resource.x lazy { blah }
818
+ # expect(resource.x).to eq "blah1"
819
+ # end
820
+ # it "retrieving lazy { blah } from two different instances gets two different instance variables" do
821
+ # resource2 = resource_class.new("another")
822
+ # l = lazy { blah }
823
+ # resource2.x l
824
+ # resource.x l
825
+ # expect(resource2.x).to eq "another1"
826
+ # expect(resource.x).to eq "blah2"
827
+ # expect(resource2.x).to eq "another3"
828
+ # end
829
+ it 'retrieving lazy { |x| "#{blah}#{x.blah}" } gets the example and instance variables' do
830
+ resource.x lazy { |x| "#{blah}#{x.blah}" }
831
+ expect(resource.x).to eq "exampleblah1"
832
+ end
833
+ it 'retrieving lazy { |x| "#{blah}#{x.blah}" } from two different instances gets two different instance variables' do
834
+ resource2 = resource_class.new("another")
835
+ l = lazy { |x| "#{blah}#{x.blah}" }
836
+ resource2.x l
837
+ resource.x l
838
+ expect(resource2.x).to eq "exampleanother1"
839
+ expect(resource.x).to eq "exampleblah2"
840
+ expect(resource2.x).to eq "exampleanother3"
841
+ end
842
+ end
843
+ end
844
+
845
+ with_property ':x, coerce: proc { |v| "#{v}#{Namer.next_index}" }' do
846
+ it "lazy values are not coerced on set" do
847
+ resource.x lazy { Namer.next_index }
848
+ expect(Namer.current_index).to eq 0
849
+ end
850
+ it "lazy values are coerced on get" do
851
+ resource.x lazy { Namer.next_index }
852
+ expect(resource.x).to eq "12"
853
+ expect(Namer.current_index).to eq 2
854
+ end
855
+ it "lazy values are coerced on each access" do
856
+ resource.x lazy { Namer.next_index }
857
+ expect(resource.x).to eq "12"
858
+ expect(Namer.current_index).to eq 2
859
+ expect(resource.x).to eq "34"
860
+ expect(Namer.current_index).to eq 4
861
+ end
862
+ end
863
+
864
+ with_property ':x, String' do
865
+ it "lazy values are not validated on set" do
866
+ resource.x lazy { Namer.next_index }
867
+ expect(Namer.current_index).to eq 0
868
+ end
869
+ it "lazy values are validated on get" do
870
+ resource.x lazy { Namer.next_index }
871
+ expect { resource.x }.to raise_error Chef::Exceptions::ValidationFailed
872
+ expect(Namer.current_index).to eq 1
873
+ end
874
+ end
875
+
876
+ with_property ':x, is: proc { |v| Namer.next_index; true }' do
877
+ it "lazy values are validated on each access" do
878
+ resource.x lazy { Namer.next_index }
879
+ expect(resource.x).to eq 1
880
+ expect(Namer.current_index).to eq 2
881
+ expect(resource.x).to eq 3
882
+ expect(Namer.current_index).to eq 4
883
+ end
884
+ end
885
+
886
+ with_property ':x, Integer, coerce: proc { |v| "#{v}#{Namer.next_index}" }' do
887
+ it "lazy values are not validated or coerced on set" do
888
+ resource.x lazy { Namer.next_index }
889
+ expect(Namer.current_index).to eq 0
890
+ end
891
+ it "lazy values are coerced before being validated, which fails" do
892
+ resource.x lazy { Namer.next_index }
893
+ expect(Namer.current_index).to eq 0
894
+ expect { resource.x }.to raise_error Chef::Exceptions::ValidationFailed
895
+ expect(Namer.current_index).to eq 2
896
+ end
897
+ end
898
+
899
+ with_property ':x, coerce: proc { |v| "#{v}#{Namer.next_index}" }, is: proc { |v| Namer.next_index; true }' do
900
+ it "lazy values are coerced and validated exactly once" do
901
+ resource.x lazy { Namer.next_index }
902
+ expect(resource.x).to eq "12"
903
+ expect(Namer.current_index).to eq 3
904
+ expect(resource.x).to eq "45"
905
+ expect(Namer.current_index).to eq 6
906
+ end
907
+ end
908
+
909
+ with_property ':x, String, coerce: proc { |v| "#{v}#{Namer.next_index}" }' do
910
+ it "lazy values are coerced before being validated, which succeeds" do
911
+ resource.x lazy { Namer.next_index }
912
+ expect(resource.x).to eq "12"
913
+ expect(Namer.current_index).to eq 2
914
+ end
915
+ end
916
+ end
917
+
918
+ context "Chef::Resource::Property#coerce" do
919
+ with_property ':x, coerce: proc { |v| "#{v}#{Namer.next_index}" }' do
920
+ it "coercion runs on set" do
921
+ expect(resource.x 10).to eq "101"
922
+ expect(Namer.current_index).to eq 1
923
+ end
924
+ it "coercion sets the value (and coercion does not run on get)" do
925
+ expect(resource.x 10).to eq "101"
926
+ expect(resource.x).to eq "101"
927
+ expect(Namer.current_index).to eq 1
928
+ end
929
+ it "coercion runs each time set happens" do
930
+ expect(resource.x 10).to eq "101"
931
+ expect(Namer.current_index).to eq 1
932
+ expect(resource.x 10).to eq "102"
933
+ expect(Namer.current_index).to eq 2
934
+ end
935
+ end
936
+ with_property ':x, coerce: proc { |x| Namer.next_index; raise "hi" if x == 10; x }, is: proc { |x| Namer.next_index; x != 10 }' do
937
+ it "failed coercion fails to set the value" do
938
+ resource.x 20
939
+ expect(resource.x).to eq 20
940
+ expect(Namer.current_index).to eq 2
941
+ expect { resource.x 10 }.to raise_error 'hi'
942
+ expect(resource.x).to eq 20
943
+ expect(Namer.current_index).to eq 3
944
+ end
945
+ it "validation does not run if coercion fails" do
946
+ expect { resource.x 10 }.to raise_error 'hi'
947
+ expect(Namer.current_index).to eq 1
948
+ end
949
+ end
950
+ end
951
+
952
+ context "Chef::Resource::Property validation" do
953
+ with_property ':x, is: proc { |v| Namer.next_index; v.is_a?(Integer) }' do
954
+ it "validation runs on set" do
955
+ expect(resource.x 10).to eq 10
956
+ expect(Namer.current_index).to eq 1
957
+ end
958
+ it "validation sets the value (and validation does not run on get)" do
959
+ expect(resource.x 10).to eq 10
960
+ expect(resource.x).to eq 10
961
+ expect(Namer.current_index).to eq 1
962
+ end
963
+ it "validation runs each time set happens" do
964
+ expect(resource.x 10).to eq 10
965
+ expect(Namer.current_index).to eq 1
966
+ expect(resource.x 10).to eq 10
967
+ expect(Namer.current_index).to eq 2
968
+ end
969
+ it "failed validation fails to set the value" do
970
+ expect(resource.x 10).to eq 10
971
+ expect(Namer.current_index).to eq 1
972
+ expect { resource.x 'blah' }.to raise_error Chef::Exceptions::ValidationFailed
973
+ expect(resource.x).to eq 10
974
+ expect(Namer.current_index).to eq 2
975
+ end
976
+ end
977
+ end
978
+
979
+ [ 'name_attribute', 'name_property' ].each do |name|
980
+ context "Chef::Resource::Property##{name}" do
981
+ with_property ":x, #{name}: true" do
982
+ it "defaults x to resource.name" do
983
+ expect(resource.x).to eq 'blah'
984
+ end
985
+ it "does not pick up resource.name if set" do
986
+ expect(resource.x 10).to eq 10
987
+ expect(resource.x).to eq 10
988
+ end
989
+ it "binds to the latest resource.name when run" do
990
+ resource.name 'foo'
991
+ expect(resource.x).to eq 'foo'
992
+ end
993
+ it "caches resource.name" do
994
+ expect(resource.x).to eq 'blah'
995
+ resource.name 'foo'
996
+ expect(resource.x).to eq 'blah'
997
+ end
998
+ end
999
+
1000
+ with_property ":x, #{name}: false" do
1001
+ it "defaults to nil" do
1002
+ expect(resource.x).to be_nil
1003
+ end
1004
+ end
1005
+
1006
+ with_property ":x, #{name}: nil" do
1007
+ it "defaults to nil" do
1008
+ expect(resource.x).to be_nil
1009
+ end
1010
+ end
1011
+
1012
+ context "default ordering deprecation warnings" do
1013
+ it "emits a deprecation warning for property :x, default: 10, #{name}: true" do
1014
+ expect { resource_class.property :x, :default => 10, name.to_sym => true }.to raise_error Chef::Exceptions::DeprecatedFeatureError,
1015
+ /Cannot specify both default and name_property together on property x of resource chef_resource_property_spec_(\d+). Only one \(default\) will be obeyed./
1016
+ end
1017
+ it "emits a deprecation warning for property :x, default: nil, #{name}: true" do
1018
+ expect { resource_class.property :x, :default => nil, name.to_sym => true }.to raise_error Chef::Exceptions::DeprecatedFeatureError,
1019
+ /Cannot specify both default and name_property together on property x of resource chef_resource_property_spec_(\d+). Only one \(name_property\) will be obeyed./
1020
+ end
1021
+ it "emits a deprecation warning for property :x, #{name}: true, default: 10" do
1022
+ expect { resource_class.property :x, name.to_sym => true, :default => 10 }.to raise_error Chef::Exceptions::DeprecatedFeatureError,
1023
+ /Cannot specify both default and name_property together on property x of resource chef_resource_property_spec_(\d+). Only one \(name_property\) will be obeyed./
1024
+ end
1025
+ it "emits a deprecation warning for property :x, #{name}: true, default: nil" do
1026
+ expect { resource_class.property :x, name.to_sym => true, :default => nil }.to raise_error Chef::Exceptions::DeprecatedFeatureError,
1027
+ /Cannot specify both default and name_property together on property x of resource chef_resource_property_spec_(\d+). Only one \(name_property\) will be obeyed./
1028
+ end
1029
+ end
1030
+
1031
+ context "default ordering" do
1032
+ before { Chef::Config[:treat_deprecation_warnings_as_errors] = false }
1033
+ with_property ":x, default: 10, #{name}: true" do
1034
+ it "chooses default over #{name}" do
1035
+ expect(resource.x).to eq 10
1036
+ end
1037
+ end
1038
+ with_property ":x, default: nil, #{name}: true" do
1039
+ it "chooses #{name} over default" do
1040
+ expect(resource.x).to eq 'blah'
1041
+ end
1042
+ end
1043
+ with_property ":x, #{name}: true, default: 10" do
1044
+ it "chooses #{name} over default" do
1045
+ expect(resource.x).to eq 'blah'
1046
+ end
1047
+ end
1048
+ with_property ":x, #{name}: true, default: nil" do
1049
+ it "chooses #{name} over default" do
1050
+ expect(resource.x).to eq 'blah'
1051
+ end
1052
+ end
1053
+ end
1054
+
1055
+ context "default ordering when #{name} is nil" do
1056
+ with_property ":x, #{name}: nil, default: 10" do
1057
+ it "chooses default" do
1058
+ expect(resource.x).to eq 10
1059
+ end
1060
+ end
1061
+ with_property ":x, default: 10, #{name}: nil" do
1062
+ it "chooses default" do
1063
+ expect(resource.x).to eq 10
1064
+ end
1065
+ end
1066
+ end
1067
+
1068
+ context "default ordering when #{name} is false" do
1069
+ with_property ":x, #{name}: false, default: 10" do
1070
+ it "chooses default" do
1071
+ expect(resource.x).to eq 10
1072
+ end
1073
+ end
1074
+ with_property ":x, default: 10, #{name}: nil" do
1075
+ it "chooses default" do
1076
+ expect(resource.x).to eq 10
1077
+ end
1078
+ end
1079
+ end
1080
+
1081
+ end
1082
+ end
1083
+
1084
+ it "raises an error if both name_property and name_attribute are specified" do
1085
+ expect { resource_class.property :x, :name_property => false, :name_attribute => 1 }.to raise_error ArgumentError,
1086
+ /Cannot specify both name_property and name_attribute together on property x of resource chef_resource_property_spec_(\d+)./
1087
+ expect { resource_class.property :x, :name_property => false, :name_attribute => nil }.to raise_error ArgumentError,
1088
+ /Cannot specify both name_property and name_attribute together on property x of resource chef_resource_property_spec_(\d+)./
1089
+ expect { resource_class.property :x, :name_property => false, :name_attribute => false }.to raise_error ArgumentError,
1090
+ /Cannot specify both name_property and name_attribute together on property x of resource chef_resource_property_spec_(\d+)./
1091
+ expect { resource_class.property :x, :name_property => true, :name_attribute => true }.to raise_error ArgumentError,
1092
+ /Cannot specify both name_property and name_attribute together on property x of resource chef_resource_property_spec_(\d+)./
1093
+ end
1094
+ end