poise 2.2.2 → 2.2.3

Sign up to get free protection for your applications and to get access to all the features.
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