ninja-model 0.8.1 → 0.9.0
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.
- data/.gitignore +1 -1
- data/Gemfile +1 -0
- data/Rakefile +6 -0
- data/lib/ninja_model.rb +23 -7
- data/lib/ninja_model/adapters.rb +25 -20
- data/lib/ninja_model/adapters/adapter_manager.rb +2 -0
- data/lib/ninja_model/adapters/adapter_pool.rb +2 -0
- data/lib/ninja_model/associations.rb +63 -101
- data/lib/ninja_model/associations/association.rb +146 -0
- data/lib/ninja_model/associations/association_scope.rb +39 -0
- data/lib/ninja_model/associations/belongs_to_association.rb +33 -21
- data/lib/ninja_model/associations/builder/association.rb +57 -0
- data/lib/ninja_model/associations/builder/belongs_to.rb +33 -0
- data/lib/ninja_model/associations/builder/collection_association.rb +60 -0
- data/lib/ninja_model/associations/builder/has_many.rb +11 -0
- data/lib/ninja_model/associations/builder/has_one.rb +20 -0
- data/lib/ninja_model/associations/builder/singular_association.rb +49 -0
- data/lib/ninja_model/associations/collection_association.rb +103 -0
- data/lib/ninja_model/associations/collection_proxy.rb +45 -0
- data/lib/ninja_model/associations/has_many_association.rb +19 -43
- data/lib/ninja_model/associations/has_one_association.rb +52 -6
- data/lib/ninja_model/associations/singular_association.rb +61 -0
- data/lib/ninja_model/attribute.rb +5 -2
- data/lib/ninja_model/attribute_methods.rb +35 -40
- data/lib/ninja_model/base.rb +31 -39
- data/lib/ninja_model/identity.rb +8 -6
- data/lib/ninja_model/rails_ext/active_record.rb +69 -225
- data/lib/ninja_model/railtie.rb +0 -9
- data/lib/ninja_model/reflection.rb +103 -20
- data/lib/ninja_model/relation.rb +2 -2
- data/lib/ninja_model/relation/query_methods.rb +16 -0
- data/lib/ninja_model/version.rb +1 -1
- data/ninja-model.gemspec +2 -1
- data/spec/db/schema.rb +15 -0
- data/spec/{ninja_model → lib/ninja_model}/adapters/abstract_adapter_spec.rb +0 -0
- data/spec/lib/ninja_model/adapters/adapter_manager_spec.rb +72 -0
- data/spec/lib/ninja_model/adapters/adapter_pool_spec.rb +230 -0
- data/spec/lib/ninja_model/adapters_spec.rb +120 -0
- data/spec/lib/ninja_model/associations/belongs_to_association_spec.rb +76 -0
- data/spec/lib/ninja_model/associations/has_many_association_spec.rb +118 -0
- data/spec/lib/ninja_model/associations/has_one_association_spec.rb +80 -0
- data/spec/{ninja_model → lib/ninja_model}/attribute_methods_spec.rb +2 -2
- data/spec/{ninja_model → lib/ninja_model}/attribute_spec.rb +4 -0
- data/spec/{ninja_model → lib/ninja_model}/base_spec.rb +0 -0
- data/spec/{ninja_model → lib/ninja_model}/identity_spec.rb +0 -0
- data/spec/{ninja_model → lib/ninja_model}/persistence_spec.rb +0 -0
- data/spec/{ninja_model → lib/ninja_model}/predicate_spec.rb +0 -0
- data/spec/{ninja_model → lib/ninja_model}/query_methods_spec.rb +0 -0
- data/spec/{ninja_model → lib/ninja_model}/reflection_spec.rb +7 -9
- data/spec/{ninja_model → lib/ninja_model}/relation_spec.rb +0 -0
- data/spec/{ninja_model → lib/ninja_model}/symbol_spec.rb +0 -0
- data/spec/{ninja_model → lib/ninja_model}/validation_spec.rb +0 -0
- data/spec/{ninja_model_spec.rb → lib/ninja_model_spec.rb} +0 -0
- data/spec/models/bio.rb +8 -0
- data/spec/models/body.rb +7 -0
- data/spec/models/category.rb +7 -0
- data/spec/models/email_address.rb +3 -0
- data/spec/models/post.rb +13 -0
- data/spec/models/tag.rb +3 -0
- data/spec/models/user.rb +4 -0
- data/spec/spec_helper.rb +38 -5
- data/spec/support/dummy_adapter/adapter.rb +48 -0
- data/spec/support/factories/bio.rb +11 -0
- data/spec/support/factories/body.rb +12 -0
- data/spec/support/factories/email_address.rb +5 -0
- data/spec/support/factories/post.rb +12 -0
- data/spec/support/factories/tag.rb +5 -0
- data/spec/support/factories/user.rb +5 -0
- metadata +121 -63
- data/spec/ninja_model/adapters/adapter_manager_spec.rb +0 -69
- data/spec/ninja_model/adapters/adapter_pool_spec.rb +0 -230
- data/spec/ninja_model/adapters_spec.rb +0 -85
data/lib/ninja_model/relation.rb
CHANGED
@@ -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 = [])
|
data/lib/ninja_model/version.rb
CHANGED
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
|
File without changes
|
@@ -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
|