ninja-model 0.8.1 → 0.9.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (72) hide show
  1. data/.gitignore +1 -1
  2. data/Gemfile +1 -0
  3. data/Rakefile +6 -0
  4. data/lib/ninja_model.rb +23 -7
  5. data/lib/ninja_model/adapters.rb +25 -20
  6. data/lib/ninja_model/adapters/adapter_manager.rb +2 -0
  7. data/lib/ninja_model/adapters/adapter_pool.rb +2 -0
  8. data/lib/ninja_model/associations.rb +63 -101
  9. data/lib/ninja_model/associations/association.rb +146 -0
  10. data/lib/ninja_model/associations/association_scope.rb +39 -0
  11. data/lib/ninja_model/associations/belongs_to_association.rb +33 -21
  12. data/lib/ninja_model/associations/builder/association.rb +57 -0
  13. data/lib/ninja_model/associations/builder/belongs_to.rb +33 -0
  14. data/lib/ninja_model/associations/builder/collection_association.rb +60 -0
  15. data/lib/ninja_model/associations/builder/has_many.rb +11 -0
  16. data/lib/ninja_model/associations/builder/has_one.rb +20 -0
  17. data/lib/ninja_model/associations/builder/singular_association.rb +49 -0
  18. data/lib/ninja_model/associations/collection_association.rb +103 -0
  19. data/lib/ninja_model/associations/collection_proxy.rb +45 -0
  20. data/lib/ninja_model/associations/has_many_association.rb +19 -43
  21. data/lib/ninja_model/associations/has_one_association.rb +52 -6
  22. data/lib/ninja_model/associations/singular_association.rb +61 -0
  23. data/lib/ninja_model/attribute.rb +5 -2
  24. data/lib/ninja_model/attribute_methods.rb +35 -40
  25. data/lib/ninja_model/base.rb +31 -39
  26. data/lib/ninja_model/identity.rb +8 -6
  27. data/lib/ninja_model/rails_ext/active_record.rb +69 -225
  28. data/lib/ninja_model/railtie.rb +0 -9
  29. data/lib/ninja_model/reflection.rb +103 -20
  30. data/lib/ninja_model/relation.rb +2 -2
  31. data/lib/ninja_model/relation/query_methods.rb +16 -0
  32. data/lib/ninja_model/version.rb +1 -1
  33. data/ninja-model.gemspec +2 -1
  34. data/spec/db/schema.rb +15 -0
  35. data/spec/{ninja_model → lib/ninja_model}/adapters/abstract_adapter_spec.rb +0 -0
  36. data/spec/lib/ninja_model/adapters/adapter_manager_spec.rb +72 -0
  37. data/spec/lib/ninja_model/adapters/adapter_pool_spec.rb +230 -0
  38. data/spec/lib/ninja_model/adapters_spec.rb +120 -0
  39. data/spec/lib/ninja_model/associations/belongs_to_association_spec.rb +76 -0
  40. data/spec/lib/ninja_model/associations/has_many_association_spec.rb +118 -0
  41. data/spec/lib/ninja_model/associations/has_one_association_spec.rb +80 -0
  42. data/spec/{ninja_model → lib/ninja_model}/attribute_methods_spec.rb +2 -2
  43. data/spec/{ninja_model → lib/ninja_model}/attribute_spec.rb +4 -0
  44. data/spec/{ninja_model → lib/ninja_model}/base_spec.rb +0 -0
  45. data/spec/{ninja_model → lib/ninja_model}/identity_spec.rb +0 -0
  46. data/spec/{ninja_model → lib/ninja_model}/persistence_spec.rb +0 -0
  47. data/spec/{ninja_model → lib/ninja_model}/predicate_spec.rb +0 -0
  48. data/spec/{ninja_model → lib/ninja_model}/query_methods_spec.rb +0 -0
  49. data/spec/{ninja_model → lib/ninja_model}/reflection_spec.rb +7 -9
  50. data/spec/{ninja_model → lib/ninja_model}/relation_spec.rb +0 -0
  51. data/spec/{ninja_model → lib/ninja_model}/symbol_spec.rb +0 -0
  52. data/spec/{ninja_model → lib/ninja_model}/validation_spec.rb +0 -0
  53. data/spec/{ninja_model_spec.rb → lib/ninja_model_spec.rb} +0 -0
  54. data/spec/models/bio.rb +8 -0
  55. data/spec/models/body.rb +7 -0
  56. data/spec/models/category.rb +7 -0
  57. data/spec/models/email_address.rb +3 -0
  58. data/spec/models/post.rb +13 -0
  59. data/spec/models/tag.rb +3 -0
  60. data/spec/models/user.rb +4 -0
  61. data/spec/spec_helper.rb +38 -5
  62. data/spec/support/dummy_adapter/adapter.rb +48 -0
  63. data/spec/support/factories/bio.rb +11 -0
  64. data/spec/support/factories/body.rb +12 -0
  65. data/spec/support/factories/email_address.rb +5 -0
  66. data/spec/support/factories/post.rb +12 -0
  67. data/spec/support/factories/tag.rb +5 -0
  68. data/spec/support/factories/user.rb +5 -0
  69. metadata +121 -63
  70. data/spec/ninja_model/adapters/adapter_manager_spec.rb +0 -69
  71. data/spec/ninja_model/adapters/adapter_pool_spec.rb +0 -230
  72. data/spec/ninja_model/adapters_spec.rb +0 -85
@@ -10,13 +10,13 @@ module NinjaModel
10
10
 
11
11
  attr_reader :klass, :loaded
12
12
 
13
- attr_accessor :ordering, :predicates, :limit_value, :offset_value
13
+ attr_accessor :ordering, :predicates, :limit_value, :offset_value, :readonly_value
14
14
  attr_accessor :default_scoped
15
15
  alias :default_scoped? :default_scoped
16
16
 
17
17
  alias :loaded? :loaded
18
18
 
19
- SINGLE_VALUE_ATTRS = [:limit, :offset]
19
+ SINGLE_VALUE_ATTRS = [:limit, :offset, :readonly]
20
20
  MULTI_VALUE_ATTRS = [:ordering, :predicates]
21
21
 
22
22
  def initialize(klass)
@@ -22,6 +22,22 @@ module NinjaModel
22
22
  relation
23
23
  end
24
24
 
25
+ def readonly(value)
26
+ relation = clone
27
+ relation.readonly_value = value
28
+ relation
29
+ end
30
+
31
+ def extending(*modules)
32
+ modules << Module.new(&Proc.new) if block_given?
33
+
34
+ return self if modules.empty?
35
+
36
+ relation = clone
37
+ relation.send(:apply_modules, modules.flatten)
38
+ relation
39
+ end
40
+
25
41
  private
26
42
 
27
43
  def build_predicates(opts, other = [])
@@ -1,3 +1,3 @@
1
1
  module NinjaModel
2
- VERSION = "0.8.1"
2
+ VERSION = "0.9.0"
3
3
  end
data/ninja-model.gemspec CHANGED
@@ -23,9 +23,10 @@ Gem::Specification.new do |s|
23
23
 
24
24
  s.add_development_dependency 'rspec', '~> 2.8.0'
25
25
  s.add_development_dependency 'mocha', '~> 0.10.0'
26
- s.add_development_dependency 'nokogiri', '~> 1.5.0'
27
26
  s.add_development_dependency 'guard-rspec', '~> 0.5.10'
28
27
  s.add_development_dependency 'libnotify', '~> 0.6.0'
29
28
  s.add_development_dependency 'yard', '~> 0.7.4'
30
29
  s.add_development_dependency 'redcarpet', '~> 2.0.0'
30
+ s.add_development_dependency 'sqlite3', '~> 1.3.5'
31
+ s.add_development_dependency 'factory_girl', '~> 2.5.0'
31
32
  end
data/spec/db/schema.rb ADDED
@@ -0,0 +1,15 @@
1
+ ActiveRecord::Schema.define do
2
+ create_table :users, :force => true do |t|
3
+ t.string :username
4
+ end
5
+
6
+ create_table :tags, :force => true do |t|
7
+ t.integer :post_id
8
+ t.string :name
9
+ end
10
+
11
+ create_table :email_addresses, :force => true do |t|
12
+ t.integer :bio_id
13
+ t.string :email
14
+ end
15
+ end
@@ -0,0 +1,72 @@
1
+ require 'spec_helper'
2
+
3
+ describe NinjaModel::Adapters::AdapterManager do
4
+ #class DummyAdapter < NinjaModel::Adapters::AbstractAdapter; end
5
+ #class TestModel < NinjaModel::Base; end
6
+ #class ChildModel < TestModel; end
7
+
8
+ let(:manager) { NinjaModel::Adapters::AdapterManager.new }
9
+ subject { manager }
10
+ #before {
11
+ # @manager = NinjaModel::Adapters::AdapterManager.new
12
+ # @manager.class.register_adapter_class(:dummy, DummyAdapter)
13
+ #}
14
+ #subject { @manager }
15
+
16
+ it 'should remember registered adapters' do
17
+ subject.class.stubs(:registered).returns({:dummy => nil})
18
+ subject.class.registered?(:dummy).should be_true
19
+ end
20
+
21
+ #describe 'creating an adapter' do
22
+ # before { @manager.create_adapter('TestModel', NinjaModel::Adapters::AdapterSpecification.new({}, :dummy)) }
23
+ # it 'should add the adapter to the pool' do
24
+ # @manager.retrieve_adapter_pool(TestModel).spec.name.should eql(:dummy)
25
+ # end
26
+ # it 'should return the adapter for descendent classes' do
27
+ # @manager.retrieve_adapter_pool(ChildModel).spec.name.should eql(:dummy)
28
+ # end
29
+ #end
30
+
31
+ #describe 'removing an adapter' do
32
+ # before {
33
+ # @spec = NinjaModel::Adapters::AdapterSpecification.new({:foo => 'bar'}, :dummy)
34
+ # @manager.create_adapter('TestModel', @spec)
35
+ # }
36
+ # it 'should remove the adapter from the pool' do
37
+ # @manager.remove_adapter(TestModel)
38
+ # @manager.retrieve_adapter_pool(TestModel).should be_nil
39
+ # end
40
+ # it 'should cause retrieve_adapter to raise an error' do
41
+ # @manager.remove_adapter(TestModel)
42
+ # lambda { @manager.retrieve_adapter(TestModel) }.should raise_error(StandardError)
43
+ # end
44
+ # it 'should return the spec that created it' do
45
+ # @manager.remove_adapter(TestModel).should eql({:foo => 'bar'})
46
+ # end
47
+ #end
48
+
49
+ #describe 'release_active_adapters!' do
50
+ # before {
51
+ # @spec = NinjaModel::Adapters::AdapterSpecification.new({:foo => 'bar'}, :dummy)
52
+ # @manager.create_adapter('TestModel', @spec)
53
+ # }
54
+ # it 'should call release_instance on all pools' do
55
+ # @pool = @manager.adapter_pools['TestModel']
56
+ # @pool.expects(:release_instance)
57
+ # @manager.release_active_adapters!
58
+ # end
59
+ #end
60
+
61
+ #describe 'release_all_adapters!' do
62
+ # before {
63
+ # @spec = NinjaModel::Adapters::AdapterSpecification.new({:foo => 'bar'}, :dummy)
64
+ # @manager.create_adapter('TestModel', @spec)
65
+ # }
66
+ # it 'should call shutdown! on all pools' do
67
+ # @pool = @manager.adapter_pools['TestModel']
68
+ # @pool.expects(:shutdown!)
69
+ # @manager.release_all_adapters!
70
+ # end
71
+ #end
72
+ end
@@ -0,0 +1,230 @@
1
+ require 'spec_helper'
2
+
3
+ describe NinjaModel::Adapters::AdapterPool do
4
+ #class DummyAdapter < NinjaModel::Adapters::AbstractAdapter; end
5
+ #before {
6
+ # @spec = NinjaModel::Adapters::AdapterSpecification.new({}, :dummy)
7
+ # NinjaModel::Base.register_adapter(:dummy, DummyAdapter)
8
+ # @pool = NinjaModel::Adapters::AdapterPool.new(@spec)
9
+ #}
10
+ #subject { @pool }
11
+ #its(:spec) { should eql(@spec) }
12
+ #its(:instances) { should be_empty }
13
+ #its(:connected?) { should be_false }
14
+ #its(:current_instance_id) { should eql(Thread.current.object_id) }
15
+
16
+ #describe 'obtaining an adapter instance' do
17
+ # it 'should store the instance for a given thread' do
18
+ # subject.instance
19
+ # subject.expects(:checkout).never
20
+ # subject.instance
21
+ # end
22
+ #end
23
+
24
+ #describe 'releasing an adapter instance' do
25
+ # it 'should call checkout when obtaining another instance' do
26
+ # subject.expects(:checkout).twice
27
+ # subject.instance
28
+ # subject.release_instance
29
+ # subject.instance
30
+ # end
31
+ #end
32
+
33
+ #describe 'with_instance' do
34
+ # it 'should yield an instance' do
35
+ # @inst = nil
36
+ # subject.with_instance do |inst|
37
+ # @inst = inst
38
+ # end
39
+ # @inst.should be_kind_of(DummyAdapter)
40
+ # end
41
+ # it 'should release the instance when complete' do
42
+ # subject.expects(:release_instance).with(subject.send :current_instance_id)
43
+ # subject.with_instance do |inst|
44
+ # end
45
+ # end
46
+ #end
47
+
48
+ #describe 'shutdown!' do
49
+ # it 'should checkin all assigned instances' do
50
+ # @inst = subject.instance
51
+ # subject.expects(:checkin).with(@inst)
52
+ # subject.shutdown!
53
+ # end
54
+ # it 'should call disconnect on all instances' do
55
+ # @inst = subject.instance
56
+ # @inst.expects(:disconnect!)
57
+ # subject.shutdown!
58
+ # end
59
+ #end
60
+
61
+ #describe 'clear_stale_cached_instances!' do
62
+ # let(:thread) { mock('Thread') }
63
+ # before { Thread.stubs(:list).returns([thread]) }
64
+ # it 'should reap any instances for dead threads' do
65
+ # thread.stubs(:alive?).returns(false)
66
+ # inst = subject.instance
67
+ # subject.instance_variable_set("@assigned_instances".to_sym, {thread.object_id => inst})
68
+ # subject.expects(:checkin).with(inst)
69
+ # subject.send :clear_stale_cached_instances!
70
+ # end
71
+ # it 'should not reap instances for live threads' do
72
+ # thread.stubs(:alive?).returns(true)
73
+ # inst = subject.instance
74
+ # subject.instance_variable_set("@assigned_instances".to_sym, {thread.object_id => inst})
75
+ # subject.expects(:checkin).with(inst).never
76
+ # subject.send :clear_stale_cached_instances!
77
+ # end
78
+ #end
79
+
80
+ #describe 'checkout' do
81
+ # subject { NinjaModel::Adapters::AdapterPool.new(@spec) }
82
+ # context 'with no current instances' do
83
+ # it 'should checkout a new instance' do
84
+ # subject.expects(:checkout_new_instance).returns('foo')
85
+ # subject.send(:checkout)
86
+ # end
87
+ # it 'should store the instance' do
88
+ # subject.send(:checkout)
89
+ # subject.instances.count.should eql(1)
90
+ # end
91
+ # end
92
+
93
+ # context 'with 1 existing instance' do
94
+ # context 'that is already assigned' do
95
+ # it 'should checkout a new instance' do
96
+ # threads = []
97
+ # subject.expects(:new_instance).twice.returns(NinjaModel::Adapters::AdapterManager.registered[subject.spec.name].new(subject.spec.config))
98
+ # 2.times do |idx|
99
+ # threads << Thread.new do
100
+ # subject.send(:checkout)
101
+ # end
102
+ # end
103
+ # threads.each { |t| t.join }
104
+ # end
105
+ # end
106
+ # context 'that is not assigned' do
107
+ # it 'should checkout the existing instance' do
108
+ # subject.expects(:checkout_existing_instance).returns('existing')
109
+ # subject.instance
110
+ # subject.release_instance
111
+ # subject.instances.count.should eql(1)
112
+ # subject.send(:checkout)
113
+ # end
114
+ # end
115
+ # end
116
+
117
+ # context 'with the maximum number of instances' do
118
+ # context 'with an available instance' do
119
+ # it 'should successfully check out an instance' do
120
+ # subject.instance
121
+ # threads = []
122
+ # 4.times do |idx|
123
+ # threads << Thread.new do
124
+ # subject.instance
125
+ # end
126
+ # end
127
+ # threads.each { |t| t.join }
128
+ # subject.release_instance
129
+ # subject.send(:checkout).should_not be_nil
130
+ # end
131
+ # end
132
+
133
+ # context 'with no available instances' do
134
+ # it 'should raise a ConnectionTimeoutError' do
135
+ # threads = []
136
+ # 5.times do |idx|
137
+ # threads << Thread.new do
138
+ # subject.instance
139
+ # end
140
+ # end
141
+ # threads.each { |t| t.join }
142
+ # subject.stubs(:clear_stale_cached_instances!)
143
+ # lambda { subject.instance }.should raise_error(NinjaModel::ConnectionTimeoutError)
144
+ # end
145
+ # end
146
+
147
+ # context 'with instances that can be reaped' do
148
+ # it 'should return an existing instance' do
149
+ # threads = []
150
+ # 5.times do |idx|
151
+ # threads << Thread.new do
152
+ # subject.instance
153
+ # end
154
+ # end
155
+ # threads.each { |t| t.join }
156
+ # subject.expects(:checkout_existing_instance).returns('foo')
157
+ # subject.instance
158
+ # end
159
+ # end
160
+ # end
161
+
162
+ #end
163
+ # before(:each) do
164
+ # @spec = mock('AdapterSpecification') do
165
+ # stubs(:adapter_method).returns(:dummy_adapter)
166
+ # stubs(:config)
167
+ # end
168
+ #
169
+ # @adapter = mock('AbstractAdapter') do
170
+ # stubs(:verify!)
171
+ # end
172
+ #
173
+ # @pool = NinjaModel::Adapters::AdapterPool.new(@spec)
174
+ # @thread = mock('thread') do
175
+ # stubs('object_id').returns(123)
176
+ # end
177
+ # Thread.stubs(:current).returns(@thread)
178
+ # NinjaModel::Base.stubs(:dummy_adapter).returns(@adapter)
179
+ # end
180
+ #
181
+ # it 'should properly respond to connected?' do
182
+ # @pool.connected?.should be_false
183
+ # @pool.instance
184
+ # @pool.connected?.should be_true
185
+ # end
186
+ #
187
+ # it 'should initialize from an AdapterSpecification' do
188
+ # spec = mock('AdapterSpecification')
189
+ # NinjaModel::Adapters::AdapterPool.new(spec).spec.should eql(spec)
190
+ # end
191
+ #
192
+ # it 'should return a valid instance_id' do
193
+ # (@pool.send :current_instance_id).should eql(@thread.object_id)
194
+ # end
195
+ #
196
+ # describe 'when creating an instance' do
197
+ # it 'should create a valid instance' do
198
+ # (@pool.send :new_instance).should eql(@adapter)
199
+ # end
200
+ #
201
+ # it 'should store the instance' do
202
+ # @pool.stubs(:new_instance).returns(@adapter)
203
+ # @pool.instance
204
+ # @pool.instances.should include(@adapter)
205
+ # end
206
+ #
207
+ # it 'should assign the instance to the current_thread' do
208
+ # @pool.stubs(:new_instance).returns(@adapter)
209
+ # @pool.instance
210
+ # @pool.stubs(:checkout).returns("new_instance")
211
+ # @pool.instance.should_not eql("new_instance")
212
+ # @pool.instance.should eql(@adapter)
213
+ # end
214
+ #
215
+ # it 'should reuse an unallocated instance' do
216
+ # @pool.stubs(:current_instance_id).returns(123)
217
+ # inst = @pool.instance
218
+ # @pool.release_instance(123)
219
+ # @pool.instance.should eql(inst)
220
+ # end
221
+ # end
222
+ #
223
+ # it 'should properly allocate/deallocate instances' do
224
+ # @pool.stubs(:current_instance_id).returns(123)
225
+ # @pool.expects(:checkout).returns(@adapter)
226
+ # @pool.expects(:checkin)
227
+ # @pool.with_instance do |instance|
228
+ # end
229
+ # end
230
+ end
@@ -0,0 +1,120 @@
1
+ require 'spec_helper'
2
+
3
+ describe NinjaModel::Adapters do
4
+ let(:klass) { Class.new(NinjaModel::Base) }
5
+ #class SmarterAdapter < NinjaModel::Adapters::AbstractAdapter; end
6
+ #before {
7
+ # NinjaModel::Base.register_adapter(:dummy, DummyAdapter::Adapter)
8
+ # NinjaModel::Base.register_adapter(:smarter, SmarterAdapter)
9
+ #}
10
+ subject { klass }
11
+ it { should respond_to(:register_adapter) }
12
+ it { should respond_to(:set_adapter) }
13
+
14
+ describe 'adapter' do
15
+ subject { klass.new }
16
+ it 'should call retrieve_adapter' do
17
+ klass.expects(:retrieve_adapter)
18
+ subject.adapter
19
+ end
20
+ end
21
+
22
+ describe 'register_adapter' do
23
+ context 'with an invalid adapter' do
24
+ it 'should raise an InvalidAdapter exception' do
25
+ lambda { subject.register_adapter(:dummy, Class.new) }.should raise_error(NinjaModel::InvalidAdapter)
26
+ end
27
+ end
28
+
29
+ context 'with a valid adapter' do
30
+ let(:adapter) { Class.new(NinjaModel::Adapters::AbstractAdapter) }
31
+ it 'should register with the adapter manager' do
32
+ subject.adapter_manager.class.expects(:register_adapter_class).with(:dummy, adapter)
33
+ subject.register_adapter(:dummy, adapter)
34
+ end
35
+ end
36
+ end
37
+
38
+ describe 'set_adapter' do
39
+ let(:spec) { {'development' => {:adapter => :dummy } } }
40
+ let(:configuration) { stub(:specs => spec) }
41
+ let!(:adapter_spec) { NinjaModel::Adapters::AdapterSpecification.new(spec['development'], :dummy) }
42
+ before {
43
+ NinjaModel.stubs(:configuration).returns(configuration)
44
+ NinjaModel::Adapters::AdapterManager.stubs(:registered?).with(:dummy).returns(true)
45
+ NinjaModel::Adapters::AdapterSpecification.stubs(:new).with(spec['development'], :dummy).returns(adapter_spec)
46
+ }
47
+ subject { klass }
48
+ context 'when nil is passed' do
49
+ context 'when rails is unavailable' do
50
+ it 'should raise AdapterNotSpecified' do
51
+ lambda { subject.set_adapter }.should raise_error(NinjaModel::AdapterNotSpecified)
52
+ end
53
+ context 'when Rails is available' do
54
+ it 'should recurse with the Rails environment' do
55
+ rails = Object.const_set('Rails', Class.new(Object))
56
+ rails.stubs(:env).returns('development')
57
+ subject.adapter_manager.expects(:create_adapter).with(subject.name, adapter_spec)
58
+ subject.set_adapter
59
+ Object.send(:remove_const, :Rails)
60
+ end
61
+ end
62
+ end
63
+ end
64
+
65
+ context 'when a string is passed' do
66
+ it 'should successfully set an adapter' do
67
+ subject.adapter_manager.expects(:create_adapter).with(subject.name, adapter_spec)
68
+ subject.set_adapter('development')
69
+ end
70
+
71
+ context 'and the string is invalid' do
72
+ it 'should raise InvalidSpecification' do
73
+ lambda { subject.set_adapter('foobar') }.should raise_error(NinjaModel::InvalidSpecification)
74
+ end
75
+ end
76
+ end
77
+
78
+ context 'when a symbol is passed' do
79
+ it 'should successfully set an adapter' do
80
+ subject.adapter_manager.expects(:create_adapter).with(subject.name, adapter_spec)
81
+ subject.set_adapter(:development)
82
+ end
83
+
84
+ context 'and the symbol is invalid' do
85
+ it 'should raise InvalidSpecification' do
86
+ lambda { subject.set_adapter(:foobar) }.should raise_error(NinjaModel::InvalidSpecification)
87
+ end
88
+ end
89
+ end
90
+
91
+ context 'when a spec is passed' do
92
+ it 'should successfully set an adapter' do
93
+ subject.adapter_manager.expects(:create_adapter).with(subject.name, adapter_spec)
94
+ subject.set_adapter(spec['development'])
95
+
96
+ end
97
+ end
98
+
99
+ context 'when a specification is passed' do
100
+ it 'should successfully set an adapter' do
101
+ subject.adapter_manager.expects(:create_adapter).with(subject.name, adapter_spec)
102
+ subject.set_adapter(adapter_spec)
103
+ end
104
+ end
105
+ end
106
+
107
+ describe 'retrieve_adapter' do
108
+ it 'should call retrieve_adapter on the manager' do
109
+ klass.adapter_manager.expects(:retrieve_adapter).with(klass)
110
+ klass.retrieve_adapter
111
+ end
112
+ end
113
+
114
+ describe 'shutdown_adapter' do
115
+ it 'should call remove_adapter on the manager' do
116
+ klass.adapter_manager.expects(:remove_adapter).with(klass)
117
+ klass.shutdown_adapter
118
+ end
119
+ end
120
+ end