chefspec 3.0.0.beta.1 → 3.0.0.beta.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 804fd5cc6af81945c28e0e0e65d94e935ff0bb82
4
- data.tar.gz: d9d195301868641521b6159d67106e3ac7a6abd2
3
+ metadata.gz: 500cc20cbae81f4fe09ee9a0ad02d0910b30f901
4
+ data.tar.gz: 1fd9ab8312366fd9b755b6ce0b1ac7fa88d5befd
5
5
  SHA512:
6
- metadata.gz: 5f951adb7cdac28459d0e0df5172e6a2e1124776a4335dcc62a6ff06c80264ca7b39290de15df21cea551b51528252e304249c2fcf45ad3888ec3fe67b2970f5
7
- data.tar.gz: 7165b07393a29850245dd0fdff9d21f9222816acb723e9e381b5c195ff180f6e87be26e8013b9e5d99b73458fdde7861c510da479f7cd089f7cda21a327abf3a
6
+ metadata.gz: 9955d1c754d878ea7db155b89d79bd44e6868d0f1f8bf91fa2561ddf2bae1df303194dedb506a12d8c5dae87dbdebeaa6ddc9ae09d23c7422805093e3dc08de0
7
+ data.tar.gz: 6d9a11b65adec8e5910c7460a1aac740438bb005cc64070344ba2a939031f41e51c9b5196d7b1b169d92df63ff1608d947d2e7366c9d4e65d30e760f2af12cf6
@@ -11,27 +11,43 @@ module ChefSpec
11
11
  class Berkshelf
12
12
  class << self
13
13
  extend Forwardable
14
- def_delegators :instance, :setup!
14
+ def_delegators :instance, :setup!, :teardown!
15
15
  end
16
16
 
17
17
  include Singleton
18
18
 
19
19
  def initialize
20
- setup!
20
+ @tmpdir = Dir.mktmpdir
21
21
  end
22
22
 
23
+ #
24
+ # Setup and install the necessary dependencies in the temporary directory.
25
+ #
23
26
  def setup!
24
- tmpdir = Dir.mktmpdir
27
+ FileUtils.rm_rf(@tmpdir) # Berkshelf 3.0 requires the directory to be empty
28
+ FileUtils.mkdir_p(@tmpdir)
25
29
 
26
30
  ::Berkshelf.ui.mute do
27
- ::Berkshelf::Berksfile.from_file('Berksfile').install(path: tmpdir)
31
+ if ::Berkshelf::Berksfile.method_defined?(:vendor)
32
+ ::Berkshelf::Berksfile.from_file('Berksfile').vendor(@tmpdir)
33
+ else
34
+ ::Berkshelf::Berksfile.from_file('Berksfile').install(path: @tmpdir)
35
+ end
28
36
  end
29
37
 
30
- ::RSpec.configure do |config|
31
- config.cookbook_path = tmpdir
32
- end
38
+ ::RSpec.configure { |config| config.cookbook_path = @tmpdir }
39
+ end
40
+
41
+ #
42
+ # Destroy the installed Berkshelf at the temporary directory.
43
+ #
44
+ def teardown!
45
+ FileUtils.rm_rf(@tmpdir) if File.exists?(@tmpdir)
33
46
  end
34
47
  end
35
48
  end
36
49
 
37
- ChefSpec::Berkshelf.setup!
50
+ RSpec.configure do |config|
51
+ config.before(:suite) { ChefSpec::Berkshelf.setup! }
52
+ config.after(:suite) { ChefSpec::Berkshelf.teardown! }
53
+ end
@@ -17,6 +17,10 @@ class Chef::Resource
17
17
  old_run_action(action, notification_type, notifying_resource)
18
18
  end
19
19
 
20
+ if node.runner.compiling?
21
+ @compile_time = true
22
+ end
23
+
20
24
  Chef::Log.info("Processing #{self} action #{action} (#{defined_at})")
21
25
 
22
26
  # Append the currently run action to the existing resource actions,
@@ -24,4 +28,15 @@ class Chef::Resource
24
28
  @action = [self.action, action].flatten.compact.map(&:to_sym).uniq
25
29
  node.runner.resources[self.to_s] ||= self
26
30
  end
31
+
32
+ #
33
+ # Determine if the current resource is a compile-time resource (as opposed
34
+ # to a converge time resource). Compile-time resources are executed with the
35
+ # +run_action+ command at load time, rather than at comverge time.
36
+ #
37
+ # @return [Boolean]
38
+ #
39
+ def compile_time?
40
+ !!@compile_time
41
+ end
27
42
  end
@@ -55,6 +55,7 @@ module ChefSpec::Matchers
55
55
  message << ", but did not."
56
56
  message << "\n\n"
57
57
  message << "Other notifications were:\n#{format_notifications}"
58
+ message << "\n "
58
59
  message
59
60
  end
60
61
 
@@ -20,13 +20,27 @@ module ChefSpec::Matchers
20
20
 
21
21
  def failure_message_for_should
22
22
  message = "expected Chef run to render '#{@path}'"
23
- message << " with:\n\n#{@expected_content}\n\nbut got:\n\n#{@actual_content}" if @expected_content
23
+ if @expected_content
24
+ message << " with:"
25
+ message << "\n\n"
26
+ message << @expected_content
27
+ message << "\n\n"
28
+ message << "but got:"
29
+ message << "\n\n"
30
+ message << @actual_content
31
+ message << "\n "
32
+ end
24
33
  message
25
34
  end
26
35
 
27
36
  def failure_message_for_should_not
28
37
  message = "expected file '#{@path}'"
29
- message << " with:\n\n#{@expected_content}\n\n" if @expected_content
38
+ if @expected_content
39
+ message << " with:"
40
+ message << "\n\n"
41
+ message << @expected_content
42
+ message << "\n\n"
43
+ end
30
44
  message << " to not be in Chef run"
31
45
  end
32
46
 
@@ -11,6 +11,18 @@ module ChefSpec::Matchers
11
11
  self
12
12
  end
13
13
 
14
+ def at_compile_time
15
+ raise ArgumentError, 'Cannot specify both .at_converge_time and .at_compile_time!' if @converge_time
16
+ @compile_time = true
17
+ self
18
+ end
19
+
20
+ def at_converge_time
21
+ raise ArgumentError, 'Cannot specify both .at_compile_time and .at_converge_time!' if @compile_time
22
+ @converge_time = true
23
+ self
24
+ end
25
+
14
26
  #
15
27
  # Allow users to specify fancy #with matchers.
16
28
  #
@@ -27,7 +39,7 @@ module ChefSpec::Matchers
27
39
  @runner = runner
28
40
 
29
41
  if resource
30
- resource_actions.include?(@expected_action) && unmatched_parameters.empty?
42
+ resource_actions.include?(@expected_action) && unmatched_parameters.empty? && correct_phase?
31
43
  else
32
44
  false
33
45
  end
@@ -36,12 +48,19 @@ module ChefSpec::Matchers
36
48
  def failure_message_for_should
37
49
  if resource
38
50
  if resource_actions.include?(@expected_action)
39
- "expected '#{resource.to_s}' to have parameters:" \
40
- "\n\n" \
41
- " " + unmatched_parameters.collect { |parameter, h|
42
- "#{parameter} #{h[:expected].inspect}, was #{h[:actual].inspect}"
43
- }.join("\n ")
44
-
51
+ if unmatched_parameters.empty?
52
+ if @compile_time
53
+ "expected '#{resource.to_s}' to be run at compile time, but was converge time"
54
+ else
55
+ "expected '#{resource.to_s}' to be run at converge time, but was compile time"
56
+ end
57
+ else
58
+ "expected '#{resource.to_s}' to have parameters:" \
59
+ "\n\n" \
60
+ " " + unmatched_parameters.collect { |parameter, h|
61
+ "#{parameter} #{h[:expected].inspect}, was #{h[:actual].inspect}"
62
+ }.join("\n ")
63
+ end
45
64
  else
46
65
  "expected '#{resource.to_s}' actions #{resource_actions.inspect}" \
47
66
  " to include ':#{@expected_action}'"
@@ -51,16 +70,20 @@ module ChefSpec::Matchers
51
70
  " action ':#{@expected_action}' to be in Chef run. Other" \
52
71
  " #{@resource_name} resources:" \
53
72
  "\n\n" \
54
- " " + similar_resources.map(&:to_s).join("\n ")
73
+ " " + similar_resources.map(&:to_s).join("\n ") + "\n "
55
74
  end
56
75
  end
57
76
 
58
77
  def failure_message_for_should_not
59
78
  if resource
60
- "expected '#{resource.to_s}' actions #{resource_actions.inspect} to not exist"
79
+ message = "expected '#{resource.to_s}' actions #{resource_actions.inspect} to not exist"
61
80
  else
62
- "expected '#{resource.to_s}' to not exist"
81
+ message = "expected '#{resource.to_s}' to not exist"
63
82
  end
83
+
84
+ message << " at compile time" if @compile_time
85
+ message << " at converge time" if @converge_time
86
+ message
64
87
  end
65
88
 
66
89
  def description
@@ -94,6 +117,16 @@ module ChefSpec::Matchers
94
117
  end
95
118
  end
96
119
 
120
+ def correct_phase?
121
+ if @compile_time
122
+ resource.compile_time?
123
+ elsif @converge_time
124
+ !resource.compile_time?
125
+ else
126
+ true
127
+ end
128
+ end
129
+
97
130
  def safe_send(parameter)
98
131
  resource.send(parameter)
99
132
  rescue NoMethodError
@@ -107,7 +140,7 @@ module ChefSpec::Matchers
107
140
  # @return [Array<Chef::Resource>]
108
141
  #
109
142
  def similar_resources
110
- @_similar_resources ||= @runner.find_resources(@resource_name)
143
+ @_similar_resources ||= @runner.find_resources(@resource_name).values
111
144
  end
112
145
 
113
146
  #
@@ -100,6 +100,9 @@ module ChefSpec
100
100
  # A reference to the calling Runner (for chaining purposes)
101
101
  #
102
102
  def apply(*recipe_names)
103
+ # Start compiling
104
+ @compiling = true
105
+
103
106
  recipe_names.each do |recipe_name|
104
107
  cookbook, recipe = Chef::Recipe.parse_recipe_name(recipe_name)
105
108
  recipe_path = File.join(Dir.pwd, 'recipes', "#{recipe}.rb")
@@ -108,9 +111,18 @@ module ChefSpec
108
111
  recipe.from_file(recipe_path)
109
112
  end
110
113
 
114
+ # Reset the resource collection
111
115
  @resources = {}
116
+
117
+ # Expand the run_list
118
+ expand_run_list!
119
+
120
+ # Setup the run_context
112
121
  @run_context = Chef::RunContext.new(client.node, {}, client.events)
113
122
 
123
+ # We are done compiling now
124
+ @compiling = false
125
+
114
126
  Chef::Runner.new(@run_context).converge
115
127
  self
116
128
  end
@@ -133,6 +145,9 @@ module ChefSpec
133
145
  # A reference to the calling Runner (for chaining purposes)
134
146
  #
135
147
  def converge(*recipe_names)
148
+ # Start compiling
149
+ @compiling = true
150
+
136
151
  node.run_list.reset!
137
152
  recipe_names.each { |recipe_name| node.run_list.add(recipe_name) }
138
153
 
@@ -141,9 +156,15 @@ module ChefSpec
141
156
  # Reset the resource collection
142
157
  @resources = {}
143
158
 
144
- client.build_node
159
+ # Expand the run_list
160
+ expand_run_list!
161
+
162
+ # Setup the run_context
145
163
  @run_context = client.setup_run_context
146
164
 
165
+ # We are done compiling now
166
+ @compiling = false
167
+
147
168
  Chef::Runner.new(@run_context).converge
148
169
  self
149
170
  end
@@ -156,7 +177,7 @@ module ChefSpec
156
177
  def node
157
178
  return @node if @node
158
179
 
159
- @node = client.node
180
+ @node = client.build_node
160
181
  @node.instance_variable_set(:@runner, self)
161
182
  @node.class.send(:attr_reader, :runner)
162
183
  @node
@@ -232,10 +253,22 @@ module ChefSpec
232
253
  !!options[:dry_run]
233
254
  end
234
255
 
256
+ #
257
+ # Boolean method to determine if the Runner is still compiling recipes.
258
+ # This is used by the +Resource+ class to determine if a resource was
259
+ # invoked at compile-time or converge-time.
260
+ #
261
+ # @return [Boolean]
262
+ #
263
+ def compiling?
264
+ !!@compiling
265
+ end
266
+
235
267
  #
236
268
  # This runner as a string.
237
269
  #
238
- # @return [String] Currently includes the run_list. Format of the string may change between versions of this gem.
270
+ # @return [String] Currently includes the run_list. Format of the string
271
+ # may change between versions of this gem.
239
272
  #
240
273
  def to_s
241
274
  return "chef_run: #{node.run_list.to_s}" unless node.run_list.empty?
@@ -252,6 +285,14 @@ module ChefSpec
252
285
  end
253
286
 
254
287
  private
288
+ #
289
+ # The inferred path from the calling spec.
290
+ #
291
+ # @param [Array<String>] kaller
292
+ # the calling trace
293
+ #
294
+ # @return [String]
295
+ #
255
296
  def calling_cookbook_path(kaller)
256
297
  calling_spec = kaller.find { |line| line =~ /\/spec/ }
257
298
  bits = calling_spec.split(':', 2).first.split(File::SEPARATOR)
@@ -260,6 +301,10 @@ module ChefSpec
260
301
  File.expand_path(File.join(bits.slice(0, spec_dir), '..'))
261
302
  end
262
303
 
304
+ #
305
+ # The +Chef::Client+ for this runner.
306
+ #
307
+ # @return [Chef::Runner]
263
308
  #
264
309
  def client
265
310
  return @client if @client
@@ -270,5 +315,19 @@ module ChefSpec
270
315
  @client.build_node
271
316
  @client
272
317
  end
318
+
319
+ #
320
+ # We really need a way to just expand the run_list, but that's done by
321
+ # +Chef::Client#build_node+. However, that same method also resets the
322
+ # automatic attributes, making it impossible to mock them. So we are
323
+ # stuck +instance_eval+ing against the client and manually expanding
324
+ # the mode object.
325
+ #
326
+ def expand_run_list!
327
+ client.instance_eval do
328
+ @run_list_expansion = @node.expand!('disk')
329
+ @expanded_run_list_with_versions = @run_list_expansion.recipes.with_version_constraints_strings
330
+ end
331
+ end
273
332
  end
274
333
  end
@@ -1,3 +1,3 @@
1
1
  module ChefSpec
2
- VERSION = '3.0.0.beta.1'
2
+ VERSION = '3.0.0.beta.2'
3
3
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: chefspec
3
3
  version: !ruby/object:Gem::Version
4
- version: 3.0.0.beta.1
4
+ version: 3.0.0.beta.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Andrew Crump
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2013-10-10 00:00:00.000000000 Z
12
+ date: 2013-10-15 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: chef
@@ -219,6 +219,6 @@ rubyforge_project:
219
219
  rubygems_version: 2.0.3
220
220
  signing_key:
221
221
  specification_version: 4
222
- summary: chefspec-3.0.0.beta.1
222
+ summary: chefspec-3.0.0.beta.2
223
223
  test_files: []
224
224
  has_rdoc: