chefspec 3.1.4 → 3.2.0

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 (532) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +15 -0
  3. data/.travis.yml +39 -0
  4. data/CHANGELOG.md +444 -0
  5. data/CONTRIBUTING.md +52 -0
  6. data/Gemfile +2 -0
  7. data/ISSUES.md +41 -0
  8. data/LICENSE +22 -0
  9. data/README.md +893 -0
  10. data/Rakefile +29 -0
  11. data/chefspec.gemspec +42 -0
  12. data/examples/apt_package/recipes/install.rb +13 -0
  13. data/examples/apt_package/recipes/purge.rb +13 -0
  14. data/examples/apt_package/recipes/reconfig.rb +13 -0
  15. data/examples/apt_package/recipes/remove.rb +13 -0
  16. data/examples/apt_package/recipes/upgrade.rb +13 -0
  17. data/examples/apt_package/spec/install_spec.rb +23 -0
  18. data/examples/apt_package/spec/purge_spec.rb +19 -0
  19. data/examples/apt_package/spec/reconfig_spec.rb +19 -0
  20. data/examples/apt_package/spec/remove_spec.rb +19 -0
  21. data/examples/apt_package/spec/upgrade_spec.rb +19 -0
  22. data/examples/attributes/attributes/default.rb +1 -0
  23. data/examples/attributes/recipes/default.rb +4 -0
  24. data/examples/attributes/spec/default_spec.rb +20 -0
  25. data/examples/batch/recipes/run.rb +13 -0
  26. data/examples/batch/spec/run_spec.rb +23 -0
  27. data/examples/cached/recipes/default.rb +1 -0
  28. data/examples/cached/spec/default_spec.rb +13 -0
  29. data/examples/chef_gem/recipes/install.rb +13 -0
  30. data/examples/chef_gem/recipes/purge.rb +13 -0
  31. data/examples/chef_gem/recipes/reconfig.rb +13 -0
  32. data/examples/chef_gem/recipes/remove.rb +13 -0
  33. data/examples/chef_gem/recipes/upgrade.rb +13 -0
  34. data/examples/chef_gem/spec/install_spec.rb +23 -0
  35. data/examples/chef_gem/spec/purge_spec.rb +19 -0
  36. data/examples/chef_gem/spec/reconfig_spec.rb +19 -0
  37. data/examples/chef_gem/spec/remove_spec.rb +19 -0
  38. data/examples/chef_gem/spec/upgrade_spec.rb +19 -0
  39. data/examples/compile_time/recipes/default.rb +3 -0
  40. data/examples/compile_time/spec/default_spec.rb +27 -0
  41. data/examples/cookbook_file/recipes/create.rb +15 -0
  42. data/examples/cookbook_file/recipes/create_if_missing.rb +15 -0
  43. data/examples/cookbook_file/recipes/delete.rb +15 -0
  44. data/examples/cookbook_file/recipes/touch.rb +15 -0
  45. data/examples/cookbook_file/spec/create_if_missing_spec.rb +28 -0
  46. data/examples/cookbook_file/spec/create_spec.rb +32 -0
  47. data/examples/cookbook_file/spec/delete_spec.rb +19 -0
  48. data/examples/cookbook_file/spec/touch_spec.rb +19 -0
  49. data/examples/cron/recipes/create.rb +10 -0
  50. data/examples/cron/recipes/delete.rb +9 -0
  51. data/examples/cron/spec/create_spec.rb +19 -0
  52. data/examples/cron/spec/delete_spec.rb +15 -0
  53. data/examples/custom_matcher/libraries/matcher.rb +23 -0
  54. data/examples/custom_matcher/providers/thing.rb +2 -0
  55. data/examples/custom_matcher/recipes/install.rb +13 -0
  56. data/examples/custom_matcher/recipes/remove.rb +13 -0
  57. data/examples/custom_matcher/resources/thing.rb +5 -0
  58. data/examples/custom_matcher/spec/install_spec.rb +27 -0
  59. data/examples/custom_matcher/spec/remove_spec.rb +23 -0
  60. data/examples/deploy/recipes/deploy.rb +10 -0
  61. data/examples/deploy/recipes/force_deploy.rb +9 -0
  62. data/examples/deploy/recipes/rollback.rb +9 -0
  63. data/examples/deploy/spec/deploy_spec.rb +15 -0
  64. data/examples/deploy/spec/force_deploy_spec.rb +15 -0
  65. data/examples/deploy/spec/rollback_spec.rb +15 -0
  66. data/examples/directory/recipes/create.rb +14 -0
  67. data/examples/directory/recipes/delete.rb +14 -0
  68. data/examples/directory/spec/create_spec.rb +30 -0
  69. data/examples/directory/spec/delete_spec.rb +26 -0
  70. data/examples/dpkg_package/recipes/install.rb +13 -0
  71. data/examples/dpkg_package/recipes/purge.rb +13 -0
  72. data/examples/dpkg_package/recipes/remove.rb +13 -0
  73. data/examples/dpkg_package/spec/install_spec.rb +23 -0
  74. data/examples/dpkg_package/spec/purge_spec.rb +19 -0
  75. data/examples/dpkg_package/spec/remove_spec.rb +19 -0
  76. data/examples/easy_install_package/recipes/install.rb +13 -0
  77. data/examples/easy_install_package/recipes/purge.rb +13 -0
  78. data/examples/easy_install_package/recipes/remove.rb +13 -0
  79. data/examples/easy_install_package/recipes/upgrade.rb +13 -0
  80. data/examples/easy_install_package/spec/install_spec.rb +23 -0
  81. data/examples/easy_install_package/spec/purge_spec.rb +19 -0
  82. data/examples/easy_install_package/spec/remove_spec.rb +19 -0
  83. data/examples/easy_install_package/spec/upgrade_spec.rb +19 -0
  84. data/examples/env/recipes/create.rb +13 -0
  85. data/examples/env/recipes/delete.rb +13 -0
  86. data/examples/env/recipes/modify.rb +13 -0
  87. data/examples/env/spec/create_spec.rb +23 -0
  88. data/examples/env/spec/delete_spec.rb +19 -0
  89. data/examples/env/spec/modify_spec.rb +19 -0
  90. data/examples/erl_call/recipes/run.rb +13 -0
  91. data/examples/erl_call/spec/run_spec.rb +23 -0
  92. data/examples/execute/recipes/run.rb +13 -0
  93. data/examples/execute/spec/run_spec.rb +23 -0
  94. data/examples/expect_exception/recipes/compile_error.rb +1 -0
  95. data/examples/expect_exception/recipes/converge_error.rb +5 -0
  96. data/examples/expect_exception/recipes/no_error.rb +1 -0
  97. data/examples/expect_exception/spec/compile_error_spec.rb +10 -0
  98. data/examples/expect_exception/spec/converge_error_spec.rb +10 -0
  99. data/examples/expect_exception/spec/no_error_spec.rb +10 -0
  100. data/examples/file/recipes/create.rb +15 -0
  101. data/examples/file/recipes/create_if_missing.rb +15 -0
  102. data/examples/file/recipes/delete.rb +15 -0
  103. data/examples/file/recipes/touch.rb +15 -0
  104. data/examples/file/spec/create_if_missing_spec.rb +28 -0
  105. data/examples/file/spec/create_spec.rb +32 -0
  106. data/examples/file/spec/delete_spec.rb +19 -0
  107. data/examples/file/spec/touch_spec.rb +19 -0
  108. data/examples/freebsd_package/recipes/install.rb +13 -0
  109. data/examples/freebsd_package/recipes/remove.rb +13 -0
  110. data/examples/freebsd_package/spec/install_spec.rb +23 -0
  111. data/examples/freebsd_package/spec/remove_spec.rb +19 -0
  112. data/examples/gem_package/recipes/install.rb +13 -0
  113. data/examples/gem_package/recipes/purge.rb +13 -0
  114. data/examples/gem_package/recipes/reconfig.rb +13 -0
  115. data/examples/gem_package/recipes/remove.rb +13 -0
  116. data/examples/gem_package/recipes/upgrade.rb +13 -0
  117. data/examples/gem_package/spec/install_spec.rb +23 -0
  118. data/examples/gem_package/spec/purge_spec.rb +19 -0
  119. data/examples/gem_package/spec/reconfig_spec.rb +19 -0
  120. data/examples/gem_package/spec/remove_spec.rb +19 -0
  121. data/examples/gem_package/spec/upgrade_spec.rb +19 -0
  122. data/examples/git/recipes/checkout.rb +13 -0
  123. data/examples/git/recipes/export.rb +13 -0
  124. data/examples/git/recipes/sync.rb +13 -0
  125. data/examples/git/spec/checkout_spec.rb +19 -0
  126. data/examples/git/spec/export_spec.rb +19 -0
  127. data/examples/git/spec/sync_spec.rb +23 -0
  128. data/examples/group/recipes/create.rb +13 -0
  129. data/examples/group/recipes/manage.rb +13 -0
  130. data/examples/group/recipes/modify.rb +13 -0
  131. data/examples/group/recipes/remove.rb +13 -0
  132. data/examples/group/spec/create_spec.rb +23 -0
  133. data/examples/group/spec/manage_spec.rb +19 -0
  134. data/examples/group/spec/modify_spec.rb +19 -0
  135. data/examples/group/spec/remove_spec.rb +18 -0
  136. data/examples/guards/recipes/default.rb +13 -0
  137. data/examples/guards/spec/default_spec.rb +17 -0
  138. data/examples/heavy_provider_light_resource/libraries/resource_service.rb +15 -0
  139. data/examples/heavy_provider_light_resource/providers/service.rb +9 -0
  140. data/examples/heavy_provider_light_resource/recipes/default.rb +4 -0
  141. data/examples/heavy_provider_light_resource/spec/provider_service_spec.rb +7 -0
  142. data/examples/http_request/recipes/delete.rb +13 -0
  143. data/examples/http_request/recipes/get.rb +13 -0
  144. data/examples/http_request/recipes/head.rb +13 -0
  145. data/examples/http_request/recipes/options.rb +13 -0
  146. data/examples/http_request/recipes/post.rb +13 -0
  147. data/examples/http_request/recipes/put.rb +13 -0
  148. data/examples/http_request/spec/delete_spec.rb +19 -0
  149. data/examples/http_request/spec/get_spec.rb +23 -0
  150. data/examples/http_request/spec/head_spec.rb +19 -0
  151. data/examples/http_request/spec/options_spec.rb +19 -0
  152. data/examples/http_request/spec/post_spec.rb +19 -0
  153. data/examples/http_request/spec/put_spec.rb +19 -0
  154. data/examples/ifconfig/recipes/add.rb +9 -0
  155. data/examples/ifconfig/recipes/delete.rb +8 -0
  156. data/examples/ifconfig/recipes/disable.rb +8 -0
  157. data/examples/ifconfig/recipes/enable.rb +8 -0
  158. data/examples/ifconfig/spec/add_spec.rb +19 -0
  159. data/examples/ifconfig/spec/delete_spec.rb +15 -0
  160. data/examples/ifconfig/spec/disable_spec.rb +15 -0
  161. data/examples/ifconfig/spec/enable_spec.rb +15 -0
  162. data/examples/include_recipe/recipes/default.rb +1 -0
  163. data/examples/include_recipe/recipes/not.rb +0 -0
  164. data/examples/include_recipe/recipes/other.rb +0 -0
  165. data/examples/include_recipe/spec/default_spec.rb +13 -0
  166. data/examples/inherits/recipes/default.rb +5 -0
  167. data/examples/inherits/spec/default_spec.rb +21 -0
  168. data/examples/ips_package/recipes/install.rb +13 -0
  169. data/examples/ips_package/recipes/remove.rb +13 -0
  170. data/examples/ips_package/recipes/upgrade.rb +13 -0
  171. data/examples/ips_package/spec/install_spec.rb +23 -0
  172. data/examples/ips_package/spec/remove_spec.rb +19 -0
  173. data/examples/ips_package/spec/upgrade_spec.rb +19 -0
  174. data/examples/link/recipes/create.rb +13 -0
  175. data/examples/link/recipes/delete.rb +13 -0
  176. data/examples/link/recipes/link_to.rb +3 -0
  177. data/examples/link/spec/create_spec.rb +23 -0
  178. data/examples/link/spec/delete_spec.rb +19 -0
  179. data/examples/link/spec/link_to_spec.rb +11 -0
  180. data/examples/log/recipes/write.rb +14 -0
  181. data/examples/log/spec/write_spec.rb +24 -0
  182. data/examples/macports_package/recipes/install.rb +13 -0
  183. data/examples/macports_package/recipes/purge.rb +13 -0
  184. data/examples/macports_package/recipes/remove.rb +13 -0
  185. data/examples/macports_package/recipes/upgrade.rb +13 -0
  186. data/examples/macports_package/spec/install_spec.rb +23 -0
  187. data/examples/macports_package/spec/purge_spec.rb +19 -0
  188. data/examples/macports_package/spec/remove_spec.rb +19 -0
  189. data/examples/macports_package/spec/upgrade_spec.rb +19 -0
  190. data/examples/mdadm/recipes/assemble.rb +13 -0
  191. data/examples/mdadm/recipes/create.rb +13 -0
  192. data/examples/mdadm/recipes/stop.rb +13 -0
  193. data/examples/mdadm/spec/assemble_spec.rb +19 -0
  194. data/examples/mdadm/spec/create_spec.rb +23 -0
  195. data/examples/mdadm/spec/stop_spec.rb +19 -0
  196. data/examples/mount/recipes/disable.rb +8 -0
  197. data/examples/mount/recipes/enable.rb +8 -0
  198. data/examples/mount/recipes/mount.rb +9 -0
  199. data/examples/mount/recipes/remount.rb +8 -0
  200. data/examples/mount/recipes/umount.rb +8 -0
  201. data/examples/mount/spec/disable_spec.rb +15 -0
  202. data/examples/mount/spec/enable_spec.rb +15 -0
  203. data/examples/mount/spec/mount_spec.rb +19 -0
  204. data/examples/mount/spec/remount_spec.rb +15 -0
  205. data/examples/mount/spec/umount_spec.rb +15 -0
  206. data/examples/multiple_actions/recipes/default.rb +3 -0
  207. data/examples/multiple_actions/recipes/sequential.rb +7 -0
  208. data/examples/multiple_actions/spec/default_spec.rb +14 -0
  209. data/examples/multiple_actions/spec/sequential_spec.rb +13 -0
  210. data/examples/multiple_run_action/recipes/default.rb +5 -0
  211. data/examples/multiple_run_action/spec/default_spec.rb +18 -0
  212. data/examples/notifications/recipes/chained.rb +12 -0
  213. data/examples/notifications/recipes/default.rb +7 -0
  214. data/examples/notifications/recipes/delayed.rb +7 -0
  215. data/examples/notifications/recipes/immediately.rb +7 -0
  216. data/examples/notifications/spec/chained_spec.rb +21 -0
  217. data/examples/notifications/spec/default_spec.rb +16 -0
  218. data/examples/notifications/spec/delayed_spec.rb +16 -0
  219. data/examples/notifications/spec/immediately_spec.rb +16 -0
  220. data/examples/ohai/recipes/reload.rb +13 -0
  221. data/examples/ohai/spec/reload_spec.rb +23 -0
  222. data/examples/package/recipes/install.rb +13 -0
  223. data/examples/package/recipes/purge.rb +13 -0
  224. data/examples/package/recipes/reconfig.rb +13 -0
  225. data/examples/package/recipes/remove.rb +13 -0
  226. data/examples/package/recipes/upgrade.rb +13 -0
  227. data/examples/package/spec/install_spec.rb +23 -0
  228. data/examples/package/spec/purge_spec.rb +19 -0
  229. data/examples/package/spec/reconfig_spec.rb +19 -0
  230. data/examples/package/spec/remove_spec.rb +19 -0
  231. data/examples/package/spec/upgrade_spec.rb +19 -0
  232. data/examples/pacman_package/recipes/install.rb +13 -0
  233. data/examples/pacman_package/recipes/purge.rb +13 -0
  234. data/examples/pacman_package/recipes/remove.rb +13 -0
  235. data/examples/pacman_package/recipes/upgrade.rb +13 -0
  236. data/examples/pacman_package/spec/install_spec.rb +23 -0
  237. data/examples/pacman_package/spec/purge_spec.rb +19 -0
  238. data/examples/pacman_package/spec/remove_spec.rb +19 -0
  239. data/examples/pacman_package/spec/upgrade_spec.rb +19 -0
  240. data/examples/portage_package/recipes/install.rb +13 -0
  241. data/examples/portage_package/recipes/purge.rb +13 -0
  242. data/examples/portage_package/recipes/remove.rb +13 -0
  243. data/examples/portage_package/recipes/upgrade.rb +13 -0
  244. data/examples/portage_package/spec/install_spec.rb +23 -0
  245. data/examples/portage_package/spec/purge_spec.rb +19 -0
  246. data/examples/portage_package/spec/remove_spec.rb +19 -0
  247. data/examples/portage_package/spec/upgrade_spec.rb +19 -0
  248. data/examples/powershell_script/recipes/run.rb +13 -0
  249. data/examples/powershell_script/spec/run_spec.rb +23 -0
  250. data/examples/registry_key/recipes/create.rb +13 -0
  251. data/examples/registry_key/recipes/create_if_missing.rb +13 -0
  252. data/examples/registry_key/recipes/delete.rb +13 -0
  253. data/examples/registry_key/recipes/delete_key.rb +13 -0
  254. data/examples/registry_key/spec/create_if_missing_spec.rb +19 -0
  255. data/examples/registry_key/spec/create_spec.rb +23 -0
  256. data/examples/registry_key/spec/delete_key_spec.rb +19 -0
  257. data/examples/registry_key/spec/delete_spec.rb +19 -0
  258. data/examples/remote_directory/recipes/create.rb +13 -0
  259. data/examples/remote_directory/recipes/create_if_missing.rb +13 -0
  260. data/examples/remote_directory/recipes/delete.rb +13 -0
  261. data/examples/remote_directory/spec/create_if_missing_spec.rb +19 -0
  262. data/examples/remote_directory/spec/create_spec.rb +23 -0
  263. data/examples/remote_directory/spec/delete_spec.rb +19 -0
  264. data/examples/remote_file/recipes/create.rb +18 -0
  265. data/examples/remote_file/recipes/create_if_missing.rb +16 -0
  266. data/examples/remote_file/recipes/delete.rb +16 -0
  267. data/examples/remote_file/recipes/touch.rb +16 -0
  268. data/examples/remote_file/spec/create_if_missing_spec.rb +19 -0
  269. data/examples/remote_file/spec/create_spec.rb +23 -0
  270. data/examples/remote_file/spec/delete_spec.rb +19 -0
  271. data/examples/remote_file/spec/touch_spec.rb +19 -0
  272. data/examples/render_file/files/default/cookbook_file +1 -0
  273. data/examples/render_file/recipes/default.rb +15 -0
  274. data/examples/render_file/recipes/template_helpers.rb +9 -0
  275. data/examples/render_file/spec/default_spec.rb +73 -0
  276. data/examples/render_file/spec/template_helpers_spec.rb +10 -0
  277. data/examples/render_file/templates/default/_partial.erb +1 -0
  278. data/examples/render_file/templates/default/partial.erb +1 -0
  279. data/examples/render_file/templates/default/template.erb +1 -0
  280. data/examples/render_file/templates/default/template_with_helper.erb +1 -0
  281. data/examples/roles/recipes/another.rb +3 -0
  282. data/examples/roles/recipes/default.rb +1 -0
  283. data/examples/roles/roles/role.rb +9 -0
  284. data/examples/roles/spec/default_spec.rb +21 -0
  285. data/examples/route/recipes/add.rb +13 -0
  286. data/examples/route/recipes/delete.rb +13 -0
  287. data/examples/route/spec/add_spec.rb +23 -0
  288. data/examples/route/spec/delete_spec.rb +19 -0
  289. data/examples/rpm_package/recipes/install.rb +13 -0
  290. data/examples/rpm_package/recipes/remove.rb +13 -0
  291. data/examples/rpm_package/recipes/upgrade.rb +13 -0
  292. data/examples/rpm_package/spec/install_spec.rb +23 -0
  293. data/examples/rpm_package/spec/remove_spec.rb +19 -0
  294. data/examples/rpm_package/spec/upgrade_spec.rb +19 -0
  295. data/examples/ruby_block/recipes/run.rb +9 -0
  296. data/examples/ruby_block/spec/run_spec.rb +18 -0
  297. data/examples/script/recipes/run_bash.rb +13 -0
  298. data/examples/script/recipes/run_csh.rb +13 -0
  299. data/examples/script/recipes/run_perl.rb +13 -0
  300. data/examples/script/recipes/run_python.rb +13 -0
  301. data/examples/script/recipes/run_ruby.rb +13 -0
  302. data/examples/script/recipes/run_script.rb +13 -0
  303. data/examples/script/spec/run_bash_spec.rb +23 -0
  304. data/examples/script/spec/run_csh_spec.rb +23 -0
  305. data/examples/script/spec/run_perl_spec.rb +23 -0
  306. data/examples/script/spec/run_python_spec.rb +23 -0
  307. data/examples/script/spec/run_ruby_spec.rb +23 -0
  308. data/examples/script/spec/run_script_spec.rb +23 -0
  309. data/examples/server/recipes/client.rb +6 -0
  310. data/examples/server/recipes/data_bag.rb +7 -0
  311. data/examples/server/recipes/environment.rb +6 -0
  312. data/examples/server/recipes/node.rb +6 -0
  313. data/examples/server/recipes/role.rb +6 -0
  314. data/examples/server/recipes/search.rb +5 -0
  315. data/examples/server/spec/client_spec.rb +17 -0
  316. data/examples/server/spec/data_bag_spec.rb +26 -0
  317. data/examples/server/spec/environment_spec.rb +17 -0
  318. data/examples/server/spec/node_spec.rb +40 -0
  319. data/examples/server/spec/role_spec.rb +17 -0
  320. data/examples/server/spec/search_spec.rb +58 -0
  321. data/examples/service/recipes/disable.rb +13 -0
  322. data/examples/service/recipes/enable.rb +13 -0
  323. data/examples/service/recipes/reload.rb +13 -0
  324. data/examples/service/recipes/restart.rb +13 -0
  325. data/examples/service/recipes/start.rb +13 -0
  326. data/examples/service/recipes/stop.rb +13 -0
  327. data/examples/service/spec/disable_spec.rb +19 -0
  328. data/examples/service/spec/enable_spec.rb +19 -0
  329. data/examples/service/spec/reload_spec.rb +19 -0
  330. data/examples/service/spec/restart_spec.rb +19 -0
  331. data/examples/service/spec/start_spec.rb +19 -0
  332. data/examples/service/spec/stop_spec.rb +19 -0
  333. data/examples/smartos_package/recipes/install.rb +13 -0
  334. data/examples/smartos_package/recipes/remove.rb +13 -0
  335. data/examples/smartos_package/recipes/upgrade.rb +13 -0
  336. data/examples/smartos_package/spec/install_spec.rb +23 -0
  337. data/examples/smartos_package/spec/remove_spec.rb +19 -0
  338. data/examples/smartos_package/spec/upgrade_spec.rb +19 -0
  339. data/examples/solaris_package/recipes/install.rb +13 -0
  340. data/examples/solaris_package/recipes/remove.rb +13 -0
  341. data/examples/solaris_package/spec/install_spec.rb +23 -0
  342. data/examples/solaris_package/spec/remove_spec.rb +19 -0
  343. data/examples/state_attrs/providers/lwrp.rb +3 -0
  344. data/examples/state_attrs/recipes/default.rb +3 -0
  345. data/examples/state_attrs/resources/lwrp.rb +6 -0
  346. data/examples/state_attrs/spec/default_spec.rb +12 -0
  347. data/examples/step_into/providers/lwrp.rb +3 -0
  348. data/examples/step_into/recipes/default.rb +1 -0
  349. data/examples/step_into/resources/lwrp.rb +4 -0
  350. data/examples/step_into/spec/default_spec.rb +19 -0
  351. data/examples/stub_command/recipes/default.rb +5 -0
  352. data/examples/stub_command/recipes/other_recipe.rb +3 -0
  353. data/examples/stub_command/spec/default_spec.rb +28 -0
  354. data/examples/stub_data_bag/recipes/default.rb +5 -0
  355. data/examples/stub_data_bag/spec/default_spec.rb +27 -0
  356. data/examples/stub_data_bag_item/recipes/default.rb +5 -0
  357. data/examples/stub_data_bag_item/spec/default_spec.rb +27 -0
  358. data/examples/stub_node/recipes/default.rb +0 -0
  359. data/examples/stub_node/spec/default_spec.rb +17 -0
  360. data/examples/stub_search/recipes/default.rb +5 -0
  361. data/examples/stub_search/spec/default_spec.rb +27 -0
  362. data/examples/subscribes/recipes/chained.rb +10 -0
  363. data/examples/subscribes/recipes/default.rb +5 -0
  364. data/examples/subscribes/recipes/delayed.rb +5 -0
  365. data/examples/subscribes/recipes/immediately.rb +5 -0
  366. data/examples/subscribes/spec/chained_spec.rb +21 -0
  367. data/examples/subscribes/spec/default_spec.rb +17 -0
  368. data/examples/subscribes/spec/delayed_spec.rb +16 -0
  369. data/examples/subscribes/spec/immediately_spec.rb +16 -0
  370. data/examples/subversion/recipes/checkout.rb +13 -0
  371. data/examples/subversion/recipes/export.rb +13 -0
  372. data/examples/subversion/recipes/force_export.rb +13 -0
  373. data/examples/subversion/recipes/sync.rb +13 -0
  374. data/examples/subversion/spec/checkout_spec.rb +19 -0
  375. data/examples/subversion/spec/export_spec.rb +19 -0
  376. data/examples/subversion/spec/force_export_spec.rb +19 -0
  377. data/examples/subversion/spec/sync_spec.rb +23 -0
  378. data/examples/template/recipes/create.rb +15 -0
  379. data/examples/template/recipes/create_if_missing.rb +15 -0
  380. data/examples/template/recipes/delete.rb +15 -0
  381. data/examples/template/recipes/touch.rb +15 -0
  382. data/examples/template/spec/create_if_missing_spec.rb +28 -0
  383. data/examples/template/spec/create_spec.rb +32 -0
  384. data/examples/template/spec/delete_spec.rb +19 -0
  385. data/examples/template/spec/touch_spec.rb +19 -0
  386. data/examples/use_inline_resources/libraries/matchers.rb +5 -0
  387. data/examples/use_inline_resources/providers/lwrp.rb +7 -0
  388. data/examples/use_inline_resources/recipes/default.rb +1 -0
  389. data/examples/use_inline_resources/resources/lwrp.rb +4 -0
  390. data/examples/use_inline_resources/spec/default_spec.rb +15 -0
  391. data/examples/user/recipes/create.rb +13 -0
  392. data/examples/user/recipes/lock.rb +13 -0
  393. data/examples/user/recipes/manage.rb +13 -0
  394. data/examples/user/recipes/modify.rb +13 -0
  395. data/examples/user/recipes/remove.rb +13 -0
  396. data/examples/user/recipes/unlock.rb +13 -0
  397. data/examples/user/spec/create_spec.rb +23 -0
  398. data/examples/user/spec/lock_spec.rb +19 -0
  399. data/examples/user/spec/manage_spec.rb +19 -0
  400. data/examples/user/spec/modify_spec.rb +19 -0
  401. data/examples/user/spec/remove_spec.rb +19 -0
  402. data/examples/user/spec/unlock_spec.rb +19 -0
  403. data/examples/yum_package/recipes/install.rb +13 -0
  404. data/examples/yum_package/recipes/purge.rb +13 -0
  405. data/examples/yum_package/recipes/remove.rb +13 -0
  406. data/examples/yum_package/recipes/upgrade.rb +13 -0
  407. data/examples/yum_package/spec/install_spec.rb +23 -0
  408. data/examples/yum_package/spec/purge_spec.rb +19 -0
  409. data/examples/yum_package/spec/remove_spec.rb +19 -0
  410. data/examples/yum_package/spec/upgrade_spec.rb +19 -0
  411. data/features/apt_package.feature +14 -0
  412. data/features/attributes.feature +7 -0
  413. data/features/batch.feature +13 -0
  414. data/features/cached.feature +7 -0
  415. data/features/chef_gem.feature +14 -0
  416. data/features/compile_time.feature +7 -0
  417. data/features/cookbook_file.feature +13 -0
  418. data/features/cron.feature +11 -0
  419. data/features/custom_matcher.feature +11 -0
  420. data/features/deploy.feature +12 -0
  421. data/features/directory.feature +11 -0
  422. data/features/dpkg_package.feature +12 -0
  423. data/features/easy_install_package.feature +13 -0
  424. data/features/env.feature +12 -0
  425. data/features/erl_call.feature +10 -0
  426. data/features/execute.feature +10 -0
  427. data/features/expect_exception.feature +12 -0
  428. data/features/file.feature +13 -0
  429. data/features/freebsd_package.feature +11 -0
  430. data/features/gem_package.feature +14 -0
  431. data/features/git.feature +12 -0
  432. data/features/group.feature +13 -0
  433. data/features/guards.feature +10 -0
  434. data/features/heavy_provider_light_resource.feature +10 -0
  435. data/features/http_request.feature +15 -0
  436. data/features/ifconfig.feature +13 -0
  437. data/features/include_recipe.feature +10 -0
  438. data/features/inherits.feature +7 -0
  439. data/features/ips_package.feature +12 -0
  440. data/features/link.feature +12 -0
  441. data/features/log.feature +10 -0
  442. data/features/macports_package.feature +13 -0
  443. data/features/mdadm.feature +12 -0
  444. data/features/mount.feature +14 -0
  445. data/features/multiple_actions.feature +11 -0
  446. data/features/multiple_run_action.feature +7 -0
  447. data/features/notifications.feature +13 -0
  448. data/features/ohai.feature +10 -0
  449. data/features/package.feature +14 -0
  450. data/features/pacman_package.feature +13 -0
  451. data/features/portage_package.feature +13 -0
  452. data/features/powershell_script.feature +13 -0
  453. data/features/registry_key.feature +13 -0
  454. data/features/remote_directory.feature +12 -0
  455. data/features/remote_file.feature +13 -0
  456. data/features/render_file.feature +16 -0
  457. data/features/roles.feature +7 -0
  458. data/features/route.feature +11 -0
  459. data/features/rpm_package.feature +12 -0
  460. data/features/ruby_block.feature +10 -0
  461. data/features/script.feature +15 -0
  462. data/features/server.feature +21 -0
  463. data/features/service.feature +15 -0
  464. data/features/smartos_package.feature +16 -0
  465. data/features/solaris_package.feature +15 -0
  466. data/features/state_attrs.feature +11 -0
  467. data/features/step_definitions/background_steps.rb +4 -0
  468. data/features/step_into.feature +7 -0
  469. data/features/stub_command.feature +7 -0
  470. data/features/stub_data_bag.feature +7 -0
  471. data/features/stub_data_bag_item.feature +7 -0
  472. data/features/stub_node.feature +7 -0
  473. data/features/stub_search.feature +7 -0
  474. data/features/subscribes.feature +13 -0
  475. data/features/subversion.feature +13 -0
  476. data/features/support/env.rb +36 -0
  477. data/features/support/executor.rb +18 -0
  478. data/features/template.feature +13 -0
  479. data/features/use_inline_resources.feature +7 -0
  480. data/features/user.feature +15 -0
  481. data/features/yum_package.feature +13 -0
  482. data/gemfiles/chef-11.0.0.gemfile +5 -0
  483. data/gemfiles/chef-11.2.0.gemfile +5 -0
  484. data/gemfiles/chef-11.4.4.gemfile +5 -0
  485. data/gemfiles/chef-11.6.0.gemfile +5 -0
  486. data/gemfiles/chef-11.8.0.gemfile +5 -0
  487. data/gemfiles/chef-master.gemfile +5 -0
  488. data/lib/chefspec/api.rb +13 -11
  489. data/lib/chefspec/api/notifications.rb +3 -3
  490. data/lib/chefspec/api/subscriptions.rb +35 -0
  491. data/lib/chefspec/coverage.rb +40 -34
  492. data/lib/chefspec/expect_exception.rb +14 -13
  493. data/lib/chefspec/formatter.rb +8 -8
  494. data/lib/chefspec/matchers.rb +1 -0
  495. data/lib/chefspec/matchers/include_recipe_matcher.rb +19 -18
  496. data/lib/chefspec/matchers/notifications_matcher.rb +25 -24
  497. data/lib/chefspec/matchers/render_file_matcher.rb +32 -31
  498. data/lib/chefspec/matchers/resource_matcher.rb +64 -63
  499. data/lib/chefspec/matchers/state_attrs_matcher.rb +18 -17
  500. data/lib/chefspec/matchers/subscribes_matcher.rb +59 -0
  501. data/lib/chefspec/renderer.rb +82 -81
  502. data/lib/chefspec/runner.rb +66 -51
  503. data/lib/chefspec/server.rb +84 -39
  504. data/lib/chefspec/stubs/stub.rb +10 -9
  505. data/lib/chefspec/version.rb +1 -1
  506. data/spec/spec_helper.rb +8 -0
  507. data/spec/support/hash.rb +35 -0
  508. data/spec/unit/api_spec.rb +18 -0
  509. data/spec/unit/cacher_spec.rb +54 -0
  510. data/spec/unit/expect_exception_spec.rb +32 -0
  511. data/spec/unit/extensions/lwrp_base_spec.rb +89 -0
  512. data/spec/unit/macros_spec.rb +119 -0
  513. data/spec/unit/matchers/include_recipe_matcher_spec.rb +38 -0
  514. data/spec/unit/matchers/link_to_matcher_spec.rb +39 -0
  515. data/spec/unit/matchers/notifications_matcher_spec.rb +5 -0
  516. data/spec/unit/matchers/render_file_matcher_spec.rb +41 -0
  517. data/spec/unit/matchers/resource_matcher_spec.rb +5 -0
  518. data/spec/unit/matchers/state_attrs_matcher_spec.rb +64 -0
  519. data/spec/unit/matchers/subscribes_matcher_spec.rb +5 -0
  520. data/spec/unit/renderer_spec.rb +51 -0
  521. data/spec/unit/runner_spec.rb +125 -0
  522. data/spec/unit/stubs/command_registry_spec.rb +27 -0
  523. data/spec/unit/stubs/command_stub_spec.rb +61 -0
  524. data/spec/unit/stubs/data_bag_item_registry_spec.rb +39 -0
  525. data/spec/unit/stubs/data_bag_item_stub_spec.rb +36 -0
  526. data/spec/unit/stubs/data_bag_registry_spec.rb +39 -0
  527. data/spec/unit/stubs/data_bag_stub_spec.rb +35 -0
  528. data/spec/unit/stubs/registry_spec.rb +29 -0
  529. data/spec/unit/stubs/search_registry_spec.rb +39 -0
  530. data/spec/unit/stubs/search_stub_spec.rb +36 -0
  531. data/spec/unit/stubs/stub_spec.rb +64 -0
  532. metadata +618 -5
@@ -0,0 +1,5 @@
1
+ source 'https://rubygems.org'
2
+
3
+ gem 'chef', '11.2.0'
4
+
5
+ gemspec :path => '..'
@@ -0,0 +1,5 @@
1
+ source 'https://rubygems.org'
2
+
3
+ gem 'chef', '11.4.4'
4
+
5
+ gemspec :path => '..'
@@ -0,0 +1,5 @@
1
+ source 'https://rubygems.org'
2
+
3
+ gem 'chef', '11.6.0'
4
+
5
+ gemspec :path => '..'
@@ -0,0 +1,5 @@
1
+ source 'https://rubygems.org'
2
+
3
+ gem 'chef', '11.8.0'
4
+
5
+ gemspec :path => '..'
@@ -0,0 +1,5 @@
1
+ source 'https://rubygems.org'
2
+
3
+ gem 'chef', :github => 'opscode/chef'
4
+
5
+ gemspec :path => '..'
@@ -11,17 +11,18 @@ module ChefSpec
11
11
  end
12
12
 
13
13
  private
14
- #
15
- # WARNING: This is metaprogramming madness. Find all modules who are
16
- # nested beneath this module.
17
- #
18
- # @return [Array<Module>]
19
- #
20
- def submodules
21
- self.constants
22
- .map { |name| const_get(name) }
23
- .select { |const| const.class == Module }
24
- end
14
+
15
+ #
16
+ # WARNING: This is metaprogramming madness. Find all modules who are
17
+ # nested beneath this module.
18
+ #
19
+ # @return [Array<Module>]
20
+ #
21
+ def submodules
22
+ self.constants
23
+ .map { |name| const_get(name) }
24
+ .select { |const| const.class == Module }
25
+ end
25
26
  end
26
27
  end
27
28
 
@@ -69,6 +70,7 @@ require_relative 'api/service'
69
70
  require_relative 'api/smartos_package'
70
71
  require_relative 'api/solaris_package'
71
72
  require_relative 'api/state_attrs'
73
+ require_relative 'api/subscriptions'
72
74
  require_relative 'api/subversion'
73
75
  require_relative 'api/template'
74
76
  require_relative 'api/user'
@@ -5,12 +5,12 @@ module ChefSpec::API
5
5
  # Assert that a resource notifies another. Given a Chef Recipe that
6
6
  # notifies a template resource to restart apache:
7
7
  #
8
- # ifconfig '10.0.0.1' do
9
- # action :add
8
+ # template '/etc/apache2/config' do
9
+ # notifies :restart, 'service[apache2]'
10
10
  # end
11
11
  #
12
12
  # The Examples section demonstrates the different ways to test an
13
- # +ifconfig+ resource with ChefSpec.
13
+ # notifications on a resource with ChefSpec.
14
14
  #
15
15
  # @example Assert the template notifies apache of something
16
16
  # template = chef_run.template('/etc/apache2.conf')
@@ -0,0 +1,35 @@
1
+ module ChefSpec::API
2
+ # @since 3.2.0
3
+ module SubscriptionsMatchers
4
+ #
5
+ # Assert that a resource subscribes to another. Given a Chef Recipe that
6
+ # subscribes a template resource to restart apache:
7
+ #
8
+ # service 'apache2' do
9
+ # subscribes :create, 'template[/etc/apache2/config]'
10
+ # end
11
+ #
12
+ # The Examples section demonstrates the different ways to test a
13
+ # subscription on a resource with ChefSpec.
14
+ #
15
+ # @example Assert a basic subscription
16
+ # service = chef_run.service('apache2')
17
+ # expect(service).to subscribe_to('template[/etc/apache2/config]')
18
+ #
19
+ # @example Assert a subscription with specified action
20
+ # expect(service).to subscribe_to('template[/etc/apache2/config]').on(:restart)
21
+ #
22
+ # @example Assert a subscription with specified action and timing
23
+ # expect(service).to subscribe_to('template[/etc/apache2/config]').on(:restart).immediately
24
+ #
25
+ #
26
+ # @param [String] signature
27
+ # the signature of the notification to match
28
+ #
29
+ # @return [ChefSpec::Matchers::NotificationsMatcher]
30
+ #
31
+ def subscribe_to(signature)
32
+ ChefSpec::Matchers::SubscribesMatcher.new(signature)
33
+ end
34
+ end
35
+ end
@@ -74,6 +74,12 @@ module ChefSpec
74
74
  report = {}
75
75
 
76
76
  report[:total] = @collection.size
77
+
78
+ if report[:total] == 0
79
+ puts 'No resources found, skipping coverage calculation'
80
+ return
81
+ end
82
+
77
83
  report[:touched] = @collection.count { |_, resource| resource.touched? }
78
84
  report[:untouched] = report[:total] - report[:touched]
79
85
  report[:coverage] = ((report[:touched].to_f/report[:total].to_f)*100).round(2)
@@ -118,49 +124,49 @@ module ChefSpec
118
124
 
119
125
  private
120
126
 
121
- def find(resource)
122
- @collection[resource.to_s]
123
- end
127
+ def find(resource)
128
+ @collection[resource.to_s]
129
+ end
124
130
 
125
- def exists?(resource)
126
- !find(resource).nil?
127
- end
131
+ def exists?(resource)
132
+ !find(resource).nil?
133
+ end
128
134
 
129
- class ResourceWrapper
130
- attr_reader :resource
135
+ class ResourceWrapper
136
+ attr_reader :resource
131
137
 
132
- def initialize(resource = nil)
133
- @resource = resource
134
- end
138
+ def initialize(resource = nil)
139
+ @resource = resource
140
+ end
135
141
 
136
- def to_s
137
- @resource.to_s
138
- end
142
+ def to_s
143
+ @resource.to_s
144
+ end
139
145
 
140
- def source
141
- return {} unless @resource.source_line
142
- file, line, *_ = @resource.source_line.split(':')
146
+ def source
147
+ return {} unless @resource.source_line
148
+ file, line, *_ = @resource.source_line.split(':')
143
149
 
144
- {
145
- file: file,
146
- line: line.to_i,
147
- }
148
- end
150
+ {
151
+ file: file,
152
+ line: line.to_i,
153
+ }
154
+ end
149
155
 
150
- def to_hash
151
- {
152
- source: source,
153
- touched: touched?,
154
- }
155
- end
156
+ def to_hash
157
+ {
158
+ source: source,
159
+ touched: touched?,
160
+ }
161
+ end
156
162
 
157
- def touch!
158
- @touched = true
159
- end
163
+ def touch!
164
+ @touched = true
165
+ end
160
166
 
161
- def touched?
162
- !!@touched
163
- end
167
+ def touched?
168
+ !!@touched
164
169
  end
170
+ end
165
171
  end
166
172
  end
@@ -26,20 +26,21 @@ module ChefSpec
26
26
  end
27
27
 
28
28
  private
29
- def exception_matched?
30
- @formatter_exception == @matcher.expected_error ||
31
- @matcher.expected_error === @formatter_exception
32
- end
33
29
 
34
- def message_matched?
35
- case @formatter_message
36
- when nil
37
- true
38
- when Regexp
39
- @matcher.expected_message =~ @formatter_message
40
- else
41
- @matcher.expected_message == @formatter_message
42
- end
30
+ def exception_matched?
31
+ @formatter_exception == @matcher.expected_error ||
32
+ @matcher.expected_error === @formatter_exception
33
+ end
34
+
35
+ def message_matched?
36
+ case @formatter_message
37
+ when nil
38
+ true
39
+ when Regexp
40
+ @matcher.expected_message =~ @formatter_message
41
+ else
42
+ @matcher.expected_message == @formatter_message
43
43
  end
44
+ end
44
45
  end
45
46
  end
@@ -255,16 +255,16 @@ module ChefSpec
255
255
  def msg(message); end
256
256
 
257
257
  private
258
- def file_load_failed(path, exception)
259
- expecting_exception(exception) do
260
- description = Chef::Formatters::ErrorMapper.file_load_failed(path, exception)
261
- display_error(description)
262
- end
263
- end
264
258
 
265
- def expecting_exception(exception, &block)
266
- yield unless ChefSpec::ExpectException.new(exception).expected?
259
+ def file_load_failed(path, exception)
260
+ expecting_exception(exception) do
261
+ description = Chef::Formatters::ErrorMapper.file_load_failed(path, exception)
262
+ display_error(description)
267
263
  end
264
+ end
268
265
 
266
+ def expecting_exception(exception, &block)
267
+ yield unless ChefSpec::ExpectException.new(exception).expected?
268
+ end
269
269
  end
270
270
  end
@@ -6,5 +6,6 @@ module ChefSpec
6
6
  require_relative 'matchers/render_file_matcher'
7
7
  require_relative 'matchers/resource_matcher'
8
8
  require_relative 'matchers/state_attrs_matcher'
9
+ require_relative 'matchers/subscribes_matcher'
9
10
  end
10
11
  end
@@ -22,24 +22,25 @@ module ChefSpec::Matchers
22
22
  end
23
23
 
24
24
  private
25
- #
26
- # Automatically appends "+::default+" to recipes that need them.
27
- #
28
- # @param [String] name
29
- #
30
- # @return [String]
31
- #
32
- def with_default(name)
33
- name.include?('::') ? name : "#{name}::default"
34
- end
35
25
 
36
- #
37
- # The list of loaded recipes on the Chef run (normalized)
38
- #
39
- # @return [Array<String>]
40
- #
41
- def loaded_recipes
42
- @runner.run_context.loaded_recipes.map { |name| with_default(name) }
43
- end
26
+ #
27
+ # Automatically appends "+::default+" to recipes that need them.
28
+ #
29
+ # @param [String] name
30
+ #
31
+ # @return [String]
32
+ #
33
+ def with_default(name)
34
+ name.include?('::') ? name : "#{name}::default"
35
+ end
36
+
37
+ #
38
+ # The list of loaded recipes on the Chef run (normalized)
39
+ #
40
+ # @return [Array<String>]
41
+ #
42
+ def loaded_recipes
43
+ @runner.run_context.loaded_recipes.map { |name| with_default(name) }
44
+ end
44
45
  end
45
46
  end
@@ -78,35 +78,36 @@ module ChefSpec::Matchers
78
78
  end
79
79
 
80
80
  private
81
- def all_notifications
82
- immediate_notifications + delayed_notifications
83
- end
84
81
 
85
- def immediate_notifications
86
- @resource.immediate_notifications
87
- end
82
+ def all_notifications
83
+ immediate_notifications + delayed_notifications
84
+ end
88
85
 
89
- def delayed_notifications
90
- @resource.delayed_notifications
91
- end
86
+ def immediate_notifications
87
+ @resource.immediate_notifications
88
+ end
92
89
 
93
- def matches_action?(notification)
94
- return true if @action.nil?
95
- @action == notification.action.to_sym
96
- end
90
+ def delayed_notifications
91
+ @resource.delayed_notifications
92
+ end
97
93
 
98
- def format_notification(notification)
99
- notifying_resource = notification.notifying_resource
100
- resource = notification.resource
101
- type = notification.notifying_resource.immediate_notifications.include?(notification) ? :immediately : :delayed
94
+ def matches_action?(notification)
95
+ return true if @action.nil?
96
+ @action == notification.action.to_sym
97
+ end
102
98
 
103
- %Q{ "#{notifying_resource.to_s}" notifies "#{resource_name(resource)}[#{resource.name}]" to :#{notification.action}, :#{type}}
104
- end
99
+ def format_notification(notification)
100
+ notifying_resource = notification.notifying_resource
101
+ resource = notification.resource
102
+ type = notification.notifying_resource.immediate_notifications.include?(notification) ? :immediately : :delayed
105
103
 
106
- def format_notifications
107
- all_notifications.map do |notification|
108
- ' ' + format_notification(notification)
109
- end.join("\n")
110
- end
104
+ %Q{ "#{notifying_resource.to_s}" notifies "#{resource_name(resource)}[#{resource.name}]" to :#{notification.action}, :#{type}}
105
+ end
106
+
107
+ def format_notifications
108
+ all_notifications.map do |notification|
109
+ ' ' + format_notification(notification)
110
+ end.join("\n")
111
+ end
111
112
  end
112
113
  end
@@ -54,42 +54,43 @@ module ChefSpec::Matchers
54
54
  end
55
55
 
56
56
  private
57
- def resource
58
- @resource ||= @runner.find_resource(:cookbook_file, @path) ||
59
- @runner.find_resource(:file, @path) ||
60
- @runner.find_resource(:template, @path)
61
- end
62
57
 
63
- #
64
- # Determines if the given resource has a create-like action.
65
- #
66
- # @param [Chef::Resource] resource
67
- #
68
- # @return [Boolean]
69
- #
70
- def has_create_action?
71
- [:create, :create_if_missing].any? { |action| resource.performed_action?(action) }
72
- end
58
+ def resource
59
+ @resource ||= @runner.find_resource(:cookbook_file, @path) ||
60
+ @runner.find_resource(:file, @path) ||
61
+ @runner.find_resource(:template, @path)
62
+ end
63
+
64
+ #
65
+ # Determines if the given resource has a create-like action.
66
+ #
67
+ # @param [Chef::Resource] resource
68
+ #
69
+ # @return [Boolean]
70
+ #
71
+ def has_create_action?
72
+ [:create, :create_if_missing].any? { |action| resource.performed_action?(action) }
73
+ end
73
74
 
74
- #
75
- # Determines if the resources content matches the expected content.
76
- #
77
- # @param [Chef::Resource] resource
78
- #
79
- # @return [Boolean]
80
- #
81
- def matches_content?
82
- return true if @expected_content.nil?
75
+ #
76
+ # Determines if the resources content matches the expected content.
77
+ #
78
+ # @param [Chef::Resource] resource
79
+ #
80
+ # @return [Boolean]
81
+ #
82
+ def matches_content?
83
+ return true if @expected_content.nil?
83
84
 
84
- @actual_content = ChefSpec::Renderer.new(@runner, resource).content
85
+ @actual_content = ChefSpec::Renderer.new(@runner, resource).content
85
86
 
86
- return false if @actual_content.nil?
87
+ return false if @actual_content.nil?
87
88
 
88
- if @expected_content.is_a?(Regexp)
89
- @actual_content =~ @expected_content
90
- else
91
- @actual_content.include?(@expected_content)
92
- end
89
+ if @expected_content.is_a?(Regexp)
90
+ @actual_content =~ @expected_content
91
+ else
92
+ @actual_content.include?(@expected_content)
93
93
  end
94
+ end
94
95
  end
95
96
  end