poise 2.2.2 → 2.2.3

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: ce32a02691e577d78fdb616e77459374be22c38e
4
- data.tar.gz: ec4202a5df8a244c184703d2988230d354880ce4
3
+ metadata.gz: 5906280e0c3c8e0555e6a255dad854a6a68f2d11
4
+ data.tar.gz: 611ffdede3b4f1021e18d88299172aea3239890d
5
5
  SHA512:
6
- metadata.gz: 10fe7f8a415002492e2b6f93b91712eedb809ba839b86a51d882b7c486f82e046a9ab5a3a0d3351f8b5033149dabf5ef37235f1c0991889cba00f61a559d3f07
7
- data.tar.gz: 63401d09fd30969b8fe2415a45ac5061972191bdcf2366ea943b71604345567f5e53df3106e75dad2b455e61833eff6a28f343d436bdcdd12bd18b4b924e4ed6
6
+ metadata.gz: 075e7d9b3aecce2cc748430ca9bca6e3a33b3db88aa63701fb42269b1254b4f2e7915843bbafb85c239729d1b2c23b6bc775db7bc297435b9555f7a77f31b2d3
7
+ data.tar.gz: f1aa2c2a67df267725169799a924df19f2f16f3927b2ec492b891886eff5aff00be251a5bbbe23d4421e146a902fe687ae936c17257a6ee469d7fecb2343b714
@@ -1,5 +1,10 @@
1
1
  # Changelog
2
2
 
3
+ ## v2.2.3
4
+
5
+ * Add `ancestor_send` utility method for use in other helpers.
6
+ * Improve subresource support for use in mixins.
7
+
3
8
  ## v2.2.2
4
9
 
5
10
  * Fix 2.2.1 for older versions of Chef.
@@ -57,6 +57,10 @@ module Poise
57
57
  # @param val [String, Hash, Chef::Resource] Parent resource to set.
58
58
  # @return [Chef::Resource, nil]
59
59
  def parent(*args)
60
+ # Lie about this method if the parent type is true.
61
+ if self.class.parent_type == true
62
+ raise NoMethodError.new("undefined method `parent' for #{self}")
63
+ end
60
64
  _parent(:parent, self.class.parent_type, self.class.parent_optional, self.class.parent_auto, *args)
61
65
  end
62
66
 
@@ -91,7 +95,7 @@ module Poise
91
95
  parent = nil
92
96
  else
93
97
  if val.is_a?(String) && !val.include?('[')
94
- raise Poise::Error.new('Cannot use a string parent without defining a parent type') if parent_type == Chef::Resource
98
+ raise Poise::Error.new("Cannot use a string #{name} without defining a parent type") if parent_type == Chef::Resource
95
99
  val = "#{parent_type.resource_name}[#{val}]"
96
100
  end
97
101
  if val.is_a?(String) || val.is_a?(Hash)
@@ -112,7 +116,7 @@ module Poise
112
116
  parent = Poise::Helpers::Subresources::DefaultContainers.find(parent_type, run_context)
113
117
  end
114
118
  # Can't find a valid parent, if it wasn't optional raise an error.
115
- raise Poise::Error.new("No parent found for #{self}") unless parent || parent_optional
119
+ raise Poise::Error.new("No #{name} found for #{self}") unless parent || parent_optional
116
120
  parent_ref = ParentRef.new(parent)
117
121
  else
118
122
  parent = parent_ref.resource
@@ -134,9 +138,10 @@ module Poise
134
138
  def parent_type(type=nil)
135
139
  if type
136
140
  raise Poise::Error.new("Parent type must be a class, symbol, or true, got #{type.inspect}") unless type.is_a?(Class) || type.is_a?(Symbol) || type == true
137
- @parent_type = type
141
+ # Setting to true shouldn't actually do anything if a type was already set.
142
+ @parent_type = type unless type == true && !@parent_type.nil?
138
143
  end
139
- @parent_type || (superclass.respond_to?(:parent_type) ? superclass.parent_type : Chef::Resource)
144
+ @parent_type || Poise::Utils.ancestor_send(self, :parent_type, default: Chef::Resource)
140
145
  end
141
146
 
142
147
  # @overload parent_optional()
@@ -151,7 +156,7 @@ module Poise
151
156
  @parent_optional = val
152
157
  end
153
158
  if @parent_optional.nil?
154
- superclass.respond_to?(:parent_optional) ? superclass.parent_optional : false
159
+ Poise::Utils.ancestor_send(self, :parent_optional, default: false)
155
160
  else
156
161
  @parent_optional
157
162
  end
@@ -169,7 +174,7 @@ module Poise
169
174
  @parent_auto = val
170
175
  end
171
176
  if @parent_auto.nil?
172
- superclass.respond_to?(:parent_auto) ? superclass.parent_auto : true
177
+ Poise::Utils.ancestor_send(self, :parent_auto, default: true)
173
178
  else
174
179
  @parent_auto
175
180
  end
@@ -66,5 +66,34 @@ module Poise
66
66
  # Sort the items by matching path length, pick the name attached to the longest.
67
67
  possibles.sort_by{|key, value| key.length }.last[1]
68
68
  end
69
+
70
+ # Try to find an ancestor to call a method on.
71
+ #
72
+ # @since 2.2.3
73
+ # @param obj [Object] Self from the caller.
74
+ # @param msg [Symbol] Method to try to call.
75
+ # @param args [Array<Object>] Method arguments.
76
+ # @param default [Object] Default return value if no valid ancestor exists.
77
+ # @return [Object]
78
+ # @example
79
+ # val = @val || Poise::Utils.ancestor_send(self, :val)
80
+ def ancestor_send(obj, msg, *args, default: nil)
81
+ # Class is a subclass of Module, if we get something else use its class.
82
+ obj = obj.class unless obj.is_a?(Module)
83
+ ancestors = []
84
+ if obj.respond_to?(:superclass)
85
+ # Check the superclass first if present.
86
+ ancestors << obj.superclass
87
+ end
88
+ # Make sure we don't check obj itself.
89
+ ancestors.concat(obj.ancestors.drop(1))
90
+ ancestor = ancestors.find {|mod| mod.respond_to?(msg) }
91
+ if ancestor
92
+ ancestor.send(msg, *args)
93
+ else
94
+ default
95
+ end
96
+ end
97
+
69
98
  end
70
99
  end
@@ -16,5 +16,5 @@
16
16
 
17
17
 
18
18
  module Poise
19
- VERSION = '2.2.2'
19
+ VERSION = '2.2.3'
20
20
  end
@@ -146,12 +146,16 @@ describe Poise::Helpers::NotifyingBlock do
146
146
  recipe(subject: false) do
147
147
  node.run_state[:things] = []
148
148
  poise_test 'test'
149
+ ruby_block 'copy' do
150
+ block do
151
+ node.run_state[:things_copy] = node.run_state[:things].dup
152
+ end
153
+ end
149
154
  end
150
- subject { chef_run.node.run_state[:things] }
155
+ subject { chef_run.node.run_state }
156
+
157
+ its([:things]) { is_expected.to eq %w{two one} }
158
+ its([:things_copy]) { is_expected.to eq %w{two} }
151
159
 
152
- # The important test.
153
- it { is_expected.to include 'one' }
154
- # Sanity check for my harness.
155
- it { is_expected.to include 'two' }
156
160
  end # /describe delayed notifications
157
161
  end
@@ -200,6 +200,20 @@ describe Poise::Helpers::Subresources::Child do
200
200
 
201
201
  it { is_expected.to run_poise_test('test').with(parent: nil) }
202
202
  end # context with an optional parent but then unset
203
+
204
+ context 'with a parent type of true' do
205
+ resource(:poise_test) do
206
+ include described_class
207
+ parent_type true
208
+ end
209
+ recipe do
210
+ poise_test 'test' do
211
+ parent 'test'
212
+ end
213
+ end
214
+
215
+ it { expect { subject }.to raise_error NoMethodError }
216
+ end # /context with a parent type of true
203
217
  end # /describe #parent
204
218
 
205
219
  describe '.parent_type' do
@@ -250,6 +264,30 @@ describe Poise::Helpers::Subresources::Child do
250
264
  expect { resource(:poise_test).parent_type('invalid') }.to raise_error Poise::Error
251
265
  end
252
266
  end # /context set to an invalid value
267
+
268
+ context 'set directly and then set to true' do
269
+ resource(:poise_test) do
270
+ include described_class
271
+ parent_type String
272
+ parent_type true
273
+ end
274
+
275
+ it { is_expected.to eq String }
276
+ end # /context set directly and then set to true
277
+
278
+ context 'set via a mixin' do
279
+ # Various scoping shenanigans.
280
+ described = described_class
281
+ test_mod = Module.new do
282
+ include described
283
+ parent_type :something
284
+ end
285
+ resource(:poise_test) do
286
+ include test_mod
287
+ end
288
+
289
+ it { is_expected.to eq :something }
290
+ end
253
291
  end # /describe .parent_type
254
292
 
255
293
  describe '.parent_optional' do
@@ -131,4 +131,68 @@ describe Poise::Utils do
131
131
  it { is_expected.to eq 'halite_cookbook_other' }
132
132
  end # /context with a Halite cookbook on a nested prefix
133
133
  end # /describe .find_cookbook_name
134
+
135
+ describe '.ancestor_send' do
136
+ let(:mod_parent) do
137
+ Module.new do
138
+ class_methods = Module.new do
139
+ def poise_test_val(val=nil)
140
+ if val
141
+ @poise_test_val = val
142
+ end
143
+ @poise_test_val || Poise::Utils.ancestor_send(self, :poise_test_val)
144
+ end
145
+
146
+ define_method(:included) do |klass|
147
+ super(klass)
148
+ klass.extend(class_methods)
149
+ end
150
+ end
151
+
152
+ extend class_methods
153
+ end
154
+ end
155
+
156
+ context 'using the parent module in class' do
157
+ subject do
158
+ mod = mod_parent
159
+ Class.new do
160
+ include mod
161
+ poise_test_val(:test)
162
+ end
163
+ end
164
+
165
+ its(:poise_test_val) { is_expected.to eq :test }
166
+ end # /context using the parent module in class
167
+
168
+ context 'using the parent module in an intermediary module' do
169
+ let(:mod_child) do
170
+ parent = mod_parent
171
+ Module.new do
172
+ include parent
173
+ poise_test_val(:child)
174
+ end
175
+ end
176
+
177
+ subject do
178
+ mod = mod_child
179
+ Class.new do
180
+ include mod
181
+ end
182
+ end
183
+
184
+ its(:poise_test_val) { is_expected.to eq :child }
185
+ end # /context using the parent module in an intermediary module
186
+
187
+ context 'with no value set' do
188
+ subject do
189
+ mod = mod_parent
190
+ Class.new do
191
+ include mod
192
+ end
193
+ end
194
+
195
+ its(:poise_test_val) { is_expected.to be_nil }
196
+ end # /context with no value set
197
+ end # /describe .ancestor_send
134
198
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: poise
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.2.2
4
+ version: 2.2.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Noah Kantrowitz
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-07-18 00:00:00.000000000 Z
11
+ date: 2015-07-21 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: halite