foodcritic 15.0.0 → 15.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (233) hide show
  1. checksums.yaml +4 -4
  2. data/chef_dsl_metadata/{chef_14.7.17.json → chef_14.8.12.json} +61 -1
  3. data/foodcritic.gemspec +1 -3
  4. data/lib/foodcritic/linter.rb +1 -1
  5. data/lib/foodcritic/version.rb +1 -1
  6. metadata +5 -232
  7. data/Rakefile +0 -73
  8. data/features/002_check_string_interpolation.feature +0 -50
  9. data/features/005_check_for_resource_repetition.feature +0 -64
  10. data/features/006_check_file_mode.feature +0 -36
  11. data/features/009_check_for_unrecognised_resource_attributes.feature +0 -55
  12. data/features/014_check_for_long_ruby_blocks.feature +0 -30
  13. data/features/018_check_for_old_lwrp_notification_syntax.feature +0 -25
  14. data/features/019_check_for_consistent_node_access.feature +0 -108
  15. data/features/021_check_for_dodgy_lwrp_conditions.feature +0 -28
  16. data/features/022_check_for_dodgy_conditions_within_loop.feature +0 -43
  17. data/features/024_check_for_missing_platforms.feature +0 -43
  18. data/features/027_check_for_internal_attribute_use.feature +0 -22
  19. data/features/030_check_for_debugger_breakpoints.feature +0 -25
  20. data/features/032_check_for_invalid_notification_timing.feature +0 -24
  21. data/features/033_check_for_missing_template.feature +0 -39
  22. data/features/034_check_for_unused_template_variables.feature +0 -80
  23. data/features/037_check_for_invalid_notification_action.feature +0 -34
  24. data/features/038_check_for_invalid_action.feature +0 -39
  25. data/features/039_check_for_key_access_to_node_methods.feature +0 -33
  26. data/features/044_check_for_bare_attribute_keys.feature +0 -53
  27. data/features/046_check_for_assign_unless_nil_attributes.feature +0 -21
  28. data/features/047_check_for_attribute_assignment_without_precedence.feature +0 -49
  29. data/features/051_check_for_template_partial_loops.feature +0 -40
  30. data/features/build_framework_support.feature +0 -109
  31. data/features/checking_all_types_of_file.feature +0 -40
  32. data/features/choose_rules_to_apply.feature +0 -47
  33. data/features/command_line_help.feature +0 -58
  34. data/features/continuous_integration_support.feature +0 -33
  35. data/features/exclude_paths_to_lint.feature +0 -12
  36. data/features/ignore_via_line_comments.feature +0 -69
  37. data/features/include_custom_rules.feature +0 -29
  38. data/features/individual_file.feature +0 -28
  39. data/features/limit_rules_to_specific_versions.feature +0 -65
  40. data/features/multiple_paths.feature +0 -35
  41. data/features/show_lines_matched.feature +0 -20
  42. data/features/sort_warnings.feature +0 -10
  43. data/features/specify_search_grammar.feature +0 -25
  44. data/features/step_definitions/cookbook_steps.rb +0 -1826
  45. data/features/support/command_helpers.rb +0 -418
  46. data/features/support/cookbook_helpers.rb +0 -599
  47. data/features/support/env.rb +0 -19
  48. data/man/foodcritic.1.ronn +0 -76
  49. data/spec/functional/fc001_spec.rb +0 -72
  50. data/spec/functional/fc004_spec.rb +0 -84
  51. data/spec/functional/fc007_spec.rb +0 -127
  52. data/spec/functional/fc008_spec.rb +0 -33
  53. data/spec/functional/fc009_spec.rb +0 -37
  54. data/spec/functional/fc010_spec.rb +0 -32
  55. data/spec/functional/fc011_spec.rb +0 -20
  56. data/spec/functional/fc013_spec.rb +0 -39
  57. data/spec/functional/fc015_spec.rb +0 -19
  58. data/spec/functional/fc016_spec.rb +0 -57
  59. data/spec/functional/fc025_spec.rb +0 -60
  60. data/spec/functional/fc026_spec.rb +0 -66
  61. data/spec/functional/fc028_spec.rb +0 -93
  62. data/spec/functional/fc029_spec.rb +0 -33
  63. data/spec/functional/fc031_spec.rb +0 -14
  64. data/spec/functional/fc037_spec.rb +0 -75
  65. data/spec/functional/fc038_spec.rb +0 -28
  66. data/spec/functional/fc040_spec.rb +0 -156
  67. data/spec/functional/fc041_spec.rb +0 -121
  68. data/spec/functional/fc042_spec.rb +0 -13
  69. data/spec/functional/fc043_spec.rb +0 -28
  70. data/spec/functional/fc045_spec.rb +0 -18
  71. data/spec/functional/fc048_spec.rb +0 -67
  72. data/spec/functional/fc049_spec.rb +0 -56
  73. data/spec/functional/fc050_spec.rb +0 -85
  74. data/spec/functional/fc052_spec.rb +0 -13
  75. data/spec/functional/fc053_spec.rb +0 -13
  76. data/spec/functional/fc055_spec.rb +0 -18
  77. data/spec/functional/fc056_spec.rb +0 -18
  78. data/spec/functional/fc058_spec.rb +0 -102
  79. data/spec/functional/fc060_spec.rb +0 -45
  80. data/spec/functional/fc061_spec.rb +0 -48
  81. data/spec/functional/fc062_spec.rb +0 -13
  82. data/spec/functional/fc063_spec.rb +0 -18
  83. data/spec/functional/fc064_spec.rb +0 -13
  84. data/spec/functional/fc065_spec.rb +0 -13
  85. data/spec/functional/fc066_spec.rb +0 -33
  86. data/spec/functional/fc067_spec.rb +0 -13
  87. data/spec/functional/fc068_spec.rb +0 -13
  88. data/spec/functional/fc069_spec.rb +0 -38
  89. data/spec/functional/fc070_spec.rb +0 -65
  90. data/spec/functional/fc071_spec.rb +0 -36
  91. data/spec/functional/fc072_spec.rb +0 -13
  92. data/spec/functional/fc073_spec.rb +0 -56
  93. data/spec/functional/fc074_spec.rb +0 -39
  94. data/spec/functional/fc075_spec.rb +0 -41
  95. data/spec/functional/fc076_spec.rb +0 -13
  96. data/spec/functional/fc077_spec.rb +0 -13
  97. data/spec/functional/fc078_spec.rb +0 -35
  98. data/spec/functional/fc079_spec.rb +0 -21
  99. data/spec/functional/fc080_spec.rb +0 -68
  100. data/spec/functional/fc081_spec.rb +0 -25
  101. data/spec/functional/fc082_spec.rb +0 -23
  102. data/spec/functional/fc083_spec.rb +0 -34
  103. data/spec/functional/fc084_spec.rb +0 -49
  104. data/spec/functional/fc085_spec.rb +0 -77
  105. data/spec/functional/fc086_spec.rb +0 -45
  106. data/spec/functional/fc087_spec.rb +0 -43
  107. data/spec/functional/fc088_spec.rb +0 -18
  108. data/spec/functional/fc089_spec.rb +0 -23
  109. data/spec/functional/fc091_spec.rb +0 -38
  110. data/spec/functional/fc092_spec.rb +0 -31
  111. data/spec/functional/fc093_spec.rb +0 -27
  112. data/spec/functional/fc094_spec.rb +0 -18
  113. data/spec/functional/fc095_spec.rb +0 -18
  114. data/spec/functional/fc096_spec.rb +0 -18
  115. data/spec/functional/fc097_spec.rb +0 -18
  116. data/spec/functional/fc098_spec.rb +0 -18
  117. data/spec/functional/fc099_spec.rb +0 -18
  118. data/spec/functional/fc100_spec.rb +0 -18
  119. data/spec/functional/fc101_spec.rb +0 -23
  120. data/spec/functional/fc102_spec.rb +0 -18
  121. data/spec/functional/fc103_spec.rb +0 -30
  122. data/spec/functional/fc104_spec.rb +0 -54
  123. data/spec/functional/fc105_spec.rb +0 -36
  124. data/spec/functional/fc106_spec.rb +0 -21
  125. data/spec/functional/fc107_spec.rb +0 -22
  126. data/spec/functional/fc108_spec.rb +0 -43
  127. data/spec/functional/fc109_spec.rb +0 -22
  128. data/spec/functional/fc110_spec.rb +0 -21
  129. data/spec/functional/fc111_spec.rb +0 -17
  130. data/spec/functional/fc112_spec.rb +0 -17
  131. data/spec/functional/fc113_spec.rb +0 -98
  132. data/spec/functional/fc114_spec.rb +0 -31
  133. data/spec/functional/fc115_spec.rb +0 -24
  134. data/spec/functional/fc116_spec.rb +0 -18
  135. data/spec/functional/fc117_spec.rb +0 -23
  136. data/spec/functional/fc118_spec.rb +0 -17
  137. data/spec/functional/fc119_spec.rb +0 -27
  138. data/spec/functional/fc120_spec.rb +0 -21
  139. data/spec/functional/fc121_spec.rb +0 -45
  140. data/spec/functional/fc122_spec.rb +0 -18
  141. data/spec/functional/root_aliases_spec.rb +0 -13
  142. data/spec/regression/cookbooks.txt +0 -83
  143. data/spec/regression/expected/activemq.txt +0 -6
  144. data/spec/regression/expected/aix.txt +0 -27
  145. data/spec/regression/expected/apparmor.txt +0 -9
  146. data/spec/regression/expected/apt.txt +0 -14
  147. data/spec/regression/expected/ark.txt +0 -3
  148. data/spec/regression/expected/auditd.txt +0 -2
  149. data/spec/regression/expected/aws.txt +0 -16
  150. data/spec/regression/expected/bluepill.txt +0 -12
  151. data/spec/regression/expected/boost.txt +0 -8
  152. data/spec/regression/expected/build-essential.txt +0 -8
  153. data/spec/regression/expected/chef-client.txt +0 -17
  154. data/spec/regression/expected/chef-ingredient.txt +0 -6
  155. data/spec/regression/expected/chef-server.txt +0 -13
  156. data/spec/regression/expected/chef-vault.txt +0 -7
  157. data/spec/regression/expected/chef.txt +0 -104
  158. data/spec/regression/expected/chef_client_updater.txt +0 -2
  159. data/spec/regression/expected/chef_handler.txt +0 -7
  160. data/spec/regression/expected/chef_hostname.txt +0 -3
  161. data/spec/regression/expected/chef_nginx.txt +0 -4
  162. data/spec/regression/expected/cron.txt +0 -7
  163. data/spec/regression/expected/database.txt +0 -42
  164. data/spec/regression/expected/dmg.txt +0 -11
  165. data/spec/regression/expected/docker.txt +0 -4
  166. data/spec/regression/expected/drbd.txt +0 -29
  167. data/spec/regression/expected/dynect.txt +0 -33
  168. data/spec/regression/expected/erlang.txt +0 -6
  169. data/spec/regression/expected/fail2ban.txt +0 -5
  170. data/spec/regression/expected/firewall.txt +0 -11
  171. data/spec/regression/expected/gecode.txt +0 -10
  172. data/spec/regression/expected/gems.txt +0 -32
  173. data/spec/regression/expected/gunicorn.txt +0 -11
  174. data/spec/regression/expected/heartbeat.txt +0 -8
  175. data/spec/regression/expected/homebrew.txt +0 -7
  176. data/spec/regression/expected/iis.txt +0 -22
  177. data/spec/regression/expected/iptables.txt +0 -9
  178. data/spec/regression/expected/jetty.txt +0 -13
  179. data/spec/regression/expected/jpackage.txt +0 -9
  180. data/spec/regression/expected/keepalived.txt +0 -3
  181. data/spec/regression/expected/kickstart.txt +0 -15
  182. data/spec/regression/expected/libarchive.txt +0 -6
  183. data/spec/regression/expected/logwatch.txt +0 -5
  184. data/spec/regression/expected/lvm.txt +0 -14
  185. data/spec/regression/expected/maradns.txt +0 -14
  186. data/spec/regression/expected/maven.txt +0 -8
  187. data/spec/regression/expected/memcached.txt +0 -31
  188. data/spec/regression/expected/motd-tail.txt +0 -5
  189. data/spec/regression/expected/mysql.txt +0 -19
  190. data/spec/regression/expected/ohai.txt +0 -9
  191. data/spec/regression/expected/openldap.txt +0 -12
  192. data/spec/regression/expected/openssh.txt +0 -6
  193. data/spec/regression/expected/openssl.txt +0 -6
  194. data/spec/regression/expected/partial_search.txt +0 -7
  195. data/spec/regression/expected/passenger_apache2.txt +0 -31
  196. data/spec/regression/expected/perl.txt +0 -14
  197. data/spec/regression/expected/php.txt +0 -6
  198. data/spec/regression/expected/postfix.txt +0 -8
  199. data/spec/regression/expected/powershell.txt +0 -8
  200. data/spec/regression/expected/resolver.txt +0 -7
  201. data/spec/regression/expected/rsync.txt +0 -9
  202. data/spec/regression/expected/rsyslog.txt +0 -11
  203. data/spec/regression/expected/runit.txt +0 -4
  204. data/spec/regression/expected/smokeping.txt +0 -6
  205. data/spec/regression/expected/sql_server.txt +0 -7
  206. data/spec/regression/expected/ssh_known_hosts.txt +0 -6
  207. data/spec/regression/expected/stompserver.txt +0 -6
  208. data/spec/regression/expected/subversion.txt +0 -6
  209. data/spec/regression/expected/sudo.txt +0 -10
  210. data/spec/regression/expected/tar.txt +0 -10
  211. data/spec/regression/expected/tftp.txt +0 -6
  212. data/spec/regression/expected/tomcat.txt +0 -18
  213. data/spec/regression/expected/transmission.txt +0 -13
  214. data/spec/regression/expected/ubuntu.txt +0 -5
  215. data/spec/regression/expected/ufw.txt +0 -12
  216. data/spec/regression/expected/unicorn.txt +0 -7
  217. data/spec/regression/expected/users.txt +0 -12
  218. data/spec/regression/expected/vcruntime.txt +0 -8
  219. data/spec/regression/expected/vim.txt +0 -7
  220. data/spec/regression/expected/webpi.txt +0 -7
  221. data/spec/regression/expected/whitelist-node-attrs.txt +0 -7
  222. data/spec/regression/expected/windows.txt +0 -35
  223. data/spec/regression/expected/wix.txt +0 -5
  224. data/spec/regression/expected/xml.txt +0 -7
  225. data/spec/regression/expected/yum.txt +0 -15
  226. data/spec/regression/regression_spec.rb +0 -23
  227. data/spec/spec_helper.rb +0 -132
  228. data/spec/unit/api_spec.rb +0 -1939
  229. data/spec/unit/chef_spec.rb +0 -66
  230. data/spec/unit/command_line_spec.rb +0 -136
  231. data/spec/unit/domain_spec.rb +0 -78
  232. data/spec/unit/linter_spec.rb +0 -107
  233. data/spec/unit/template_spec.rb +0 -53
@@ -1,4 +0,0 @@
1
- FC004: Use a service resource to start and stop services: ./recipes/default.rb:24
2
- FC069: Ensure standardized license defined in metadata: ./metadata.rb:1
3
- FC078: Ensure cookbook shared under an OSI-approved open source license: ./metadata.rb:1
4
- FC113: Resource declares deprecated use_inline_resources: ./libraries/provider_runit_service.rb:42
@@ -1,6 +0,0 @@
1
- FC066: Ensure chef_version is set in metadata: ./metadata.rb:1
2
- FC069: Ensure standardized license defined in metadata: ./metadata.rb:1
3
- FC078: Ensure cookbook shared under an OSI-approved open source license: ./metadata.rb:1
4
- FC082: Deprecated node.set or node.set_unless used to set node attributes: ./recipes/example_slave.rb:19
5
- FC085: Resource using new_resource.updated_by_last_action to converge resource: ./providers/target.rb:53
6
- FC085: Resource using new_resource.updated_by_last_action to converge resource: ./providers/target.rb:63
@@ -1,7 +0,0 @@
1
- FC064: Ensure issues_url is set in metadata: ./metadata.rb:1
2
- FC065: Ensure source_url is set in metadata: ./metadata.rb:1
3
- FC066: Ensure chef_version is set in metadata: ./metadata.rb:1
4
- FC069: Ensure standardized license defined in metadata: ./metadata.rb:1
5
- FC075: Cookbook uses node.save to save partial node data to the chef-server mid-run: ./recipes/server.rb:28
6
- FC078: Ensure cookbook shared under an OSI-approved open source license: ./metadata.rb:1
7
- FC082: Deprecated node.set or node.set_unless used to set node attributes: ./recipes/server.rb:26
@@ -1,6 +0,0 @@
1
- FC064: Ensure issues_url is set in metadata: ./metadata.rb:1
2
- FC065: Ensure source_url is set in metadata: ./metadata.rb:1
3
- FC066: Ensure chef_version is set in metadata: ./metadata.rb:1
4
- FC067: Ensure at least one platform supported in metadata: ./metadata.rb:1
5
- FC069: Ensure standardized license defined in metadata: ./metadata.rb:1
6
- FC078: Ensure cookbook shared under an OSI-approved open source license: ./metadata.rb:1
@@ -1,6 +0,0 @@
1
- FC001: Use strings in preference to symbols to access node attributes: ./templates/default/sv-stompserver-run.erb:2
2
- FC064: Ensure issues_url is set in metadata: ./metadata.rb:1
3
- FC065: Ensure source_url is set in metadata: ./metadata.rb:1
4
- FC066: Ensure chef_version is set in metadata: ./metadata.rb:1
5
- FC069: Ensure standardized license defined in metadata: ./metadata.rb:1
6
- FC078: Ensure cookbook shared under an OSI-approved open source license: ./metadata.rb:1
@@ -1,6 +0,0 @@
1
- FC043: Prefer new notification syntax: ./recipes/server.rb:30
2
- FC064: Ensure issues_url is set in metadata: ./metadata.rb:1
3
- FC065: Ensure source_url is set in metadata: ./metadata.rb:1
4
- FC066: Ensure chef_version is set in metadata: ./metadata.rb:1
5
- FC069: Ensure standardized license defined in metadata: ./metadata.rb:1
6
- FC078: Ensure cookbook shared under an OSI-approved open source license: ./metadata.rb:1
@@ -1,10 +0,0 @@
1
- FC064: Ensure issues_url is set in metadata: ./metadata.rb:1
2
- FC065: Ensure source_url is set in metadata: ./metadata.rb:1
3
- FC066: Ensure chef_version is set in metadata: ./metadata.rb:1
4
- FC069: Ensure standardized license defined in metadata: ./metadata.rb:1
5
- FC072: Metadata should not contain "attribute" keyword: ./metadata.rb:1
6
- FC074: LWRP should use DSL to define resource's default action: ./resources/default.rb:1
7
- FC078: Ensure cookbook shared under an OSI-approved open source license: ./metadata.rb:1
8
- FC085: Resource using new_resource.updated_by_last_action to converge resource: ./providers/default.rb:98
9
- FC085: Resource using new_resource.updated_by_last_action to converge resource: ./providers/default.rb:112
10
- FC089: Prefer Mixlib::Shellout over deprecated Chef::ShellOut: ./providers/default.rb:46
@@ -1,10 +0,0 @@
1
- FC064: Ensure issues_url is set in metadata: ./metadata.rb:1
2
- FC065: Ensure source_url is set in metadata: ./metadata.rb:1
3
- FC066: Ensure chef_version is set in metadata: ./metadata.rb:1
4
- FC067: Ensure at least one platform supported in metadata: ./metadata.rb:1
5
- FC069: Ensure standardized license defined in metadata: ./metadata.rb:1
6
- FC071: Missing LICENSE file: ./LICENSE:1
7
- FC074: LWRP should use DSL to define resource's default action: ./resources/package.rb:1
8
- FC078: Ensure cookbook shared under an OSI-approved open source license: ./metadata.rb:1
9
- FC113: Resource declares deprecated use_inline_resources: ./providers/extract.rb:26
10
- FC113: Resource declares deprecated use_inline_resources: ./providers/package.rb:22
@@ -1,6 +0,0 @@
1
- FC064: Ensure issues_url is set in metadata: ./metadata.rb:1
2
- FC065: Ensure source_url is set in metadata: ./metadata.rb:1
3
- FC066: Ensure chef_version is set in metadata: ./metadata.rb:1
4
- FC069: Ensure standardized license defined in metadata: ./metadata.rb:1
5
- FC072: Metadata should not contain "attribute" keyword: ./metadata.rb:1
6
- FC078: Ensure cookbook shared under an OSI-approved open source license: ./metadata.rb:1
@@ -1,18 +0,0 @@
1
- FC069: Ensure standardized license defined in metadata: ./metadata.rb:1
2
- FC078: Ensure cookbook shared under an OSI-approved open source license: ./metadata.rb:1
3
- FC116: Cookbook depends on the deprecated compat_resource cookbook: ./metadata.rb:1
4
- FC117: Do not use kind_of in custom resource properties: ./resources/install.rb:7
5
- FC117: Do not use kind_of in custom resource properties: ./resources/install.rb:8
6
- FC117: Do not use kind_of in custom resource properties: ./resources/install.rb:9
7
- FC117: Do not use kind_of in custom resource properties: ./resources/install.rb:10
8
- FC117: Do not use kind_of in custom resource properties: ./resources/install.rb:12
9
- FC117: Do not use kind_of in custom resource properties: ./resources/install.rb:13
10
- FC117: Do not use kind_of in custom resource properties: ./resources/service_systemd.rb:23
11
- FC117: Do not use kind_of in custom resource properties: ./resources/service_systemd.rb:24
12
- FC117: Do not use kind_of in custom resource properties: ./resources/service_systemd.rb:28
13
- FC117: Do not use kind_of in custom resource properties: ./resources/service_sysv_init.rb:16
14
- FC117: Do not use kind_of in custom resource properties: ./resources/service_sysv_init.rb:17
15
- FC117: Do not use kind_of in custom resource properties: ./resources/service_sysv_init.rb:21
16
- FC117: Do not use kind_of in custom resource properties: ./resources/service_upstart.rb:10
17
- FC117: Do not use kind_of in custom resource properties: ./resources/service_upstart.rb:11
18
- FC117: Do not use kind_of in custom resource properties: ./resources/service_upstart.rb:15
@@ -1,13 +0,0 @@
1
- FC016: LWRP does not declare a default action: ./resources/torrent_file.rb:1
2
- FC024: Consider adding platform equivalents: ./recipes/default.rb:42
3
- FC025: Prefer chef_gem to compile-time gem install: ./recipes/default.rb:25
4
- FC025: Prefer chef_gem to compile-time gem install: ./recipes/default.rb:31
5
- FC064: Ensure issues_url is set in metadata: ./metadata.rb:1
6
- FC065: Ensure source_url is set in metadata: ./metadata.rb:1
7
- FC066: Ensure chef_version is set in metadata: ./metadata.rb:1
8
- FC067: Ensure at least one platform supported in metadata: ./metadata.rb:1
9
- FC069: Ensure standardized license defined in metadata: ./metadata.rb:1
10
- FC078: Ensure cookbook shared under an OSI-approved open source license: ./metadata.rb:1
11
- FC085: Resource using new_resource.updated_by_last_action to converge resource: ./providers/torrent_file.rb:53
12
- FC085: Resource using new_resource.updated_by_last_action to converge resource: ./providers/torrent_file.rb:58
13
- FC122: Use the build_essential resource instead of the recipe: ./recipes/source.rb:21
@@ -1,5 +0,0 @@
1
- FC064: Ensure issues_url is set in metadata: ./metadata.rb:1
2
- FC065: Ensure source_url is set in metadata: ./metadata.rb:1
3
- FC066: Ensure chef_version is set in metadata: ./metadata.rb:1
4
- FC069: Ensure standardized license defined in metadata: ./metadata.rb:1
5
- FC078: Ensure cookbook shared under an OSI-approved open source license: ./metadata.rb:1
@@ -1,12 +0,0 @@
1
- FC001: Use strings in preference to symbols to access node attributes: ./attributes/default.rb:1
2
- FC001: Use strings in preference to symbols to access node attributes: ./attributes/default.rb:2
3
- FC019: Access node attributes in a consistent manner: ./attributes/default.rb:1
4
- FC019: Access node attributes in a consistent manner: ./attributes/default.rb:2
5
- FC064: Ensure issues_url is set in metadata: ./metadata.rb:1
6
- FC065: Ensure source_url is set in metadata: ./metadata.rb:1
7
- FC066: Ensure chef_version is set in metadata: ./metadata.rb:1
8
- FC069: Ensure standardized license defined in metadata: ./metadata.rb:1
9
- FC072: Metadata should not contain "attribute" keyword: ./metadata.rb:1
10
- FC078: Ensure cookbook shared under an OSI-approved open source license: ./metadata.rb:1
11
- FC082: Deprecated node.set or node.set_unless used to set node attributes: ./recipes/default.rb:34
12
- FC120: Do not set the name property directly on a resource: ./recipes/default.rb:69
@@ -1,7 +0,0 @@
1
- FC015: Consider converting definition to a Custom Resource: ./definitions/unicorn_config.rb:1
2
- FC064: Ensure issues_url is set in metadata: ./metadata.rb:1
3
- FC065: Ensure source_url is set in metadata: ./metadata.rb:1
4
- FC066: Ensure chef_version is set in metadata: ./metadata.rb:1
5
- FC067: Ensure at least one platform supported in metadata: ./metadata.rb:1
6
- FC069: Ensure standardized license defined in metadata: ./metadata.rb:1
7
- FC078: Ensure cookbook shared under an OSI-approved open source license: ./metadata.rb:1
@@ -1,12 +0,0 @@
1
- FC009: Resource attribute not recognised: ./providers/manage.rb:78
2
- FC047: Attribute assignment does not specify precedence: ./providers/manage.rb:55
3
- FC064: Ensure issues_url is set in metadata: ./metadata.rb:1
4
- FC065: Ensure source_url is set in metadata: ./metadata.rb:1
5
- FC066: Ensure chef_version is set in metadata: ./metadata.rb:1
6
- FC069: Ensure standardized license defined in metadata: ./metadata.rb:1
7
- FC074: LWRP should use DSL to define resource's default action: ./resources/manage.rb:1
8
- FC078: Ensure cookbook shared under an OSI-approved open source license: ./metadata.rb:1
9
- FC080: User resource uses deprecated supports property: ./providers/manage.rb:87
10
- FC080: User resource uses deprecated supports property: ./providers/manage.rb:89
11
- FC085: Resource using new_resource.updated_by_last_action to converge resource: ./providers/manage.rb:39
12
- FC085: Resource using new_resource.updated_by_last_action to converge resource: ./providers/manage.rb:143
@@ -1,8 +0,0 @@
1
- FC009: Resource attribute not recognised: ./recipes/vc10.rb:24
2
- FC009: Resource attribute not recognised: ./recipes/vc11.rb:24
3
- FC009: Resource attribute not recognised: ./recipes/vc12.rb:24
4
- FC009: Resource attribute not recognised: ./recipes/vc14.rb:24
5
- FC009: Resource attribute not recognised: ./recipes/vc6.rb:24
6
- FC009: Resource attribute not recognised: ./recipes/vc9.rb:24
7
- FC069: Ensure standardized license defined in metadata: ./metadata.rb:1
8
- FC078: Ensure cookbook shared under an OSI-approved open source license: ./metadata.rb:1
@@ -1,7 +0,0 @@
1
- FC001: Use strings in preference to symbols to access node attributes: ./attributes/default.rb:20
2
- FC001: Use strings in preference to symbols to access node attributes: ./recipes/default.rb:33
3
- FC064: Ensure issues_url is set in metadata: ./metadata.rb:1
4
- FC065: Ensure source_url is set in metadata: ./metadata.rb:1
5
- FC066: Ensure chef_version is set in metadata: ./metadata.rb:1
6
- FC069: Ensure standardized license defined in metadata: ./metadata.rb:1
7
- FC078: Ensure cookbook shared under an OSI-approved open source license: ./metadata.rb:1
@@ -1,7 +0,0 @@
1
- FC064: Ensure issues_url is set in metadata: ./metadata.rb:1
2
- FC065: Ensure source_url is set in metadata: ./metadata.rb:1
3
- FC066: Ensure chef_version is set in metadata: ./metadata.rb:1
4
- FC069: Ensure standardized license defined in metadata: ./metadata.rb:1
5
- FC074: LWRP should use DSL to define resource's default action: ./resources/product.rb:1
6
- FC078: Ensure cookbook shared under an OSI-approved open source license: ./metadata.rb:1
7
- FC085: Resource using new_resource.updated_by_last_action to converge resource: ./providers/product.rb:33
@@ -1,7 +0,0 @@
1
- FC001: Use strings in preference to symbols to access node attributes: ./attributes/default.rb:20
2
- FC064: Ensure issues_url is set in metadata: ./metadata.rb:1
3
- FC065: Ensure source_url is set in metadata: ./metadata.rb:1
4
- FC066: Ensure chef_version is set in metadata: ./metadata.rb:1
5
- FC067: Ensure at least one platform supported in metadata: ./metadata.rb:1
6
- FC069: Ensure standardized license defined in metadata: ./metadata.rb:1
7
- FC078: Ensure cookbook shared under an OSI-approved open source license: ./metadata.rb:1
@@ -1,35 +0,0 @@
1
- FC002: Avoid string interpolation where not required: ./libraries/registry_helper.rb:99
2
- FC002: Avoid string interpolation where not required: ./libraries/registry_helper.rb:173
3
- FC002: Avoid string interpolation where not required: ./libraries/windows_privileged.rb:42
4
- FC002: Avoid string interpolation where not required: ./libraries/windows_privileged.rb:56
5
- FC018: LWRP uses deprecated notification syntax: ./providers/shortcut.rb:54
6
- FC048: Prefer shell_out helper method to shelling out with Ruby: ./providers/task.rb:106
7
- FC064: Ensure issues_url is set in metadata: ./metadata.rb:1
8
- FC065: Ensure source_url is set in metadata: ./metadata.rb:1
9
- FC066: Ensure chef_version is set in metadata: ./metadata.rb:1
10
- FC069: Ensure standardized license defined in metadata: ./metadata.rb:1
11
- FC074: LWRP should use DSL to define resource's default action: ./resources/auto_run.rb:1
12
- FC074: LWRP should use DSL to define resource's default action: ./resources/batch.rb:1
13
- FC074: LWRP should use DSL to define resource's default action: ./resources/feature.rb:1
14
- FC074: LWRP should use DSL to define resource's default action: ./resources/package.rb:1
15
- FC074: LWRP should use DSL to define resource's default action: ./resources/path.rb:1
16
- FC074: LWRP should use DSL to define resource's default action: ./resources/reboot.rb:1
17
- FC074: LWRP should use DSL to define resource's default action: ./resources/registry.rb:1
18
- FC074: LWRP should use DSL to define resource's default action: ./resources/shortcut.rb:1
19
- FC074: LWRP should use DSL to define resource's default action: ./resources/task.rb:1
20
- FC074: LWRP should use DSL to define resource's default action: ./resources/zipfile.rb:1
21
- FC078: Ensure cookbook shared under an OSI-approved open source license: ./metadata.rb:1
22
- FC085: Resource using new_resource.updated_by_last_action to converge resource: ./libraries/feature_base.rb:9
23
- FC085: Resource using new_resource.updated_by_last_action to converge resource: ./libraries/feature_base.rb:19
24
- FC085: Resource using new_resource.updated_by_last_action to converge resource: ./providers/batch.rb:42
25
- FC085: Resource using new_resource.updated_by_last_action to converge resource: ./providers/package.rb:48
26
- FC085: Resource using new_resource.updated_by_last_action to converge resource: ./providers/package.rb:59
27
- FC085: Resource using new_resource.updated_by_last_action to converge resource: ./providers/package.rb:68
28
- FC085: Resource using new_resource.updated_by_last_action to converge resource: ./providers/pagefile.rb:63
29
- FC085: Resource using new_resource.updated_by_last_action to converge resource: ./providers/pagefile.rb:75
30
- FC085: Resource using new_resource.updated_by_last_action to converge resource: ./providers/registry.rb:70
31
- FC085: Resource using new_resource.updated_by_last_action to converge resource: ./providers/task.rb:38
32
- FC085: Resource using new_resource.updated_by_last_action to converge resource: ./providers/task.rb:50
33
- FC085: Resource using new_resource.updated_by_last_action to converge resource: ./providers/task.rb:68
34
- FC085: Resource using new_resource.updated_by_last_action to converge resource: ./providers/task.rb:79
35
- FC085: Resource using new_resource.updated_by_last_action to converge resource: ./providers/zipfile.rb:41
@@ -1,5 +0,0 @@
1
- FC064: Ensure issues_url is set in metadata: ./metadata.rb:1
2
- FC065: Ensure source_url is set in metadata: ./metadata.rb:1
3
- FC066: Ensure chef_version is set in metadata: ./metadata.rb:1
4
- FC069: Ensure standardized license defined in metadata: ./metadata.rb:1
5
- FC078: Ensure cookbook shared under an OSI-approved open source license: ./metadata.rb:1
@@ -1,7 +0,0 @@
1
- FC064: Ensure issues_url is set in metadata: ./metadata.rb:1
2
- FC065: Ensure source_url is set in metadata: ./metadata.rb:1
3
- FC066: Ensure chef_version is set in metadata: ./metadata.rb:1
4
- FC069: Ensure standardized license defined in metadata: ./metadata.rb:1
5
- FC078: Ensure cookbook shared under an OSI-approved open source license: ./metadata.rb:1
6
- FC082: Deprecated node.set or node.set_unless used to set node attributes: ./recipes/ruby.rb:27
7
- FC122: Use the build_essential resource instead of the recipe: ./recipes/ruby.rb:28
@@ -1,15 +0,0 @@
1
- FC009: Resource attribute not recognised: ./recipes/epel.rb:27
2
- FC038: Invalid resource action: ./recipes/epel.rb:27
3
- FC043: Prefer new notification syntax: ./providers/key.rb:60
4
- FC043: Prefer new notification syntax: ./providers/repository.rb:94
5
- FC064: Ensure issues_url is set in metadata: ./metadata.rb:1
6
- FC065: Ensure source_url is set in metadata: ./metadata.rb:1
7
- FC066: Ensure chef_version is set in metadata: ./metadata.rb:1
8
- FC069: Ensure standardized license defined in metadata: ./metadata.rb:1
9
- FC072: Metadata should not contain "attribute" keyword: ./metadata.rb:1
10
- FC074: LWRP should use DSL to define resource's default action: ./resources/key.rb:1
11
- FC074: LWRP should use DSL to define resource's default action: ./resources/repository.rb:1
12
- FC078: Ensure cookbook shared under an OSI-approved open source license: ./metadata.rb:1
13
- FC085: Resource using new_resource.updated_by_last_action to converge resource: ./providers/key.rb:76
14
- FC085: Resource using new_resource.updated_by_last_action to converge resource: ./providers/repository.rb:41
15
- FC104: Use the :run action in ruby_block instead of :create: ./providers/repository.rb:94
@@ -1,23 +0,0 @@
1
- require "spec_helper"
2
-
3
- describe "regression test" do
4
- command("#{File.expand_path("../../../bin/foodcritic", __FILE__)} --no-progress --tags any .", allow_error: true)
5
-
6
- File.readlines(File.expand_path("../cookbooks.txt", __FILE__)).each do |line|
7
- name, ref = line.strip.split(":")
8
-
9
- context "with cookbook #{name}", "regression_#{name}" => true do
10
- before do
11
- command("git clone -q https://github.com/chef-cookbooks/#{name}.git .")
12
- command("git checkout -q #{ref}")
13
- end
14
-
15
- it "should match expected output" do
16
- expected_output = File.readlines(File.expand_path("../expected/#{name}.txt", __FILE__))
17
- expected_output.each do |expected_line|
18
- expect(subject.stdout).to include expected_line
19
- end
20
- end
21
- end
22
- end
23
- end
@@ -1,132 +0,0 @@
1
- require "shellwords"
2
-
3
- require "rspec_command"
4
- require "simplecov"
5
-
6
- SimpleCov.start do
7
- add_filter "/spec/"
8
- end
9
-
10
- module FunctionalHelpers
11
- extend RSpec::Matchers::DSL
12
-
13
- matcher :violate_rule do |rule_id = nil|
14
- match do |cmd|
15
- if location
16
- cmd.stdout =~ /^#{expected}:.*: \.\/#{location}/
17
- else
18
- cmd.stdout =~ /^#{expected}:/
19
- end
20
- end
21
- chain :in, :location
22
- failure_message do |cmd|
23
- "expected a violation of rule #{expected}#{location && " in #{location}"}, output was:\n#{cmd.stdout}"
24
- end
25
- failure_message_when_negated do |cmd|
26
- "expected no violation of rule #{expected}#{location && " in #{location}"}, output was:\n#{cmd.stdout}"
27
- end
28
- # Override the default behavior from RSpec for the expected value, use
29
- # define_method insetad of def so we can see the _rule_id variable in closure.
30
- define_method(:expected) do
31
- # Fill in the top-level example group description as the rule ID if not specified.
32
- rule_id || method_missing(:class).parent_groups.last.description
33
- end
34
- end
35
-
36
- def foodcritic_command(*args)
37
- output = StringIO.new
38
- error = StringIO.new
39
- begin
40
- # Don't use the block form of chdir because for some reason it can't be
41
- # nested.
42
- cwd = Dir.pwd
43
- Dir.chdir(temp_path)
44
- $stderr = error
45
- exitstatus = FoodCritic::CommandLine.main(args, output)
46
- ensure
47
- $stderr = STDERR
48
- Dir.chdir(cwd)
49
- end
50
- RSpecCommand::OutputString.new(output.string, error.string).tap do |out|
51
- out.define_singleton_method(:exitstatus) { exitstatus }
52
- end
53
- end
54
-
55
- module ClassMethods
56
- def foodcritic_command(*args)
57
- metadata[:foodcritic_command] = true
58
- subject do |example|
59
- foodcritic_command(*args)
60
- end
61
- end
62
-
63
- def attributes_file(*args, &block)
64
- file("attributes/default.rb", *args, &block)
65
- end
66
-
67
- def resource_file(*args, &block)
68
- file("resources/my_resource.rb", *args, &block)
69
- end
70
-
71
- def provider_file(*args, &block)
72
- file("providers/my_resource.rb", *args, &block)
73
- end
74
-
75
- def definition_file(*args, &block)
76
- file("definitions/my_definition.rb", *args, &block)
77
- end
78
-
79
- def library_file(*args, &block)
80
- file("libraries/helper.rb", *args, &block)
81
- end
82
-
83
- def recipe_file(*args, &block)
84
- file("recipes/default.rb", *args, &block)
85
- end
86
-
87
- def metadata_file(*args, &block)
88
- file("metadata.rb", *args, &block)
89
- end
90
-
91
- def readme_file(*args, &block)
92
- file("README.md", *args, &block)
93
- end
94
-
95
- def included(klass)
96
- super
97
- klass.extend ClassMethods
98
- # Set a default subject command, can be overridden if needed.
99
- klass.foodcritic_command("--no-progress", ".")
100
- end
101
- end
102
-
103
- extend ClassMethods
104
- end
105
-
106
- RSpec.configure do |config|
107
- # Basic configuraiton
108
- config.run_all_when_everything_filtered = true
109
- config.filter_run(:focus) unless ENV["CI"]
110
-
111
- # Run specs in random order to surface order dependencies. If you find an
112
- # order dependency and want to debug it, you can fix the order by providing
113
- # the seed, which is printed after each run.
114
- # --seed 1234
115
- config.order = "random"
116
-
117
- # Set some metadata based on test folders.
118
- config.define_derived_metadata(file_path: %r{spec/unit}) do |metadata|
119
- metadata[:unit] = true
120
- end
121
- config.define_derived_metadata(file_path: %r{spec/functional}) do |metadata|
122
- metadata[:functional] = true
123
- end
124
- config.define_derived_metadata(file_path: %r{spec/regression}) do |metadata|
125
- metadata[:regression] = true
126
- end
127
-
128
- config.include RSpecCommand
129
- config.include FunctionalHelpers, functional: true
130
- end
131
-
132
- require_relative "../lib/foodcritic"
@@ -1,1939 +0,0 @@
1
- require "spec_helper"
2
-
3
- describe FoodCritic::Api do
4
-
5
- def parse_ast(str)
6
- api.send(:build_xml, Ripper::SexpBuilder.new(str).parse)
7
- end
8
-
9
- def self.ast(str)
10
- let(:ast) { parse_ast(str) }
11
- end
12
-
13
- let(:api) { Object.new.extend(FoodCritic::Api) }
14
-
15
- describe :exposed_api do
16
- let(:ignorable_methods) do
17
- api.class.ancestors.map { |a| a.public_methods }.flatten.sort.uniq
18
- end
19
- it "exposes the expected api to rule authors" do
20
- expect(api.public_methods.sort - ignorable_methods).to eq [
21
- :attribute_access,
22
- :chef_dsl_methods,
23
- :chef_node_methods,
24
- :cookbook_base_path,
25
- :cookbook_maintainer,
26
- :cookbook_maintainer_email,
27
- :cookbook_name,
28
- :declared_dependencies,
29
- :ensure_file_exists,
30
- :field,
31
- :field_value,
32
- :file_match,
33
- :find_resources,
34
- :gem_version,
35
- :included_recipes,
36
- :json_file_to_hash,
37
- :literal_searches,
38
- :match,
39
- :metadata_field,
40
- :notifications,
41
- :read_ast,
42
- :resource_action?,
43
- :resource_attribute,
44
- :resource_attribute?,
45
- :resource_attributes,
46
- :resource_attributes_by_type,
47
- :resource_name,
48
- :resource_type,
49
- :resources_by_type,
50
- :ruby_code?,
51
- :searches,
52
- :standard_cookbook_subdirs,
53
- :supported_platforms,
54
- :template_file,
55
- :template_paths,
56
- :templates_included,
57
- :valid_query?,
58
- ]
59
- end
60
- end
61
-
62
- describe "#attribute_access" do
63
- let(:ast) { double() }
64
- it "returns empty if the provided ast does not support XPath" do
65
- expect(api.attribute_access(nil, type: :vivified)).to be_empty
66
- end
67
- it "returns empty if the provided ast has no matches" do
68
- expect(ast).to receive(:xpath).with(kind_of(String), kind_of(FoodCritic::Api::AttFilter)).and_return([]).exactly(3).times
69
- [:vivified, :string, :symbol].each do |access_type|
70
- expect(api.attribute_access(ast, type: access_type)).to be_empty
71
- end
72
- end
73
- it "raises if the specified node type is not recognised" do
74
- allow(ast).to receive(:xpath)
75
- expect { api.attribute_access(ast, type: :cymbals) }.to raise_error ArgumentError
76
- end
77
- it "does not raise if the specified node type is valid" do
78
- expect(ast).to receive(:xpath).with(/field/, FoodCritic::Api::AttFilter).and_return([])
79
- expect(ast).to receive(:xpath).with(/symbol/, FoodCritic::Api::AttFilter).and_return([])
80
- expect(ast).to receive(:xpath).with(/tstring_content/, FoodCritic::Api::AttFilter).and_return([])
81
- [:vivified, :symbol, :string].each do |access_type|
82
- api.attribute_access(ast, type: access_type)
83
- end
84
- end
85
- it "returns vivified attributes access" do
86
- call = double()
87
- expect(call).to receive(:xpath).with(/args_add_block/).and_return([])
88
- expect(call).to receive(:xpath).with(/ident/).and_return(%w{node bar})
89
- expect(call).to receive(:xpath).with(/@value/).and_return("foo")
90
- expect(ast).to receive(:xpath).with(kind_of(String), kind_of(FoodCritic::Api::AttFilter)).and_return([call])
91
- expect(api.attribute_access(ast, type: :vivified)).to eq [call]
92
- end
93
- it "doesn't flag searching for a node by name as symbol access" do
94
- ast = parse_ast(%q{baz = search(:node, "name:#{node['foo']['bar']}")[0]})
95
- expect(api.attribute_access(ast, type: :symbol)).to be_empty
96
- end
97
- describe :ignoring_attributes do
98
- it "doesn't ignore run_state by default for backwards compatibility" do
99
- ast = parse_ast("node.run_state['bar'] = 'baz'")
100
- expect(api.attribute_access(ast)).to_not be_empty
101
- end
102
- it "allows run_state to be ignored" do
103
- ast = parse_ast("node.run_state['bar'] = 'baz'")
104
- expect(api.attribute_access(ast, ignore: ["run_state"])).to be_empty
105
- end
106
- it "allows run_state to be ignored (symbols access)" do
107
- ast = parse_ast("node.run_state[:bar] = 'baz'")
108
- expect(api.attribute_access(ast, ignore: ["run_state"])).to be_empty
109
- end
110
- it "allows any attribute to be ignored" do
111
- ast = parse_ast("node['bar'] = 'baz'")
112
- expect(api.attribute_access(ast, ignore: ["bar"])).to be_empty
113
- end
114
- it "allows any attribute to be ignored (symbols access)" do
115
- ast = parse_ast("node[:bar] = 'baz'")
116
- expect(api.attribute_access(ast, ignore: ["bar"])).to be_empty
117
- end
118
- it "allows any attribute to be ignored (dot access)" do
119
- ast = parse_ast("node.bar = 'baz'")
120
- expect(api.attribute_access(ast, ignore: ["bar"])).to be_empty
121
- end
122
- it "includes the children of attributes" do
123
- ast = parse_ast("node['foo']['bar'] = 'baz'")
124
- expect(api.attribute_access(ast).map { |a| a["value"] }).to eq %w{foo bar}
125
- end
126
- it "does not include children of removed attributes" do
127
- ast = parse_ast("node['foo']['bar'] = 'baz'")
128
- expect(api.attribute_access(ast, ignore: ["foo"])).to be_empty
129
- end
130
- it "coerces ignore values to enumerate them" do
131
- ast = parse_ast("node.run_state['bar'] = 'baz'")
132
- expect(api.attribute_access(ast, ignore: "run_state")).to be_empty
133
- end
134
- it "can ignore multiple attributes" do
135
- ast = parse_ast(%q{
136
- node['bar'] = 'baz'
137
- node.foo = 'baz'
138
- })
139
- expect(api.attribute_access(ast, ignore: %w{foo bar})).to be_empty
140
- end
141
- end
142
- end
143
-
144
- describe "#metadata_field" do
145
- file "metadata.rb", 'name "YOUR_COOKBOOK_NAME"'
146
-
147
- it "returns the 'name' value when passed a metadata file and the name field" do
148
- expect(api.metadata_field(temp_path, "name")).to eq "YOUR_COOKBOOK_NAME"
149
- end
150
-
151
- it "it raises if a invalid field is requested" do
152
- expect { api.metadata_field(temp_path, "bogus_field") }.to raise_error RuntimeError
153
- end
154
-
155
- it "it raises if a invalid file is requested" do
156
- expect { api.metadata_field("/invalid", "name") }.to raise_error RuntimeError
157
- end
158
- end
159
-
160
- describe "#cookbook_base_path" do
161
- file "templates/defaults/test.erb"
162
-
163
- context "with a metadata.rb" do
164
- file "metadata.rb"
165
-
166
- it "returns the cookbook dir when passed the path itself" do
167
- expect(api.cookbook_base_path(temp_path)).to eq temp_path
168
- end
169
-
170
- it "returns the cookbook dir when passed a nested directory" do
171
- expect(api.cookbook_base_path("#{temp_path}/templates/defaults/test.erb")).to eq temp_path
172
- end
173
- end
174
-
175
- context "with a metadata.json" do
176
- file "metadata.json"
177
-
178
- it "returns the cookbook dir when passed the path itself" do
179
- expect(api.cookbook_base_path(temp_path)).to eq temp_path
180
- end
181
-
182
- it "returns the cookbook dir when passed a nested directory" do
183
- expect(api.cookbook_base_path("#{temp_path}/templates/defaults/test.erb")).to eq temp_path
184
- end
185
- end
186
-
187
- context "with complex nested folders with metadata.rb" do
188
- file "metadata.rb"
189
- file "templates/metadata.rb"
190
-
191
- it "returns the cookbook dir when path contains cookbook like names" do
192
- expect(api.cookbook_base_path("#{temp_path}/templates/defaults/test.erb")).to eq "#{temp_path}/templates"
193
- end
194
- end
195
- end
196
-
197
- describe "#cookbook_name" do
198
- it "raises if passed a nil" do
199
- expect { api.cookbook_name(nil) }.to raise_error ArgumentError
200
- end
201
- it "raises if passed an empty string" do
202
- expect { api.cookbook_name("") }.to raise_error ArgumentError
203
- end
204
- it "returns the cookbook name when passed a recipe" do
205
- recipe_path = "cookbooks/apache2/recipes/default.rb"
206
- expect(api.cookbook_name(recipe_path)).to eq "apache2"
207
- end
208
- it "returns the cookbook name when passed the cookbook metadata" do
209
- expect(api.cookbook_name("cookbooks/apache2/metadata.rb")).to eq "apache2"
210
- end
211
- it "returns the cookbook name when passed a template" do
212
- erb_path = "cookbooks/apache2/templates/default/a2ensite.erb"
213
- expect(api.cookbook_name(erb_path)).to eq "apache2"
214
- end
215
- context "with a metadata.rb" do
216
- file "metadata.rb", 'name "YOUR_COOKBOOK_NAME"'
217
- it "returns the cookbook name when passed the cookbook metadata with a name field" do
218
- expect(api.cookbook_name(temp_path)).to eq "YOUR_COOKBOOK_NAME"
219
- end
220
- end
221
- end
222
-
223
- describe "#cookbook_maintainer" do
224
- it "raises if passed a nil" do
225
- expect { api.cookbook_maintainer(nil) }.to raise_error ArgumentError
226
- end
227
- it "raises if passed an empty string" do
228
- expect { api.cookbook_maintainer("") }.to raise_error ArgumentError
229
- end
230
- it "raises if the path does not exist" do
231
- expect { api.cookbook_maintainer("/invalid") }.to raise_error RuntimeError
232
- end
233
- context "with a metadata.rb" do
234
- file "metadata.rb", 'maintainer "YOUR_COMPANY_NAME"'
235
- it "returns the cookbook maintainer when passed the cookbook metadata" do
236
- expect(api.cookbook_maintainer(temp_path)).to eq "YOUR_COMPANY_NAME"
237
- end
238
- it "returns the cookbook maintainer when passed a recipe" do
239
- expect(api.cookbook_maintainer("#{temp_path}/recipes/default.rb")).to eq "YOUR_COMPANY_NAME"
240
- end
241
- it "returns the cookbook maintainer when passed a template" do
242
- expect(api.cookbook_maintainer("#{temp_path}/templates/default/mock.erb")).to eq "YOUR_COMPANY_NAME"
243
- end
244
- end
245
- end
246
-
247
- describe "#cookbook_maintainer_email" do
248
- it "raises if passed a nil" do
249
- expect { api.cookbook_maintainer_email(nil) }.to raise_error ArgumentError
250
- end
251
- it "raises if passed an empty string" do
252
- expect { api.cookbook_maintainer_email("") }.to raise_error ArgumentError
253
- end
254
- it "raises if the path does not exist" do
255
- expect { api.cookbook_maintainer_email("/invalid") }.to raise_error RuntimeError
256
- end
257
- context "with a metadata.rb" do
258
- file "metadata.rb", 'maintainer_email "YOUR_EMAIL"'
259
- it "returns the cookbook maintainer_email when passed the cookbook metadata" do
260
- expect(api.cookbook_maintainer_email(temp_path)).to eq "YOUR_EMAIL"
261
- end
262
- it "returns the cookbook maintainer_email when passed a recipe" do
263
- expect(api.cookbook_maintainer_email("#{temp_path}/recipes/default.rb")).to eq "YOUR_EMAIL"
264
- end
265
- it "returns the cookbook maintainer_email when passed a template" do
266
- expect(api.cookbook_maintainer_email("#{temp_path}/templates/default/mock.erb")).to eq "YOUR_EMAIL"
267
- end
268
- end
269
- end
270
-
271
- describe "#declared_dependencies" do
272
- let(:ast) { nil }
273
- subject { api.declared_dependencies(ast) }
274
- context "with an invalid options" do
275
- it { expect { subject }.to raise_error ArgumentError }
276
- end
277
- context "with no dependencies" do
278
- ast 'name "cook"'
279
- it { is_expected.to eq [] }
280
- end
281
- context "with a simple dependency" do
282
- ast 'depends "one"'
283
- it { is_expected.to eq %w{one} }
284
- end
285
- context "with multiple simple dependencies" do
286
- ast %Q{depends "one"\ndepends 'two'\ndepends('three')}
287
- it { is_expected.to eq %w{one two three} }
288
- end
289
- context "using a word array and a one-line block" do
290
- ast "%w{one two three}.each {|d| depends d }"
291
- it { is_expected.to eq %w{one two three} }
292
- end
293
- context "using a word array and a multi-line block" do
294
- ast "%w{one two three}.each do |d|\n depends d\nend"
295
- it { is_expected.to eq %w{one two three} }
296
- end
297
- context "using a non-standard word array" do
298
- ast "%w|one two three|.each {|d| depends d }"
299
- it { is_expected.to eq %w{one two three} }
300
- end
301
- end
302
-
303
- describe "#field" do
304
- describe :simple_ast do
305
- let(:ast) { parse_ast('name "webserver"') }
306
- it "raises if the field name is nil" do
307
- expect { api.field(ast, nil) }.to raise_error ArgumentError
308
- end
309
- it "raises if the field name is empty" do
310
- expect { api.field(ast, "") }.to raise_error ArgumentError
311
- end
312
- it "returns empty if the field is not present" do
313
- expect(api.field(ast, :common_name)).to be_empty
314
- end
315
- it "accepts a string for the field name" do
316
- expect(api.field(ast, "name")).to_not be_empty
317
- end
318
- it "accepts a symbol for the field name" do
319
- expect(api.field(ast, :name)).to_not be_empty
320
- end
321
- end
322
- it "returns fields when the value is an embedded string expression" do
323
- ast = parse_ast(%q{
324
- name "#{foo}_#{bar}"
325
- }.strip)
326
- expect(api.field(ast, :name).size).to eq 1
327
- end
328
- it "returns fields when the value is a method call" do
329
- ast = parse_ast(%q{
330
- name generate_name
331
- }.strip)
332
- expect(api.field(ast, :name).size).to eq 1
333
- end
334
- it "returns both fields if the field is specified twice" do
335
- ast = parse_ast(%q{
336
- name "webserver"
337
- name "database"
338
- }.strip)
339
- expect(api.field(ast, :name).size).to eq 2
340
- end
341
- end
342
-
343
- describe "#field_value" do
344
- describe :simple_ast do
345
- let(:ast) { parse_ast('name "webserver"') }
346
- it "raises if the field name is nil" do
347
- expect { api.field_value(ast, nil) }.to raise_error ArgumentError
348
- end
349
- it "raises if the field name is empty" do
350
- expect { api.field_value(ast, "") }.to raise_error ArgumentError
351
- end
352
- it "is falsy if the field is not present" do
353
- expect(api.field_value(ast, :common_name)).to be_falsey
354
- end
355
- it "accepts a string for the field name" do
356
- expect(api.field_value(ast, "name")).to eq "webserver"
357
- end
358
- it "accepts a symbol for the field name" do
359
- expect(api.field_value(ast, :name)).to eq "webserver"
360
- end
361
- end
362
- it "is falsy when the value is an embedded string expression" do
363
- ast = parse_ast(%q{
364
- name "#{foo}_#{bar}"
365
- }.strip)
366
- expect(api.field_value(ast, :name)).to be_falsey
367
- end
368
- it "is falsy when the value is a method call" do
369
- ast = parse_ast(%q{
370
- name generate_name('foo')
371
- }.strip)
372
- expect(api.field_value(ast, :name)).to be_falsey
373
- end
374
- it "returns the last value if the field is specified twice" do
375
- ast = parse_ast(%q{
376
- name "webserver"
377
- name "database"
378
- }.strip)
379
- expect(api.field_value(ast, :name)).to eq "database"
380
- end
381
- end
382
-
383
- describe "#file_match" do
384
- it "includes the provided filename in the match" do
385
- expect(api.file_match("foo.rb")[:filename]).to eq "foo.rb"
386
- end
387
- it "retains the full provided filename path in the match" do
388
- expect(api.file_match("foo/bar/foo.rb")[:filename]).to eq "foo/bar/foo.rb"
389
- end
390
- it "raises an error if the provided filename is nil" do
391
- expect { api.file_match(nil) }.to raise_error ArgumentError
392
- end
393
- it "sets the line and column to the beginning of the file" do
394
- match = api.file_match("bar.rb")
395
- expect(match[:line]).to eq 1
396
- expect(match[:column]).to eq 1
397
- end
398
- end
399
-
400
- describe "#find_resources" do
401
- let(:ast) { double() }
402
- it "returns empty unless the ast supports XPath" do
403
- expect(api.find_resources(nil)).to be_empty
404
- end
405
- it "restricts by resource type when provided an array" do
406
- expect(ast).to receive(:xpath).with("//method_add_block[command/ident[@value='file' or @value='template']][command/ident/@value != 'action']").and_return(["method_add_block"])
407
- api.find_resources(ast, type: %w{file template})
408
- end
409
- it "restricts by resource type when provided a string" do
410
- expect(ast).to receive(:xpath).with("//method_add_block[command/ident[@value='file']][command/ident/@value != 'action']").and_return(["method_add_block"])
411
- api.find_resources(ast, type: "file")
412
- end
413
- it "does not restrict by resource type when not provided" do
414
- expect(ast).to receive(:xpath).with("//method_add_block[command/ident][command/ident/@value != 'action']").and_return(["method_add_block"])
415
- api.find_resources(ast)
416
- end
417
- it "allows resource type to be specified as :any" do
418
- expect(ast).to receive(:xpath).with("//method_add_block[command/ident][command/ident/@value != 'action']").and_return(["method_add_block"])
419
- api.find_resources(ast, type: :any)
420
- end
421
- it "returns any matches" do
422
- expect(ast).to receive(:xpath).with(kind_of(String)).and_return(["method_add_block"])
423
- expect(api.find_resources(ast)).to eq ["method_add_block"]
424
- end
425
- end
426
-
427
- describe "#included_recipes" do
428
- let(:ast) { double() }
429
- it "raises if the ast does not support XPath" do
430
- expect { api.included_recipes(nil) }.to raise_error ArgumentError
431
- end
432
- it "returns an empty hash if there are no included recipes" do
433
- expect(ast).to receive(:xpath).with(kind_of(String)).and_return([])
434
- expect(api.included_recipes(ast).keys).to be_empty
435
- end
436
- it "returns a hash keyed by recipe name" do
437
- expect(ast).to receive(:xpath).with(kind_of(String)).and_return([{ "value" => "foo::bar" }])
438
- expect(api.included_recipes(ast).keys).to eq ["foo::bar"]
439
- end
440
- it "returns a hash where the values are the matching nodes" do
441
- expect(ast).to receive(:xpath).with(kind_of(String)).and_return([{ "value" => "foo::bar" }])
442
- expect(api.included_recipes(ast).values).to eq [[{ "value" => "foo::bar" }]]
443
- end
444
- it "correctly keys an included recipe specified as a string literal" do
445
- ast = parse_ast(%q{
446
- include_recipe "foo::default"
447
- })
448
- expect(api.included_recipes(ast).keys).to eq ["foo::default"]
449
- end
450
- describe "embedded expression - recipe name" do
451
- let(:ast) do
452
- parse_ast(%q{
453
- include_recipe "foo::#{bar}"
454
- })
455
- end
456
- it "returns the literal string component by default" do
457
- expect(api.included_recipes(ast).keys).to eq ["foo::"]
458
- end
459
- it "returns the literal string part of the AST" do
460
- expect(api.included_recipes(ast)["foo::"].first).to respond_to :xpath
461
- end
462
- it "returns empty if asked to exclude statements with embedded expressions" do
463
- expect(api.included_recipes(ast, with_partial_names: false)).to be_empty
464
- end
465
- it "returns the literals if asked to include statements with embedded expressions" do
466
- expect(api.included_recipes(ast, with_partial_names: true).keys).to eq ["foo::"]
467
- end
468
- end
469
- describe "embedded expression - cookbook name" do
470
- let(:ast) do
471
- parse_ast(%q{
472
- include_recipe "#{foo}::bar"
473
- })
474
- end
475
- it "returns the literal string component by default" do
476
- expect(api.included_recipes(ast).keys).to eq ["::bar"]
477
- end
478
- it "returns the literal string part of the AST" do
479
- expect(api.included_recipes(ast)["::bar"].first).to respond_to :xpath
480
- end
481
- it "returns empty if asked to exclude statements with embedded expressions" do
482
- expect(api.included_recipes(ast, with_partial_names: false)).to be_empty
483
- end
484
- end
485
- describe "embedded expression - partial cookbook name" do
486
- let(:ast) do
487
- parse_ast(%q{
488
- include_recipe "#{foo}_foo::bar"
489
- })
490
- end
491
- it "returns the literal string component by default" do
492
- expect(api.included_recipes(ast).keys).to eq ["_foo::bar"]
493
- end
494
- it "returns the literal string part of the AST" do
495
- expect(api.included_recipes(ast)["_foo::bar"].first).to respond_to :xpath
496
- end
497
- it "returns empty if asked to exclude statements with embedded expressions" do
498
- expect(api.included_recipes(ast, with_partial_names: false)).to be_empty
499
- end
500
- end
501
- end
502
-
503
- describe :AttFilter do
504
- describe "#is_att_type" do
505
- let(:filter) { FoodCritic::Api::AttFilter.new }
506
- it "returns empty if the argument is not enumerable" do
507
- expect(filter.is_att_type(nil)).to be_empty
508
- end
509
- it "filters out values that are not Chef node attribute types" do
510
- nodes = %w{node node badger default override ostrich set normal}
511
- expect(filter.is_att_type(nodes).uniq.size).to eq 5
512
- end
513
- it "returns all filtered nodes" do
514
- nodes = %w{node node override default normal set set override}
515
- expect(filter.is_att_type(nodes)).to eq nodes
516
- end
517
- it "returns empty if there are no Chef node attribute types" do
518
- nodes = %w{squirrel badger pooh tigger}
519
- expect(filter.is_att_type(nodes)).to be_empty
520
- end
521
- end
522
- end
523
-
524
- describe "#literal_searches" do
525
- let(:ast) { double() }
526
- it "returns empty if the AST does not support XPath expressions" do
527
- expect(api.literal_searches(nil)).to be_empty
528
- end
529
- it "returns empty if the AST has no elements" do
530
- expect(ast).to receive(:xpath).with(kind_of(String)).and_return([])
531
- expect(api.literal_searches(ast)).to be_empty
532
- end
533
- it "returns the AST elements for each literal search" do
534
- expect(ast).to receive(:xpath).with(kind_of(String)).and_return(["tstring_content"])
535
- expect(api.literal_searches(ast)).to eq ["tstring_content"]
536
- end
537
- end
538
-
539
- describe "#match" do
540
- it "raises if the provided node is nil" do
541
- expect { api.match(nil) }.to raise_error ArgumentError
542
- end
543
- it "raises if the provided node does not support XPath" do
544
- expect { api.match(Object.new) }.to raise_error ArgumentError
545
- end
546
- it "returns nil if there is no nested position node" do
547
- node = double()
548
- expect(node).to receive(:xpath).with("descendant::pos").and_return([])
549
- expect(api.match(node)).to be nil
550
- end
551
- it "uses the position of the first position node if there are multiple" do
552
- node = double()
553
- expect(node).to receive(:xpath).with("descendant::pos").and_return([
554
- { "name" => "pos", "line" => "1", "column" => "10" },
555
- { "name" => "pos", "line" => "3", "column" => "16" }])
556
- match = api.match(node)
557
- expect(match[:line]).to eq 1
558
- expect(match[:column]).to eq 10
559
- end
560
- describe :matched_node_name do
561
- let(:node) do
562
- node = double()
563
- expect(node).to receive(:xpath).with("descendant::pos").and_return([{ "name" => "pos", "line" => "1", "column" => "10" }])
564
- node
565
- end
566
- it "includes the name of the node in the match" do
567
- expect(node).to receive(:name).and_return("command")
568
- expect(api.match(node)).to eq({ matched: "command", line: 1,
569
- column: 10 })
570
- end
571
- it "sets the matched name to empty if the element does not have a name" do
572
- expect(api.match(node)).to eq({ matched: "", line: 1, column: 10 })
573
- end
574
- end
575
- end
576
-
577
- describe "#notifications" do
578
- it "returns empty if the provided AST does not support XPath" do
579
- expect(api.notifications(nil)).to be_empty
580
- end
581
- it "returns empty if there are no notifications" do
582
- ast = parse_ast(%q{
583
- template "/etc/nscd.conf" do
584
- source "nscd.conf"
585
- owner "root"
586
- group "root"
587
- end
588
- })
589
- expect(api.notifications(ast)).to be_empty
590
- end
591
- describe "malformed syntax" do
592
- it "returns empty if no notifies value is provided" do
593
- ast = parse_ast(%q{
594
- template "/etc/nscd.conf" do
595
- source "nscd.conf"
596
- owner "root"
597
- group "root"
598
- notifies
599
- end
600
- })
601
- expect(api.notifications(ast)).to be_empty
602
- end
603
- it "returns empty if no subscribes value is provided" do
604
- ast = parse_ast(%q{
605
- template "/etc/nscd.conf" do
606
- source "nscd.conf"
607
- owner "root"
608
- group "root"
609
- subscribes
610
- end
611
- })
612
- expect(api.notifications(ast)).to be_empty
613
- end
614
- it "returns empty if only the notifies action is provided" do
615
- ast = parse_ast(%q{
616
- template "/etc/nscd.conf" do
617
- source "nscd.conf"
618
- owner "root"
619
- group "root"
620
- notifies :restart
621
- end
622
- })
623
- expect(api.notifications(ast)).to be_empty
624
- end
625
- it "returns empty if only the subscribes action is provided" do
626
- ast = parse_ast(%q{
627
- template "/etc/nscd.conf" do
628
- source "nscd.conf"
629
- owner "root"
630
- group "root"
631
- subscribes :restart
632
- end
633
- })
634
- expect(api.notifications(ast)).to be_empty
635
- end
636
- describe "returns empty if the service name is missing" do
637
- it "old-style notifications" do
638
- ast = parse_ast(%q{
639
- template "/etc/nscd.conf" do
640
- source "nscd.conf"
641
- owner "root"
642
- group "root"
643
- notifies :restart, resources(:service)
644
- end
645
- })
646
- expect(api.notifications(ast)).to be_empty
647
- end
648
- it "old-style subscriptions" do
649
- ast = parse_ast(%q{
650
- template "/etc/nscd.conf" do
651
- source "nscd.conf"
652
- owner "root"
653
- group "root"
654
- subscribes:restart, resources(:service)
655
- end
656
- })
657
- expect(api.notifications(ast)).to be_empty
658
- end
659
- it "new-style notifications" do
660
- ast = parse_ast(%q{
661
- template "/etc/nscd.conf" do
662
- source "nscd.conf"
663
- owner "root"
664
- group "root"
665
- notifies :restart, "service"
666
- end
667
- })
668
- expect(api.notifications(ast)).to be_empty
669
- end
670
- it "new-style subscriptions" do
671
- ast = parse_ast(%q{
672
- template "/etc/nscd.conf" do
673
- source "nscd.conf"
674
- owner "root"
675
- group "root"
676
- subscribes:restart, "service"
677
- end
678
- })
679
- expect(api.notifications(ast)).to be_empty
680
- end
681
- end
682
- describe "returns empty if the resource type is missing" do
683
- it "old-style notifications" do
684
- ast = parse_ast(%q{
685
- template "/etc/nscd.conf" do
686
- source "nscd.conf"
687
- owner "root"
688
- group "root"
689
- notifies :restart, resources("nscd")
690
- end
691
- })
692
- expect(api.notifications(ast)).to be_empty
693
- end
694
- it "old-style subscriptions" do
695
- ast = parse_ast(%q{
696
- template "/etc/nscd.conf" do
697
- source "nscd.conf"
698
- owner "root"
699
- group "root"
700
- subscribes :restart, resources("nscd")
701
- end
702
- })
703
- expect(api.notifications(ast)).to be_empty
704
- end
705
- it "new-style notifications" do
706
- ast = parse_ast(%q{
707
- template "/etc/nscd.conf" do
708
- source "nscd.conf"
709
- owner "root"
710
- group "root"
711
- notifies :restart, "nscd"
712
- end
713
- })
714
- expect(api.notifications(ast)).to be_empty
715
- end
716
- it "new-style subscriptions" do
717
- ast = parse_ast(%q{
718
- template "/etc/nscd.conf" do
719
- source "nscd.conf"
720
- owner "root"
721
- group "root"
722
- subscribes :restart, "nscd"
723
- end
724
- })
725
- expect(api.notifications(ast)).to be_empty
726
- end
727
- end
728
- describe "returns empty if the resource name is missing" do
729
- it "old-style notifications" do
730
- ast = parse_ast(%q{
731
- template "/etc/nscd.conf" do
732
- source "nscd.conf"
733
- owner "root"
734
- group "root"
735
- notifies :restart, resources(:service)
736
- end
737
- })
738
- expect(api.notifications(ast)).to be_empty
739
- end
740
- it "old-style subscriptions" do
741
- ast = parse_ast(%q{
742
- template "/etc/nscd.conf" do
743
- source "nscd.conf"
744
- owner "root"
745
- group "root"
746
- subscribes :restart, resources(:service)
747
- end
748
- })
749
- expect(api.notifications(ast)).to be_empty
750
- end
751
- it "new-style notifications" do
752
- ast = parse_ast(%q{
753
- template "/etc/nscd.conf" do
754
- source "nscd.conf"
755
- owner "root"
756
- group "root"
757
- notifies :restart, "service[]"
758
- end
759
- })
760
- expect(api.notifications(ast)).to be_empty
761
- end
762
- it "new-style subscriptions" do
763
- ast = parse_ast(%q{
764
- template "/etc/nscd.conf" do
765
- source "nscd.conf"
766
- owner "root"
767
- group "root"
768
- subscribes :restart, "service[]"
769
- end
770
- })
771
- expect(api.notifications(ast)).to be_empty
772
- end
773
- end
774
- it "returns empty if the left square bracket is missing" do
775
- ast = parse_ast(%q{
776
- template "/etc/nscd.conf" do
777
- source "nscd.conf"
778
- owner "root"
779
- group "root"
780
- subscribes :restart, "servicefoo]"
781
- end
782
- })
783
- expect(api.notifications(ast)).to be_empty
784
- end
785
- it "returns empty if the right square bracket is missing" do
786
- ast = parse_ast(%q{
787
- template "/etc/nscd.conf" do
788
- source "nscd.conf"
789
- owner "root"
790
- group "root"
791
- subscribes :restart, "service[foo"
792
- end
793
- })
794
- expect(api.notifications(ast)).to be_empty
795
- end
796
- end
797
- it "understands the old-style notifications" do
798
- ast = parse_ast(%q{
799
- template "/etc/nscd.conf" do
800
- source "nscd.conf"
801
- owner "root"
802
- group "root"
803
- notifies :restart, resources(:service => "nscd")
804
- end
805
- })
806
- expect(api.notifications(ast)).to eq [{
807
- type: :notifies,
808
- action: :restart,
809
- resource_type: :service,
810
- resource_name: "nscd",
811
- timing: :delayed,
812
- style: :old,
813
- }]
814
- end
815
- it "understands old-style notifications with :'symbol' literals as action" do
816
- ast = parse_ast(%q{
817
- template "/etc/nscd.conf" do
818
- source "nscd.conf"
819
- owner "root"
820
- group "root"
821
- notifies :'soft-restart', resources(:service => "nscd")
822
- end
823
- })
824
- expect(api.notifications(ast)).to eq [{
825
- type: :notifies,
826
- action: :'soft-restart',
827
- resource_type: :service,
828
- resource_name: "nscd",
829
- timing: :delayed,
830
- style: :old,
831
- }]
832
- end
833
- it "understands old-style notifications with added parentheses" do
834
- ast = parse_ast(%q{
835
- template "/etc/nscd.conf" do
836
- source "nscd.conf"
837
- owner "root"
838
- group "root"
839
- notifies(:restart, resources(:service => "nscd"))
840
- end
841
- })
842
- expect(api.notifications(ast)).to eq [{
843
- type: :notifies,
844
- action: :restart,
845
- resource_type: :service,
846
- resource_name: "nscd",
847
- timing: :delayed,
848
- style: :old,
849
- }]
850
- end
851
- it "understands old-style notifications with ruby 1.9 hash syntax" do
852
- ast = parse_ast(%q{
853
- template "/etc/nscd.conf" do
854
- source "nscd.conf"
855
- owner "root"
856
- group "root"
857
- notifies :restart, resources(service: "nscd")
858
- end
859
- })
860
- expect(api.notifications(ast)).to eq [{
861
- type: :notifies,
862
- action: :restart,
863
- resource_type: :service,
864
- resource_name: "nscd",
865
- timing: :delayed,
866
- style: :old,
867
- }]
868
- end
869
- it "understands the old-style subscriptions" do
870
- ast = parse_ast(%q{
871
- template "/etc/nscd.conf" do
872
- source "nscd.conf"
873
- owner "root"
874
- group "root"
875
- subscribes :restart, resources(:service => "nscd")
876
- end
877
- })
878
- expect(api.notifications(ast)).to eq [{
879
- type: :subscribes,
880
- action: :restart,
881
- resource_type: :service,
882
- resource_name: "nscd",
883
- timing: :delayed,
884
- style: :old,
885
- }]
886
- end
887
- it "understands old-style subscriptions with added parentheses" do
888
- ast = parse_ast(%q{
889
- template "/etc/nscd.conf" do
890
- source "nscd.conf"
891
- owner "root"
892
- group "root"
893
- subscribes(:restart, resources(:service => "nscd"))
894
- end
895
- })
896
- expect(api.notifications(ast)).to eq [{
897
- type: :subscribes,
898
- action: :restart,
899
- resource_type: :service,
900
- resource_name: "nscd",
901
- timing: :delayed,
902
- style: :old,
903
- }]
904
- end
905
- it "understands the new-style notifications" do
906
- ast = parse_ast(%q{
907
- template "/etc/nscd.conf" do
908
- source "nscd.conf"
909
- owner "root"
910
- group "root"
911
- notifies :restart, "service[nscd]"
912
- end
913
- })
914
- expect(api.notifications(ast)).to eq [{
915
- type: :notifies,
916
- action: :restart,
917
- resource_type: :service,
918
- resource_name: "nscd",
919
- timing: :delayed,
920
- style: :new,
921
- }]
922
- end
923
- it "understands new-style notifications with :'symbol' literals as action" do
924
- ast = parse_ast(%q{
925
- template "/etc/nscd.conf" do
926
- source "nscd.conf"
927
- owner "root"
928
- group "root"
929
- notifies :'soft-restart', "service[nscd]"
930
- end
931
- })
932
- expect(api.notifications(ast)).to eq [{
933
- type: :notifies,
934
- action: :'soft-restart',
935
- resource_type: :service,
936
- resource_name: "nscd",
937
- timing: :delayed,
938
- style: :new,
939
- }]
940
- end
941
- it "understands new-style notifications with added parentheses" do
942
- ast = parse_ast(%q{
943
- template "/etc/nscd.conf" do
944
- source "nscd.conf"
945
- owner "root"
946
- group "root"
947
- notifies(:restart, "service[nscd]")
948
- end
949
- })
950
- expect(api.notifications(ast)).to eq [{
951
- type: :notifies,
952
- action: :restart,
953
- resource_type: :service,
954
- resource_name: "nscd",
955
- timing: :delayed,
956
- style: :new,
957
- }]
958
- end
959
- it "understands the new-style subscriptions" do
960
- ast = parse_ast(%q{
961
- template "/etc/nscd.conf" do
962
- source "nscd.conf"
963
- owner "root"
964
- group "root"
965
- subscribes :restart, "service[nscd]"
966
- end
967
- })
968
- expect(api.notifications(ast)).to eq [{
969
- type: :subscribes,
970
- action: :restart,
971
- resource_type: :service,
972
- resource_name: "nscd",
973
- timing: :delayed,
974
- style: :new,
975
- }]
976
- end
977
- it "understands new-style subscriptions with added parentheses" do
978
- ast = parse_ast(%q{
979
- template "/etc/nscd.conf" do
980
- source "nscd.conf"
981
- owner "root"
982
- group "root"
983
- subscribes(:restart, "service[nscd]")
984
- end
985
- })
986
- expect(api.notifications(ast)).to eq [{
987
- type: :subscribes,
988
- action: :restart,
989
- resource_type: :service,
990
- resource_name: "nscd",
991
- timing: :delayed,
992
- style: :new,
993
- }]
994
- end
995
- describe "supports a resource both notifying and subscribing" do
996
- it "old-style notifications" do
997
- ast = parse_ast(%q{
998
- template "/etc/nscd.conf" do
999
- source "nscd.conf"
1000
- owner "root"
1001
- group "root"
1002
- notifies :restart, resources(:service => "nscd")
1003
- subscribes :create, resources(:template => "/etc/nscd.conf")
1004
- end
1005
- })
1006
- expect(api.notifications(ast)).to eq [
1007
- {
1008
- type: :notifies,
1009
- action: :restart,
1010
- resource_type: :service,
1011
- resource_name: "nscd",
1012
- timing: :delayed,
1013
- style: :old,
1014
- },
1015
- {
1016
- type: :subscribes,
1017
- action: :create,
1018
- resource_type: :template,
1019
- resource_name: "/etc/nscd.conf",
1020
- timing: :delayed,
1021
- style: :old,
1022
- },
1023
- ]
1024
- end
1025
- it "new-style notifications" do
1026
- ast = parse_ast(%q{
1027
- template "/etc/nscd.conf" do
1028
- source "nscd.conf"
1029
- owner "root"
1030
- group "root"
1031
- notifies :restart, "service[nscd]"
1032
- subscribes :create, "template[/etc/nscd.conf]"
1033
- end
1034
- })
1035
- expect(api.notifications(ast)).to eq [
1036
- {
1037
- type: :notifies,
1038
- action: :restart,
1039
- resource_type: :service,
1040
- resource_name: "nscd",
1041
- timing: :delayed,
1042
- style: :new,
1043
- },
1044
- {
1045
- type: :subscribes,
1046
- action: :create,
1047
- resource_type: :template,
1048
- resource_name: "/etc/nscd.conf",
1049
- timing: :delayed,
1050
- style: :new,
1051
- },
1052
- ]
1053
- end
1054
- end
1055
- it "understands the old-style notifications with timing" do
1056
- ast = parse_ast(%q{
1057
- template "/etc/nscd.conf" do
1058
- source "nscd.conf"
1059
- owner "root"
1060
- group "root"
1061
- notifies :restart, resources(:service => "nscd"), :immediately
1062
- end
1063
- })
1064
- expect(api.notifications(ast)).to eq [{
1065
- type: :notifies,
1066
- action: :restart,
1067
- resource_type: :service,
1068
- resource_name: "nscd",
1069
- timing: :immediate,
1070
- style: :old,
1071
- }]
1072
- end
1073
- it "understands the old-style subscriptions with timing" do
1074
- ast = parse_ast(%q{
1075
- template "/etc/nscd.conf" do
1076
- source "nscd.conf"
1077
- owner "root"
1078
- group "root"
1079
- subscribes :restart, resources(:service => "nscd"), :immediately
1080
- end
1081
- })
1082
- expect(api.notifications(ast)).to eq [{
1083
- type: :subscribes,
1084
- action: :restart,
1085
- resource_type: :service,
1086
- resource_name: "nscd",
1087
- timing: :immediate,
1088
- style: :old,
1089
- }]
1090
- end
1091
- it "understands the new-style notifications with timing" do
1092
- ast = parse_ast(%q{
1093
- template "/etc/nscd.conf" do
1094
- source "nscd.conf"
1095
- owner "root"
1096
- group "root"
1097
- notifies :restart, "service[nscd]", :immediately
1098
- end
1099
- })
1100
- expect(api.notifications(ast)).to eq [{
1101
- type: :notifies,
1102
- action: :restart,
1103
- resource_type: :service,
1104
- resource_name: "nscd",
1105
- timing: :immediate,
1106
- style: :new,
1107
- }]
1108
- end
1109
- it "understands the new-style subscriptions with timing" do
1110
- ast = parse_ast(%q{
1111
- template "/etc/nscd.conf" do
1112
- source "nscd.conf"
1113
- owner "root"
1114
- group "root"
1115
- subscribes :restart, "service[nscd]", :immediately
1116
- end
1117
- })
1118
- expect(api.notifications(ast)).to eq [{
1119
- type: :subscribes,
1120
- action: :restart,
1121
- resource_type: :service,
1122
- resource_name: "nscd",
1123
- timing: :immediate,
1124
- style: :new,
1125
- }]
1126
- end
1127
- describe "can be passed an individual resource" do
1128
- it "old-style notifications" do
1129
- ast = parse_ast(%q{
1130
- service "nscd" do
1131
- action :start
1132
- end
1133
- template "/etc/nscd.conf" do
1134
- source "nscd.conf"
1135
- owner "root"
1136
- group "root"
1137
- notifies :restart, resources(:service => "nscd")
1138
- end
1139
- })
1140
- expect(api.notifications(api.find_resources(ast, type: :template).first)).to eq [
1141
- { type: :notifies, action: :restart, resource_type: :service,
1142
- resource_name: "nscd", timing: :delayed,
1143
- style: :old },
1144
- ]
1145
- end
1146
- it "old-style subscriptions" do
1147
- ast = parse_ast(%q{
1148
- service "nscd" do
1149
- action :start
1150
- end
1151
- template "/etc/nscd.conf" do
1152
- source "nscd.conf"
1153
- owner "root"
1154
- group "root"
1155
- subscribes :restart, resources(:service => "nscd")
1156
- end
1157
- })
1158
- expect(api.notifications(api.find_resources(ast, type: :template).first)).to eq [
1159
- { type: :subscribes, action: :restart, resource_type: :service,
1160
- resource_name: "nscd", timing: :delayed,
1161
- style: :old },
1162
- ]
1163
- end
1164
- it "new-style notifications" do
1165
- ast = parse_ast(%q{
1166
- service "nscd" do
1167
- action :start
1168
- end
1169
- template "/etc/nscd.conf" do
1170
- source "nscd.conf"
1171
- owner "root"
1172
- group "root"
1173
- notifies :restart, "service[nscd]"
1174
- end
1175
- })
1176
- expect(api.notifications(api.find_resources(ast, type: :template).first)).to eq [
1177
- { type: :notifies, action: :restart, resource_type: :service,
1178
- resource_name: "nscd", timing: :delayed,
1179
- style: :new },
1180
- ]
1181
- end
1182
- it "new-style subscriptions" do
1183
- ast = parse_ast(%q{
1184
- service "nscd" do
1185
- action :start
1186
- end
1187
- template "/etc/nscd.conf" do
1188
- source "nscd.conf"
1189
- owner "root"
1190
- group "root"
1191
- subscribes :restart, "service[nscd]"
1192
- end
1193
- })
1194
- expect(api.notifications(api.find_resources(ast, type: :template).first)).to eq [
1195
- { type: :subscribes, action: :restart, resource_type: :service,
1196
- resource_name: "nscd", timing: :delayed,
1197
- style: :new },
1198
- ]
1199
- end
1200
- end
1201
- describe "supports multiple notifications on a single resource" do
1202
- it "old-style notifications" do
1203
- ast = parse_ast(%q{
1204
- template "/etc/nscd.conf" do
1205
- source "nscd.conf"
1206
- owner "root"
1207
- group "root"
1208
- notifies :stop, resources(:service => "nscd")
1209
- notifies :start, resources(:service => "nscd")
1210
- end
1211
- })
1212
- expect(api.notifications(ast)).to eq [
1213
- { type: :notifies, action: :stop, resource_type: :service,
1214
- resource_name: "nscd", timing: :delayed,
1215
- style: :old },
1216
- { type: :notifies, action: :start, resource_type: :service,
1217
- resource_name: "nscd", timing: :delayed,
1218
- style: :old },
1219
- ]
1220
- end
1221
- it "old-style subscriptions" do
1222
- ast = parse_ast(%q{
1223
- template "/etc/nscd.conf" do
1224
- source "nscd.conf"
1225
- owner "root"
1226
- group "root"
1227
- subscribes :stop, resources(:service => "nscd")
1228
- subscribes :start, resources(:service => "nscd")
1229
- end
1230
- })
1231
- expect(api.notifications(ast)).to eq [
1232
- { type: :subscribes, action: :stop, resource_type: :service,
1233
- resource_name: "nscd", timing: :delayed,
1234
- style: :old },
1235
- { type: :subscribes, action: :start, resource_type: :service,
1236
- resource_name: "nscd", timing: :delayed,
1237
- style: :old },
1238
- ]
1239
- end
1240
- it "new-style notifications" do
1241
- ast = parse_ast(%q{
1242
- template "/etc/nscd.conf" do
1243
- source "nscd.conf"
1244
- owner "root"
1245
- group "root"
1246
- notifies :stop, "service[nscd]"
1247
- notifies :start, "service[nscd]"
1248
- end
1249
- })
1250
- expect(api.notifications(ast)).to eq [
1251
- { type: :notifies, action: :stop, resource_type: :service,
1252
- resource_name: "nscd", timing: :delayed,
1253
- style: :new },
1254
- { type: :notifies, action: :start, resource_type: :service,
1255
- resource_name: "nscd", timing: :delayed,
1256
- style: :new },
1257
- ]
1258
- end
1259
- it "new-style subscriptions" do
1260
- ast = parse_ast(%q{
1261
- template "/etc/nscd.conf" do
1262
- source "nscd.conf"
1263
- owner "root"
1264
- group "root"
1265
- subscribes :stop, "service[nscd]"
1266
- subscribes :start, "service[nscd]"
1267
- end
1268
- })
1269
- expect(api.notifications(ast)).to eq [
1270
- { type: :subscribes, action: :stop, resource_type: :service,
1271
- resource_name: "nscd", timing: :delayed,
1272
- style: :new },
1273
- { type: :subscribes, action: :start, resource_type: :service,
1274
- resource_name: "nscd", timing: :delayed,
1275
- style: :new },
1276
- ]
1277
- end
1278
- end
1279
- describe "understands notifications for an execute resource" do
1280
- it "old-style notifications" do
1281
- ast = parse_ast(%q{
1282
- template "/tmp/foo.bar" do
1283
- source "foo.bar.erb"
1284
- notifies :run, resources(:execute => "foo")
1285
- end
1286
- })
1287
- expect(api.notifications(ast)).to eq [
1288
- { type: :notifies, action: :run, resource_type: :execute,
1289
- resource_name: "foo", timing: :delayed,
1290
- style: :old },
1291
- ]
1292
- end
1293
- it "old-style subscriptions" do
1294
- ast = parse_ast(%q{
1295
- template "/tmp/foo.bar" do
1296
- source "foo.bar.erb"
1297
- subscribes :run, resources(:execute => "foo")
1298
- end
1299
- })
1300
- expect(api.notifications(ast)).to eq [
1301
- { type: :subscribes, action: :run, resource_type: :execute,
1302
- resource_name: "foo", timing: :delayed,
1303
- style: :old },
1304
- ]
1305
- end
1306
- it "old-style notifications" do
1307
- ast = parse_ast(%q{
1308
- template "/tmp/foo.bar" do
1309
- source "foo.bar.erb"
1310
- notifies :run, "execute[foo]"
1311
- end
1312
- })
1313
- expect(api.notifications(ast)).to eq [
1314
- { type: :notifies, action: :run, resource_type: :execute,
1315
- resource_name: "foo", timing: :delayed,
1316
- style: :new },
1317
- ]
1318
- end
1319
- it "old-style subscriptions" do
1320
- ast = parse_ast(%q{
1321
- template "/tmp/foo.bar" do
1322
- source "foo.bar.erb"
1323
- subscribes :run, "execute[foo]"
1324
- end
1325
- })
1326
- expect(api.notifications(ast)).to eq [
1327
- { type: :subscribes, action: :run, resource_type: :execute,
1328
- resource_name: "foo", timing: :delayed,
1329
- style: :new },
1330
- ]
1331
- end
1332
- end
1333
- describe "sets the notification timing to delayed if specified" do
1334
- it "old-style notifications" do
1335
- ast = parse_ast(%q{
1336
- template "/etc/foo.conf" do
1337
- notifies :run, resources(execute => "robespierre"), :delayed
1338
- end
1339
- })
1340
- expect(api.notifications(ast).first[:timing]).to eq :delayed
1341
- end
1342
- it "old-style subscriptions" do
1343
- ast = parse_ast(%q{
1344
- template "/etc/foo.conf" do
1345
- subscribes :run, resources(execute => "robespierre"), :delayed
1346
- end
1347
- })
1348
- expect(api.notifications(ast).first[:timing]).to eq :delayed
1349
- end
1350
- it "new-style notifications" do
1351
- ast = parse_ast(%q{
1352
- template "/etc/foo.conf" do
1353
- notifies :run, "execute[robespierre]", :delayed
1354
- end
1355
- })
1356
- expect(api.notifications(ast).first[:timing]).to eq :delayed
1357
- end
1358
- it "new-style subscriptions" do
1359
- ast = parse_ast(%q{
1360
- template "/etc/foo.conf" do
1361
- subscribes :run, "execute[robespierre]", :delayed
1362
- end
1363
- })
1364
- expect(api.notifications(ast).first[:timing]).to eq :delayed
1365
- end
1366
- end
1367
- describe "sets the notification timing to immediate if specified as immediate" do
1368
- it "old-style notifications" do
1369
- ast = parse_ast(%q{
1370
- template "/etc/foo.conf" do
1371
- notifies :run, resources(execute => "robespierre"), :immediate
1372
- end
1373
- })
1374
- expect(api.notifications(ast).first[:timing]).to eq :immediate
1375
- end
1376
- it "old-style subscriptions" do
1377
- ast = parse_ast(%q{
1378
- template "/etc/foo.conf" do
1379
- subscribes :run, resources(execute => "robespierre"), :immediate
1380
- end
1381
- })
1382
- expect(api.notifications(ast).first[:timing]).to eq :immediate
1383
- end
1384
- it "new-style notifications" do
1385
- ast = parse_ast(%q{
1386
- template "/etc/foo.conf" do
1387
- notifies :run, "execute[robespierre]", :immediate
1388
- end
1389
- })
1390
- expect(api.notifications(ast).first[:timing]).to eq :immediate
1391
- end
1392
- it "new-style subscriptions" do
1393
- ast = parse_ast(%q{
1394
- template "/etc/foo.conf" do
1395
- subscribes :run, "execute[robespierre]", :immediate
1396
- end
1397
- })
1398
- expect(api.notifications(ast).first[:timing]).to eq :immediate
1399
- end
1400
- end
1401
-
1402
- describe "sets the notification timing to immediate if specified as immediately" do
1403
- it "old-style notifications" do
1404
- ast = parse_ast(%q{
1405
- template "/etc/foo.conf" do
1406
- notifies :run, resources(execute => "robespierre"), :immediately
1407
- end
1408
- })
1409
- expect(api.notifications(ast).first[:timing]).to eq :immediate
1410
- end
1411
- it "old-style subscriptions" do
1412
- ast = parse_ast(%q{
1413
- template "/etc/foo.conf" do
1414
- subscribes :run, resources(execute => "robespierre"), :immediately
1415
- end
1416
- })
1417
- expect(api.notifications(ast).first[:timing]).to eq :immediate
1418
- end
1419
- it "new-style notifications" do
1420
- ast = parse_ast(%q{
1421
- template "/etc/foo.conf" do
1422
- notifies :run, "execute[robespierre]", :immediately
1423
- end
1424
- })
1425
- expect(api.notifications(ast).first[:timing]).to eq :immediate
1426
- end
1427
- it "new-style subscriptions" do
1428
- ast = parse_ast(%q{
1429
- template "/etc/foo.conf" do
1430
- subscribes :run, "execute[robespierre]", :immediately
1431
- end
1432
- })
1433
- expect(api.notifications(ast).first[:timing]).to eq :immediate
1434
- end
1435
- end
1436
- it "passes unrecognised notification timings through unchanged" do
1437
- ast = parse_ast(%q{
1438
- template "/etc/foo.conf" do
1439
- notifies :run, resources(execute => "robespierre"), :forthwith
1440
- end
1441
- })
1442
- expect(api.notifications(ast).first[:timing]).to eq :forthwith
1443
- end
1444
- describe "resource names as expressions" do
1445
- describe "returns the AST for an embedded string" do
1446
- it "old-style notifications" do
1447
- ast = parse_ast(%q{
1448
- template "/etc/foo.conf" do
1449
- notifies :create, resources(:template => "/etc/bar/#{resource}.bar")
1450
- end
1451
- })
1452
- expect(api.notifications(ast).first[:resource_name]).to respond_to :xpath
1453
- end
1454
- it "new-style notifications" do
1455
- ast = parse_ast(%q{
1456
- template "/etc/foo.conf" do
1457
- notifies :create, "template[/etc/bar/#{resource}.bar]"
1458
- end
1459
- })
1460
- expect(api.notifications(ast).first[:resource_name]).to respond_to :xpath
1461
- end
1462
- it "new-style notifications - complete resource_name" do
1463
- ast = parse_ast(%q{
1464
- template "/etc/foo.conf" do
1465
- notifies :create, "template[#{template_path}]"
1466
- end
1467
- })
1468
- expect(api.notifications(ast).first[:resource_name]).to respond_to :xpath
1469
- end
1470
- end
1471
- describe "returns the AST for node attribute" do
1472
- it "old-style notifications" do
1473
- ast = parse_ast(%q{
1474
- template "/etc/foo.conf" do
1475
- notifies :restart, resources(:service => node['foo']['service'])
1476
- end
1477
- })
1478
- expect(api.notifications(ast).first[:resource_name]).to respond_to :xpath
1479
- end
1480
- it "new-style notifications" do
1481
- ast = parse_ast(%q{
1482
- template "/etc/foo.conf" do
1483
- notifies :restart, "service[#{node['foo']['service']}]"
1484
- end
1485
- })
1486
- expect(api.notifications(ast).first[:resource_name]).to respond_to :xpath
1487
- end
1488
- end
1489
- describe "returns the AST for variable reference" do
1490
- it "old-style notifications" do
1491
- ast = parse_ast(%q{
1492
- template "/etc/foo.conf" do
1493
- notifies :restart, resources(:service => my_service)
1494
- end
1495
- })
1496
- expect(api.notifications(ast).first[:resource_name]).to respond_to :xpath
1497
- end
1498
- it "new-style notifications" do
1499
- ast = parse_ast(%q{
1500
- template "/etc/foo.conf" do
1501
- notifies :restart, "service[#{my_service}]"
1502
- end
1503
- })
1504
- expect(api.notifications(ast).first[:resource_name]).to respond_to :xpath
1505
- end
1506
- end
1507
- end
1508
- describe "mark style of notification" do
1509
- it "specifies that the notification was in the old style" do
1510
- ast = parse_ast(%q{
1511
- template "/etc/foo.conf" do
1512
- notifies :restart, resources(:service => 'foo')
1513
- end
1514
- })
1515
- expect(api.notifications(ast).first[:style]).to eq :old
1516
- end
1517
- it "specifies that the notification was in the new style" do
1518
- ast = parse_ast(%q{
1519
- template "/etc/foo.conf" do
1520
- notifies :restart, "service[foo]"
1521
- end
1522
- })
1523
- expect(api.notifications(ast).first[:style]).to eq :new
1524
- end
1525
- end
1526
- end
1527
-
1528
- describe "#read_ast" do
1529
- it "raises if the file cannot be read" do
1530
- expect { api.read_ast(nil) }.to raise_error TypeError
1531
- end
1532
- end
1533
-
1534
- describe "#resource_attribute" do
1535
- let(:resource) do
1536
- Class.new do
1537
- def xpath(str)
1538
- raise "Not expected"
1539
- end
1540
- end.new
1541
- end
1542
- it "raises if the resource does not support XPath" do
1543
- expect { api.resource_attribute(nil, "mode") }.to raise_error ArgumentError
1544
- end
1545
- it "raises if the attribute name is empty" do
1546
- expect { api.resource_attribute(resource, "") }.to raise_error ArgumentError
1547
- end
1548
- end
1549
-
1550
- describe "#resource_attributes" do
1551
- def str_to_atts(str)
1552
- api.resource_attributes(api.find_resources(parse_ast(str)).first)
1553
- end
1554
- it "raises if the resource does not support XPath" do
1555
- expect { api.resource_attributes(nil) }.to raise_error ArgumentError
1556
- end
1557
- it "returns a string value for a literal string" do
1558
- atts = str_to_atts(%q{
1559
- directory "/foo/bar" do
1560
- owner "root"
1561
- end
1562
- })
1563
- expect(atts["owner"]).to eq "root"
1564
- end
1565
- it "returns a truthy value for a literal true" do
1566
- atts = str_to_atts(%q{
1567
- directory "/foo/bar" do
1568
- recursive true
1569
- end
1570
- })
1571
- expect(atts["recursive"]).to be true
1572
- end
1573
- it "returns a truthy value for a literal false" do
1574
- atts = str_to_atts(%q{
1575
- directory "/foo/bar" do
1576
- recursive false
1577
- end
1578
- })
1579
- expect(atts["recursive"]).to be false
1580
- end
1581
- it "decodes numeric attributes correctly" do
1582
- atts = str_to_atts(%q{
1583
- directory "/foo/bar" do
1584
- owner "root"
1585
- mode 0755
1586
- end
1587
- })
1588
- expect(atts["mode"]).to eq "0755"
1589
- end
1590
- describe "block attributes" do
1591
- it "includes attributes with brace block values in the result" do
1592
- atts = str_to_atts(%q{
1593
- file "/etc/foo" do
1594
- mode "0600"
1595
- action :create
1596
- only_if { File.exists?("/etc/bar") }
1597
- end
1598
- })
1599
- expect(atts["only_if"]).to respond_to :xpath
1600
- expect(atts["only_if"].name).to eq "brace_block"
1601
- end
1602
- it "includes attributes with do block values in the result" do
1603
- atts = str_to_atts(%q{
1604
- file "/etc/foo" do
1605
- mode "0600"
1606
- action :create
1607
- only_if do
1608
- !File.exists?(foo) || (File.exists?(bar) &&
1609
- File.mtime(baz) < last_changedate)
1610
- end
1611
- end
1612
- })
1613
- expect(atts["only_if"]).to respond_to :xpath
1614
- expect(atts["only_if"].name).to eq "do_block"
1615
- end
1616
- it "supports multiple block attributes" do
1617
- atts = str_to_atts(%q{
1618
- file "/etc/foo" do
1619
- mode "0600"
1620
- action :create
1621
- only_if { false }
1622
- not_if { true }
1623
- end
1624
- })
1625
- expect(atts["only_if"]).to respond_to :xpath
1626
- expect(atts["only_if"].name).to eq "brace_block"
1627
- expect(atts["not_if"]).to respond_to :xpath
1628
- expect(atts["not_if"].name).to eq "brace_block"
1629
- end
1630
- it "doesn't include method calls in ruby blocks" do
1631
- atts = str_to_atts(%q{
1632
- ruby_block "example" do
1633
- block do
1634
- foo do |bar|
1635
- Chef::Log.info(bar)
1636
- end
1637
- end
1638
- only_if { true }
1639
- not_if { false }
1640
- end
1641
- })
1642
- expect(atts.keys).to_not include "foo"
1643
- expect(atts["block"]).to respond_to :xpath
1644
- expect(atts["block"].name).to eq "do_block"
1645
- expect(atts["only_if"]).to respond_to :xpath
1646
- expect(atts["only_if"].name).to eq "brace_block"
1647
- expect(atts["not_if"]).to respond_to :xpath
1648
- expect(atts["not_if"].name).to eq "brace_block"
1649
- end
1650
- it "includes notifications in the result" do
1651
- atts = str_to_atts(%q{
1652
- template "/etc/httpd.conf" do
1653
- notifies :restart, "service[apache]"
1654
- end
1655
- })
1656
- expect(atts["notifies"]).to respond_to :xpath
1657
- expect(atts["notifies"].name).to eq "args_add_block"
1658
- end
1659
- it "includes old-style notifications in the result" do
1660
- atts = str_to_atts(%q{
1661
- template "/etc/httpd.conf" do
1662
- notifies :restart, resources(:service => "apache")
1663
- end
1664
- })
1665
- expect(atts["notifies"]).to respond_to :xpath
1666
- expect(atts["notifies"].name).to eq "args_add_block"
1667
- end
1668
- end
1669
- end
1670
-
1671
- describe "#resource_attributes_by_type" do
1672
- it "raises if the ast does not support XPath" do
1673
- expect { api.resource_attributes_by_type(nil) }.to raise_error ArgumentError
1674
- end
1675
- it "returns an empty hash if there are no resources" do
1676
- ast = double()
1677
- expect(ast).to receive(:xpath).with(kind_of(String)).and_return([])
1678
- expect(api.resource_attributes_by_type(ast)).to be_empty
1679
- end
1680
- end
1681
-
1682
- describe "#resource_name" do
1683
- it "raises if the resource does not support XPath" do
1684
- expect { api.resource_name("foo") }.to raise_error ArgumentError
1685
- end
1686
- it "returns the resource name for a resource" do
1687
- ast = double()
1688
- expect(ast).to receive(:xpath).with(kind_of(String)).and_return("bob")
1689
- expect(api.resource_name(ast)).to eq "bob"
1690
- end
1691
- end
1692
-
1693
- describe "#resources_by_type" do
1694
- it "raises if the ast does not support XPath" do
1695
- expect { api.resources_by_type(nil) }.to raise_error ArgumentError
1696
- end
1697
- it "returns an empty hash if there are no resources" do
1698
- ast = double()
1699
- expect(ast).to receive(:xpath).with(kind_of(String)).and_return([])
1700
- expect(api.resources_by_type(ast)).to be_empty
1701
- end
1702
- end
1703
-
1704
- describe "#resource_type" do
1705
- it "raises if the resource does not support XPath" do
1706
- expect { api.resource_type(nil) }.to raise_error ArgumentError
1707
- end
1708
- it "raises if the resource type cannot be determined" do
1709
- ast = double()
1710
- expect(ast).to receive(:xpath).with(kind_of(String)).and_return("")
1711
- expect { api.resource_type(ast) }.to raise_error ArgumentError
1712
- end
1713
- it "returns the resource type for a resource" do
1714
- ast = double()
1715
- expect(ast).to receive(:xpath).with(kind_of(String)).and_return("directory")
1716
- expect(api.resource_type(ast)).to eq "directory"
1717
- end
1718
- end
1719
-
1720
- describe "#ruby_code?" do
1721
- it "says a nil is not ruby code" do
1722
- expect(api.ruby_code?(nil)).to be_falsey
1723
- end
1724
- it "says an empty string is not ruby code" do
1725
- expect(api.ruby_code?("")).to be_falsey
1726
- end
1727
- it "coerces arguments to a string" do
1728
- expect(api.ruby_code?(%w{foo bar})).to be_truthy
1729
- end
1730
- it "returns true for a snippet of ruby code" do
1731
- expect(api.ruby_code?("assert api.ruby_code?(nil)")).to be_truthy
1732
- end
1733
- it "returns false for a unix command" do
1734
- expect(api.ruby_code?("find -type f -print")).to be_falsey
1735
- end
1736
- end
1737
-
1738
- describe "#searches" do
1739
- let(:ast) { double() }
1740
- it "returns empty if the AST does not support XPath expressions" do
1741
- expect(api.searches("not-an-ast")).to be_empty
1742
- end
1743
- it "returns empty if the AST has no elements" do
1744
- expect(ast).to receive(:xpath).with(kind_of(String)).and_return([])
1745
- expect(api.searches(ast)).to be_empty
1746
- end
1747
- it "returns the AST elements for each use of search" do
1748
- expect(ast).to receive(:xpath).with(kind_of(String)).and_return(["ident"])
1749
- expect(api.searches(ast)).to eq ["ident"]
1750
- end
1751
- end
1752
-
1753
- describe "#standard_cookbook_subdirs" do
1754
- it "is enumerable" do
1755
- api.standard_cookbook_subdirs.each { |s| s }
1756
- end
1757
- it "is sorted in alphabetical order" do
1758
- expect(api.standard_cookbook_subdirs).to eq api.standard_cookbook_subdirs.sort
1759
- end
1760
- it "includes the directories generated by knife create cookbook" do
1761
- %w{attributes definitions files libraries providers recipes resources
1762
- templates}.each do |dir|
1763
- expect(api.standard_cookbook_subdirs).to include dir
1764
- end
1765
- end
1766
- it "does not include the spec directory" do
1767
- expect(api.standard_cookbook_subdirs).to_not include "spec"
1768
- end
1769
- it "does not include a subdirectory of a subdirectory" do
1770
- expect(api.standard_cookbook_subdirs).to_not include "default"
1771
- end
1772
- end
1773
-
1774
- describe "#supported_platforms" do
1775
- subject { api.supported_platforms(ast) }
1776
-
1777
- context "with no platforms" do
1778
- ast 'name "supports"'
1779
- it { is_expected.to eq [] }
1780
- end
1781
- context "with supports but no argument" do
1782
- ast "supports"
1783
- it { is_expected.to eq [] }
1784
- end
1785
- context "with supports using a string expression" do
1786
- ast 'supports "red#{hat}"'
1787
- it { is_expected.to eq [] }
1788
- end
1789
- context "with supports using a complex string expression" do
1790
- ast 'supports "red#{hat(foo "bar")}"'
1791
- it { is_expected.to eq [] }
1792
- end
1793
- context "with a single platform" do
1794
- ast 'supports "redhat"'
1795
- it { is_expected.to eq [{ platform: "redhat", versions: [] }] }
1796
- end
1797
- context "with multiple platforms" do
1798
- ast "supports 'oracle'\nsupports 'redhat'\nsupports 'scientific'"
1799
- it do
1800
- is_expected.to eq [{ platform: "oracle", versions: [] },
1801
- { platform: "redhat", versions: [] },
1802
- { platform: "scientific", versions: [] }] end
1803
- end
1804
- context "with multiple platforms not in alphabetical order" do
1805
- ast "supports 'redhat'\nsupports 'scientific'\nsupports 'oracle'"
1806
- it do
1807
- is_expected.to eq [{ platform: "oracle", versions: [] },
1808
- { platform: "redhat", versions: [] },
1809
- { platform: "scientific", versions: [] }] end
1810
- end
1811
- context "with a version constraint" do
1812
- ast 'supports "redhat", ">= 6"'
1813
- it { is_expected.to eq [{ platform: "redhat", versions: [">= 6"] }] }
1814
- end
1815
- context "with complex version constraints" do
1816
- ast %q{
1817
- supports 'redhat', '> 5.0', '< 7.0'
1818
- supports 'scientific', '> 5.0', '< 6.0'
1819
- }
1820
- it do
1821
- is_expected.to eq [{ platform: "redhat", versions: ["> 5.0", "< 7.0"] },
1822
- { platform: "scientific", versions: ["> 5.0", "< 6.0"] }] end
1823
- end
1824
- context "with a symbol platform" do
1825
- ast "supports :ubuntu"
1826
- it { is_expected.to eq [{ platform: "ubuntu", versions: [] }] }
1827
- end
1828
- context "with a symbol platform with a version constraint" do
1829
- ast 'supports :ubuntu, ">= 6"'
1830
- it { is_expected.to eq [{ platform: "ubuntu", versions: [">= 6"] }] }
1831
- end
1832
- context "with a word list" do
1833
- ast "%w{redhat centos fedora}.each {|os| supports os }"
1834
- it do
1835
- is_expected.to eq [{ platform: "centos", versions: [] },
1836
- { platform: "fedora", versions: [] },
1837
- { platform: "redhat", versions: [] }] end
1838
- end
1839
- context "with a multi-line word list" do
1840
- ast %q{
1841
- %w(
1842
- redhat
1843
- centos
1844
- fedora
1845
- ).each do |os|
1846
- supports os
1847
- end
1848
- }
1849
- it do
1850
- is_expected.to eq [{ platform: "centos", versions: [] },
1851
- { platform: "fedora", versions: [] },
1852
- { platform: "redhat", versions: [] }] end
1853
- end
1854
- context "with both a word list and a non-word list" do
1855
- ast "supports 'redhat'\n%w{centos fedora}.each {|os| supports os }"
1856
- it do
1857
- is_expected.to eq [{ platform: "centos", versions: [] },
1858
- { platform: "fedora", versions: [] },
1859
- { platform: "redhat", versions: [] }] end
1860
- end
1861
- end
1862
-
1863
- describe "#templates_included" do
1864
-
1865
- def all_templates
1866
- [
1867
- "templates/default/main.erb",
1868
- "templates/default/included_1.erb",
1869
- "templates/default/included_2.erb",
1870
- ]
1871
- end
1872
-
1873
- def template_ast(content)
1874
- parse_ast(FoodCritic::Template::ExpressionExtractor.new.extract(
1875
- content).map { |e| e[:code] }.join(";"))
1876
- end
1877
-
1878
- it "returns the path of the containing template when there are no partials" do
1879
- ast = parse_ast("<%= foo.erb %>")
1880
- expect(api).to receive(:read_ast).with("foo.erb").and_return(ast)
1881
- expect(api.templates_included(["foo.erb"], "foo.erb")).to eq ["foo.erb"]
1882
- end
1883
-
1884
- it "returns the path of the containing template and any partials" do
1885
- main_ast = template_ast('<%= render "included_1.erb" %>
1886
- <%= render "included_2.erb" %>')
1887
- inner_ast = template_ast("<%= @foo %>")
1888
- expect(api).to receive(:read_ast).with(/main/).and_return(main_ast)
1889
- expect(api).to receive(:read_ast).and_return(inner_ast).twice
1890
- expect(api.templates_included(all_templates, "templates/default/main.erb")).to eq [
1891
- "templates/default/main.erb",
1892
- "templates/default/included_1.erb",
1893
- "templates/default/included_2.erb",
1894
- ]
1895
- end
1896
-
1897
- it "doesn't mistake render options for partial template names" do
1898
- main_ast = template_ast('<%= render "included_1.erb",
1899
- :variables => {:foo => "included_2.erb"} %>')
1900
- inner_ast = template_ast("<%= @foo %>")
1901
- expect(api).to receive(:read_ast).with(/main/).and_return(main_ast)
1902
- expect(api).to receive(:read_ast).and_return(inner_ast)
1903
- expect(api.templates_included(all_templates, "templates/default/main.erb")).to eq [
1904
- "templates/default/main.erb",
1905
- "templates/default/included_1.erb",
1906
- ]
1907
- end
1908
-
1909
- it "raises if included partials have cycles" do
1910
- main_ast = template_ast('<%= render "included_1.erb" %>
1911
- <%= render "included_2.erb" %>')
1912
- loop_ast = template_ast('<%= render "main.erb" %>')
1913
- inner_ast = template_ast("<%= foo %>")
1914
- expect(api).to receive(:read_ast).with(/main/).and_return(main_ast).at_least(:once)
1915
- expect(api).to receive(:read_ast).with(/included_2/).and_return(loop_ast).at_least(:once)
1916
- expect(api).to receive(:read_ast).and_return(inner_ast).at_least(:once)
1917
- expect { api.templates_included(all_templates, "templates/default/main.erb") }.to raise_error(FoodCritic::Api::RecursedTooFarError, "templates/default/main.erb")
1918
- end
1919
- end
1920
-
1921
- describe "#json_file_to_hash" do
1922
-
1923
- it "raises if the filename is not provided" do
1924
- expect { api.json_file_to_hash }.to raise_error ArgumentError
1925
- end
1926
-
1927
- it "raises if the filename is not found" do
1928
- expect(::File).to receive(:exist?).with("/some/path/with/a/file").and_return(false)
1929
- expect { api.json_file_to_hash("/some/path/with/a/file") }.to raise_error RuntimeError
1930
- end
1931
-
1932
- it "raises if the json is not valid" do
1933
- expect(::File).to receive(:exist?).with("/some/path/with/a/file").and_return(true)
1934
- allow(File).to receive(:read).with("/some/path/with/a/file").and_return("I am bogus data")
1935
- expect { api.json_file_to_hash("/some/path/with/a/file") }.to raise_error RuntimeError
1936
- end
1937
- end
1938
-
1939
- end