ninja-model 0.4.2 → 0.5.1
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 +19 -0
- data/Rakefile +0 -7
- data/autotest/discover.rb +1 -0
- data/lib/ninja_model.rb +22 -26
- data/lib/ninja_model/adapters.rb +33 -43
- data/lib/ninja_model/adapters/abstract_adapter.rb +2 -10
- data/lib/ninja_model/adapters/adapter_manager.rb +17 -10
- data/lib/ninja_model/adapters/adapter_pool.rb +15 -17
- data/lib/ninja_model/adapters/adapter_specification.rb +3 -3
- data/lib/ninja_model/associations.rb +25 -106
- data/lib/ninja_model/associations/association_proxy.rb +119 -1
- data/lib/ninja_model/associations/belongs_to_association.rb +5 -1
- data/lib/ninja_model/attribute.rb +130 -0
- data/lib/ninja_model/{attributes.rb → attribute_methods.rb} +21 -42
- data/lib/ninja_model/base.rb +23 -20
- data/lib/ninja_model/callbacks.rb +2 -11
- data/lib/ninja_model/identity.rb +6 -11
- data/lib/ninja_model/persistence.rb +15 -30
- data/lib/ninja_model/predicate.rb +4 -4
- data/lib/ninja_model/rails_ext/active_record.rb +187 -0
- data/lib/ninja_model/railtie.rb +14 -8
- data/lib/ninja_model/reflection.rb +7 -14
- data/lib/ninja_model/relation.rb +5 -3
- data/lib/ninja_model/relation/finder_methods.rb +4 -8
- data/lib/ninja_model/relation/spawn_methods.rb +1 -1
- data/lib/ninja_model/validation.rb +6 -23
- data/lib/ninja_model/version.rb +1 -1
- data/ninja-model.gemspec +28 -0
- data/spec/ninja_model/adapters/abstract_adapter_spec.rb +45 -0
- data/spec/ninja_model/adapters/adapter_manager_spec.rb +69 -0
- data/spec/ninja_model/adapters/adapter_pool_spec.rb +210 -48
- data/spec/ninja_model/adapters_spec.rb +77 -0
- data/spec/ninja_model/attribute_methods_spec.rb +95 -0
- data/spec/ninja_model/attribute_spec.rb +129 -0
- data/spec/ninja_model/base_spec.rb +4 -52
- data/spec/ninja_model/identity_spec.rb +16 -32
- data/spec/ninja_model/persistence_spec.rb +130 -4
- data/spec/ninja_model/predicate_spec.rb +40 -6
- data/spec/ninja_model/query_methods_spec.rb +76 -74
- data/spec/ninja_model/reflection_spec.rb +63 -0
- data/spec/ninja_model/relation_spec.rb +213 -20
- data/spec/ninja_model/symbol_spec.rb +19 -0
- data/spec/ninja_model/validation_spec.rb +18 -0
- data/spec/spec_helper.rb +9 -0
- data/spec/support/matchers/convert.rb +30 -0
- metadata +85 -63
- data/lib/ninja_model/associations/active_record_proxy.rb +0 -53
- data/lib/ninja_model/associations/ninja_model_proxy.rb +0 -46
- data/lib/ninja_model/configuration.rb +0 -20
- data/lib/ninja_model/errors.rb +0 -5
- data/lib/ninja_model/log_subscriber.rb +0 -18
- data/lib/ninja_model/scoping.rb +0 -50
- data/spec/ninja_model/attributes_spec.rb +0 -85
- data/spec/ninja_model/scoping_spec.rb +0 -40
@@ -1,8 +1,85 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
3
|
describe NinjaModel::Adapters do
|
4
|
+
class DummyAdapter < NinjaModel::Adapters::AbstractAdapter; end
|
5
|
+
class SmarterAdapter < NinjaModel::Adapters::AbstractAdapter; end
|
6
|
+
before {
|
7
|
+
NinjaModel::Base.register_adapter(:dummy, DummyAdapter)
|
8
|
+
NinjaModel::Base.register_adapter(:smarter, SmarterAdapter)
|
9
|
+
}
|
10
|
+
subject { Class.new(NinjaModel::Base) }
|
11
|
+
it { should respond_to(:register_adapter) }
|
12
|
+
it { should respond_to(:set_adapter) }
|
13
|
+
|
14
|
+
describe 'adapter' do
|
15
|
+
before { @klass = Class.new(NinjaModel::Base) }
|
16
|
+
subject { @klass.new }
|
17
|
+
it 'should call retrieve_adapter' do
|
18
|
+
@klass.expects(:retrieve_adapter)
|
19
|
+
subject.adapter
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
describe 'register_adapter' do
|
24
|
+
it 'should register with the adapter manager' do
|
25
|
+
subject.adapter_manager.class.expects(:register_adapter_class).with(:dummy, DummyAdapter)
|
26
|
+
subject.register_adapter(:dummy, DummyAdapter)
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
4
30
|
describe 'set_adapter' do
|
31
|
+
before {
|
32
|
+
@configuration = mock('Configuration') do
|
33
|
+
stubs(:specs).returns({'development' => {:adapter => :dummy}})
|
34
|
+
end
|
35
|
+
NinjaModel.stubs(:configuration).returns(@configuration)
|
36
|
+
@klass = Class.new(NinjaModel::Base)
|
37
|
+
}
|
38
|
+
subject { @klass }
|
39
|
+
context 'when nil is passed' do
|
40
|
+
it 'should return a DummyAdapter if Rails is available' do
|
41
|
+
@rails = Object.const_set('Rails', Class.new(Object))
|
42
|
+
@rails.stubs(:env).returns('development')
|
43
|
+
subject.set_adapter.spec.name.should eql(:dummy)
|
44
|
+
Object.send(:remove_const, :Rails)
|
45
|
+
end
|
46
|
+
it 'should raise AdapterNotSpecified is Rails is not available' do
|
47
|
+
lambda { subject.set_adapter }.should raise_error(NinjaModel::Adapters::AdapterNotSpecified)
|
48
|
+
end
|
49
|
+
end
|
50
|
+
it 'should return a DummyAdapter pool when "development" is passed' do
|
51
|
+
subject.set_adapter('development').spec.name.should eql(:dummy)
|
52
|
+
end
|
53
|
+
it 'should return a DummyAdapter pool when a dummy specification is passed' do
|
54
|
+
subject.set_adapter(:adapter => :dummy).spec.name.should eql(:dummy)
|
55
|
+
end
|
56
|
+
it 'should return a SmarterAdapter pool when a smarter specification is passed' do
|
57
|
+
subject.set_adapter(:adapter => :smarter).spec.name.should eql(:smarter)
|
58
|
+
end
|
59
|
+
it 'should raise AdapterNotSpecified if the configuration doesn\'t specify an adapter' do
|
60
|
+
lambda { subject.set_adapter({}) }.should raise_error(NinjaModel::Adapters::AdapterNotSpecified)
|
61
|
+
end
|
62
|
+
it 'should raise InvalidAdapter for an invalid adapter name' do
|
63
|
+
lambda { subject.set_adapter(:adapter => :bogus) }.should raise_error(NinjaModel::Adapters::InvalidAdapter)
|
64
|
+
end
|
65
|
+
it 'should raise InvalidSpecification for an invalid Rails.env' do
|
66
|
+
lambda { subject.set_adapter('foobar') }.should raise_error(NinjaModel::Adapters::InvalidSpecification)
|
67
|
+
end
|
68
|
+
end
|
5
69
|
|
70
|
+
describe 'retrieve_adapter' do
|
71
|
+
before { @klass = Class.new(NinjaModel::Base) }
|
72
|
+
it 'should call retrieve_adapter on the manager' do
|
73
|
+
@klass.adapter_manager.expects(:retrieve_adapter).with(@klass)
|
74
|
+
@klass.retrieve_adapter
|
75
|
+
end
|
6
76
|
end
|
7
77
|
|
78
|
+
describe 'shutdown_adapter' do
|
79
|
+
before { @klass = Class.new(NinjaModel::Base) }
|
80
|
+
it 'should call remove_adapter on the manager' do
|
81
|
+
@klass.adapter_manager.expects(:remove_adapter).with(@klass)
|
82
|
+
@klass.shutdown_adapter
|
83
|
+
end
|
84
|
+
end
|
8
85
|
end
|
@@ -0,0 +1,95 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe NinjaModel::AttributeMethods do
|
4
|
+
class AttributeModel < NinjaModel::Base
|
5
|
+
attribute :test, :string
|
6
|
+
end
|
7
|
+
subject { AttributeModel.new }
|
8
|
+
specify { subject.attribute_method?(:test).should be_true }
|
9
|
+
specify { subject.attribute_method?(:invalid).should be_false }
|
10
|
+
|
11
|
+
it 'should return a list of valid attribute names' do
|
12
|
+
AttributeModel.attribute_names.should eql(['test'])
|
13
|
+
end
|
14
|
+
|
15
|
+
it 'should return a valid column list' do
|
16
|
+
AttributeModel.columns.length.should eql(1)
|
17
|
+
end
|
18
|
+
|
19
|
+
it 'should allow updating by hash' do
|
20
|
+
subject.attributes = {:test => 'hashvalue'}
|
21
|
+
subject.test.should eql('hashvalue')
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
describe NinjaModel::AttributeMethods, 'reading an attribute' do
|
26
|
+
class ReaderModel < NinjaModel::Base
|
27
|
+
attribute :test, :string
|
28
|
+
end
|
29
|
+
subject { ReaderModel.new }
|
30
|
+
it { should respond_to(:test) }
|
31
|
+
it 'should call "read_attribute"' do
|
32
|
+
subject.expects(:read_attribute).with('test')
|
33
|
+
subject.test
|
34
|
+
end
|
35
|
+
|
36
|
+
context 'by hash key' do
|
37
|
+
it 'should call "read_attribute"' do
|
38
|
+
subject.expects(:read_attribute).with(:test)
|
39
|
+
subject[:test]
|
40
|
+
end
|
41
|
+
it 'should return the correct value' do
|
42
|
+
subject.test = 'hashcorrect'
|
43
|
+
subject[:test].should eql('hashcorrect')
|
44
|
+
end
|
45
|
+
it 'should accept a string hash key' do
|
46
|
+
subject.test = 'stringkey'
|
47
|
+
subject['test'].should eql('stringkey')
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
context 'before_type_cast' do
|
52
|
+
it 'should not convert the value' do
|
53
|
+
subject.test = Date.new(2001,1,1)
|
54
|
+
subject.test_before_type_cast.should eql(Date.new(2001,1,1))
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
describe NinjaModel::AttributeMethods, 'writing an attribute' do
|
60
|
+
class WriterModel < NinjaModel::Base
|
61
|
+
attribute :test, :string
|
62
|
+
end
|
63
|
+
subject { WriterModel.new }
|
64
|
+
it 'should call "write_attribute"' do
|
65
|
+
subject.expects(:write_attribute).with('test', 'newvalue')
|
66
|
+
subject.test = 'newvalue'
|
67
|
+
end
|
68
|
+
it 'should update the value' do
|
69
|
+
subject.test = 'newvalue'
|
70
|
+
subject.test.should eql('newvalue')
|
71
|
+
end
|
72
|
+
it 'should be dirty' do
|
73
|
+
subject.test = 'newvalue'
|
74
|
+
subject.changed?.should be_true
|
75
|
+
subject.test_changed?.should be_true
|
76
|
+
end
|
77
|
+
it 'should raise an exception for an invalid attribute name' do
|
78
|
+
lambda { subject.write_attribute(:invalid, 'foo') }.should raise_error(NoMethodError)
|
79
|
+
end
|
80
|
+
|
81
|
+
context 'by hash key' do
|
82
|
+
it 'should call "write_attribute"' do
|
83
|
+
subject.expects(:write_attribute).with(:test, 'newvalue')
|
84
|
+
subject[:test] = 'newvalue'
|
85
|
+
end
|
86
|
+
it 'should update the value' do
|
87
|
+
subject[:test] = 'newvalue'
|
88
|
+
subject.test.should eql('newvalue')
|
89
|
+
end
|
90
|
+
it 'should accept a string hash key' do
|
91
|
+
subject['test'] = 'stringkey'
|
92
|
+
subject.test.should eql('stringkey')
|
93
|
+
end
|
94
|
+
end
|
95
|
+
end
|
@@ -0,0 +1,129 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe NinjaModel::Attribute do
|
4
|
+
def mock_attribute(*args)
|
5
|
+
NinjaModel::Attribute.new(*args)
|
6
|
+
end
|
7
|
+
|
8
|
+
RSpec::Matchers.define :convert do |input|
|
9
|
+
chain :to do |expected|
|
10
|
+
@expected = expected
|
11
|
+
end
|
12
|
+
|
13
|
+
match do |attr|
|
14
|
+
@actual = attr.convert(input)
|
15
|
+
@actual.eql?(@expected)
|
16
|
+
end
|
17
|
+
|
18
|
+
failure_message_for_should do |attr|
|
19
|
+
"convert(#{input.inspect}) should be #{@expected.inspect}, but got #{@actual.inspect}"
|
20
|
+
end
|
21
|
+
|
22
|
+
description do |attr|
|
23
|
+
"convert #{input.inspect} to #{@expected.inspect}"
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
context 'an instance' do
|
28
|
+
before {
|
29
|
+
@date_obj = Date.new(2001,1,1)
|
30
|
+
@datetime_obj = DateTime.new(2001,1,1)
|
31
|
+
}
|
32
|
+
subject { mock_attribute(:foo, :string, :default => 'bar') }
|
33
|
+
it { should respond_to(:name) }
|
34
|
+
it { should respond_to(:type) }
|
35
|
+
it { should respond_to(:default) }
|
36
|
+
its(:name) { should eql('foo') }
|
37
|
+
its(:type) { should eql(:string) }
|
38
|
+
its(:default) { should eql('bar') }
|
39
|
+
|
40
|
+
context 'with a :string type' do
|
41
|
+
subject { mock_attribute(:test, :string) }
|
42
|
+
it { should convert('').to('') }
|
43
|
+
it { should convert('foo').to('foo') }
|
44
|
+
it { should convert(123).to('123') }
|
45
|
+
it { should convert(1.23).to('1.23') }
|
46
|
+
it { should convert(@date_obj).to(@date_obj.to_s) }
|
47
|
+
it { should convert(@datetime_obj).to(@datetime_obj.to_s) }
|
48
|
+
it { should convert(true).to('true') }
|
49
|
+
it { should convert(false).to('false') }
|
50
|
+
it { should convert(nil).to(nil) }
|
51
|
+
it 'should raise an error with an unconvertable value' do
|
52
|
+
lambda { subject.convert([]) }.should raise_error(NinjaModel::InvalidConversion)
|
53
|
+
end
|
54
|
+
its(:number?) { should be_false }
|
55
|
+
end
|
56
|
+
|
57
|
+
context 'with an :integer type' do
|
58
|
+
subject { mock_attribute(:test, :integer) }
|
59
|
+
it { should convert('').to(0) }
|
60
|
+
it { should convert('foo').to(0) }
|
61
|
+
it { should convert(123).to(123) }
|
62
|
+
it { should convert(1.23).to(1) }
|
63
|
+
it { should convert(@date_obj).to(1) }
|
64
|
+
it { should convert(@datetime_obj).to(@datetime_obj.to_i) }
|
65
|
+
it { should convert(true).to(1) }
|
66
|
+
it { should convert(false).to(0) }
|
67
|
+
it { should convert(nil).to(0) }
|
68
|
+
its(:number?) { should be_true }
|
69
|
+
end
|
70
|
+
|
71
|
+
context 'with a :float type' do
|
72
|
+
subject { mock_attribute(:test, :float) }
|
73
|
+
it { should convert('').to(0.0) }
|
74
|
+
it { should convert('foo').to(0.0) }
|
75
|
+
it { should convert(123).to(123.0) }
|
76
|
+
it { should convert(1.23).to(1.23) }
|
77
|
+
it { should convert(@date_obj).to(1.0) }
|
78
|
+
it { should convert(@datetime_obj).to(@datetime_obj.to_f) }
|
79
|
+
it { should convert(true).to(1.0) }
|
80
|
+
it { should convert(false).to(0.0) }
|
81
|
+
it { should convert(nil).to(0.0) }
|
82
|
+
its(:number?) { should be_true }
|
83
|
+
end
|
84
|
+
|
85
|
+
context 'with a :date type' do
|
86
|
+
subject { mock_attribute(:test, :date) }
|
87
|
+
it { should convert('').to(nil) }
|
88
|
+
it { should convert('foo').to(nil) }
|
89
|
+
it { should convert(123).to(123) }
|
90
|
+
it { should convert(1.23).to(1.23) }
|
91
|
+
it { should convert(@date_obj).to(@date_obj) }
|
92
|
+
it { should convert(@datetime_obj).to(@datetime_obj) }
|
93
|
+
it { should convert('2001-01-01').to(Date.new(2001,1,1)) }
|
94
|
+
it { should convert(true).to(true) }
|
95
|
+
it { should convert(false).to(false) }
|
96
|
+
it { should convert(nil).to(nil) }
|
97
|
+
its(:number?) { should be_false }
|
98
|
+
end
|
99
|
+
|
100
|
+
context 'with a :datetime type' do
|
101
|
+
subject { mock_attribute(:test, :datetime) }
|
102
|
+
it { should convert('').to(nil) }
|
103
|
+
it { should convert('foo').to(nil) }
|
104
|
+
it { should convert(123).to(123) }
|
105
|
+
it { should convert(1.23).to(1.23) }
|
106
|
+
it { should convert(@date_obj).to(@date_obj) }
|
107
|
+
it { should convert(@datetime_obj).to(@datetime_obj) }
|
108
|
+
it { should convert('2001-01-01 01:01:00').to(DateTime.new(2001,1,1,1,1)) }
|
109
|
+
it { should convert(true).to(true) }
|
110
|
+
it { should convert(false).to(false) }
|
111
|
+
it { should convert(nil).to(nil) }
|
112
|
+
its(:number?) { should be_false }
|
113
|
+
end
|
114
|
+
|
115
|
+
context 'with a :boolean type' do
|
116
|
+
subject { mock_attribute(:test, :boolean) }
|
117
|
+
it { should convert('').to(nil) }
|
118
|
+
it { should convert('foo').to(false) }
|
119
|
+
it { should convert(123).to(false) }
|
120
|
+
it { should convert(1.23).to(false) }
|
121
|
+
it { should convert(@date_obj).to(false) }
|
122
|
+
it { should convert(@datetime_obj).to(false) }
|
123
|
+
it { should convert(true).to(true) }
|
124
|
+
it { should convert(false).to(false) }
|
125
|
+
it { should convert(nil).to(false) }
|
126
|
+
its(:number?) { should be_false }
|
127
|
+
end
|
128
|
+
end
|
129
|
+
end
|
@@ -2,65 +2,17 @@ require 'spec_helper'
|
|
2
2
|
|
3
3
|
describe NinjaModel::Base do
|
4
4
|
it_should_behave_like "ActiveModel"
|
5
|
-
before
|
6
|
-
@klass = Class.new(NinjaModel::Base)
|
7
|
-
end
|
5
|
+
before {
|
6
|
+
@klass = Class.new(NinjaModel::Base)
|
8
7
|
@klass.send :attribute, :width, :integer
|
9
8
|
@klass.send :attribute, :height, :integer
|
10
9
|
@klass.send :attribute, :color, :string
|
11
|
-
|
12
|
-
|
13
|
-
it 'should return a configuration path' do
|
14
|
-
Rails.stubs(:root).returns('/')
|
15
|
-
@klass.configuration_path.should be_kind_of(String)
|
16
|
-
end
|
17
|
-
|
18
|
-
it 'should accept a configuration path' do
|
19
|
-
@klass.configuration_path = 'foo'
|
20
|
-
@klass.configuration_path.should eql('foo')
|
21
|
-
end
|
22
|
-
|
23
|
-
it 'should return NinjaModel\'s logger' do
|
24
|
-
logger = mock('logger')
|
25
|
-
NinjaModel.stubs(:logger).returns(logger)
|
26
|
-
@klass.logger.should eql(logger)
|
27
|
-
end
|
28
|
-
|
29
|
-
it { @klass.should respond_to(:logger) }
|
30
|
-
|
31
|
-
it 'should generate a relation' do
|
32
|
-
@klass.relation.should be_kind_of(NinjaModel::Relation)
|
33
|
-
end
|
10
|
+
}
|
34
11
|
|
35
12
|
it 'should instantiate from an existing data structure' do
|
36
13
|
attrs = {:width => 100, :height => 200, :color => 'red'}
|
37
14
|
@obj = @klass.new
|
38
15
|
@obj.instantiate(attrs)
|
39
|
-
@obj.
|
40
|
-
end
|
41
|
-
|
42
|
-
it 'should return a configuration' do
|
43
|
-
@klass.stubs(:configuration_path)
|
44
|
-
IO.stubs(:read).returns('foo: bar')
|
45
|
-
@klass.configuration.should be_kind_of(Hash)
|
46
|
-
@klass.configuration[:foo].should eql('bar')
|
47
|
-
end
|
48
|
-
|
49
|
-
describe 'scoping' do
|
50
|
-
it 'should return a stock relation for unscoped' do
|
51
|
-
@klass.unscoped.predicates.should be_empty
|
52
|
-
@klass.unscoped.limit_value.should be_nil
|
53
|
-
@klass.unscoped.offset_value.should be_nil
|
54
|
-
@klass.unscoped.ordering.should be_empty
|
55
|
-
@klass.unscoped.predicates.should be_empty
|
56
|
-
end
|
57
|
-
|
58
|
-
it 'should handle default scoping' do
|
59
|
-
@klass.default_scope(@klass.where(:width => 100))
|
60
|
-
rel = @klass.default_scoping.first
|
61
|
-
rel.should be_kind_of(NinjaModel::Relation)
|
62
|
-
rel.predicates.first.should be_kind_of(NinjaModel::Predicate)
|
63
|
-
rel.predicates.first.value.should eql(100)
|
64
|
-
end
|
16
|
+
@obj.width.should eql(100)
|
65
17
|
end
|
66
18
|
end
|
@@ -1,41 +1,25 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
3
|
describe NinjaModel::Identity do
|
4
|
-
|
5
|
-
|
6
|
-
@klass.send :include, NinjaModel::Identity
|
4
|
+
class IdentityModel < NinjaModel::Base
|
5
|
+
attribute :primary, :integer, :primary_key => true
|
7
6
|
end
|
7
|
+
before {
|
8
|
+
@obj = IdentityModel.new
|
9
|
+
@obj.primary = 123
|
10
|
+
@obj
|
11
|
+
}
|
12
|
+
subject { @obj }
|
8
13
|
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
obj
|
14
|
+
context 'when persisted' do
|
15
|
+
before { @obj.stubs(:persisted?).returns(true) }
|
16
|
+
its(:to_param) { should eql('123') }
|
17
|
+
its(:to_key) { should eql([123]) }
|
14
18
|
end
|
15
19
|
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
end
|
21
|
-
|
22
|
-
describe 'to_key' do
|
23
|
-
it 'should generate a key when persisted' do
|
24
|
-
persisted.to_key.should eql([123])
|
25
|
-
end
|
26
|
-
|
27
|
-
it 'should return nil when not persisted' do
|
28
|
-
unpersisted.to_key.should be_nil
|
29
|
-
end
|
30
|
-
end
|
31
|
-
|
32
|
-
describe 'to_param' do
|
33
|
-
it 'should generate a param when persisted' do
|
34
|
-
persisted.to_param.should eql('123')
|
35
|
-
end
|
36
|
-
|
37
|
-
it 'should return nil when not persisted' do
|
38
|
-
unpersisted.to_param.should be_nil
|
39
|
-
end
|
20
|
+
context 'when not persisted' do
|
21
|
+
before { @obj.stubs(:persisted?).returns(false) }
|
22
|
+
its(:to_param) { should be_nil }
|
23
|
+
its(:to_key) { should be_nil }
|
40
24
|
end
|
41
25
|
end
|
@@ -1,9 +1,135 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
3
|
describe NinjaModel::Persistence do
|
4
|
-
|
5
|
-
|
6
|
-
|
4
|
+
class PersistenceModel < NinjaModel::Base
|
5
|
+
attribute :testing, :integer
|
6
|
+
end
|
7
|
+
|
8
|
+
before {
|
9
|
+
@obj = PersistenceModel.new
|
10
|
+
@adapter = mock('Adapter')
|
11
|
+
@obj.class.stubs(:adapter).returns(@adapter)
|
12
|
+
}
|
13
|
+
subject { @obj }
|
14
|
+
it { should respond_to(:save) }
|
15
|
+
it { should respond_to(:create) }
|
16
|
+
it { should respond_to(:update) }
|
17
|
+
it { should respond_to(:new_record?) }
|
18
|
+
it { should respond_to(:destroyed?) }
|
19
|
+
it { should respond_to(:persisted?) }
|
20
|
+
it { should respond_to(:destroy) }
|
21
|
+
it { should respond_to(:reload) }
|
22
|
+
it { should respond_to(:update_attributes) }
|
23
|
+
its(:new_record?) { should be_true }
|
24
|
+
its(:persisted?) { should be_false }
|
25
|
+
its(:destroyed?) { should be_false }
|
26
|
+
|
27
|
+
describe 'save' do
|
28
|
+
before { subject.stubs(:run_callbacks).yields(true) }
|
29
|
+
it 'should run the save callbacks' do
|
30
|
+
subject.expects(:run_callbacks).with(:save)
|
31
|
+
subject.save
|
32
|
+
end
|
33
|
+
|
34
|
+
it 'should call create for a new record' do
|
35
|
+
subject.stubs(:new_record?).returns(true)
|
36
|
+
subject.expects(:create)
|
37
|
+
subject.save
|
38
|
+
end
|
39
|
+
|
40
|
+
it 'should call update for a persisted record' do
|
41
|
+
subject.stubs(:new_record?).returns(false)
|
42
|
+
subject.expects(:update)
|
43
|
+
subject.save
|
44
|
+
end
|
45
|
+
|
46
|
+
it 'should clear the changed attributes after successful save' do
|
47
|
+
attributes = {}
|
48
|
+
subject.stubs(:changed_attributes).returns(attributes)
|
49
|
+
subject.stubs(:new_record?).returns(false)
|
50
|
+
subject.stubs(:update).returns(true)
|
51
|
+
attributes.expects(:clear)
|
52
|
+
subject.save
|
53
|
+
end
|
54
|
+
|
55
|
+
it 'should not clear the changed attributes after unsuccessful save' do
|
56
|
+
attributes = {}
|
57
|
+
subject.stubs(:changed_attributes).returns(attributes)
|
58
|
+
subject.stubs(:new_record?).returns(false)
|
59
|
+
subject.stubs(:update).returns(false)
|
60
|
+
attributes.expects(:clear).never
|
61
|
+
subject.save
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
describe 'create' do
|
66
|
+
before {
|
67
|
+
subject.stubs(:run_callbacks).yields(true)
|
68
|
+
@adapter.stubs(:create).returns(true)
|
69
|
+
}
|
70
|
+
it 'should run the create callbacks' do
|
71
|
+
subject.expects(:run_callbacks).with(:create)
|
72
|
+
subject.create
|
73
|
+
end
|
74
|
+
it 'should call create on the adapter' do
|
75
|
+
@adapter.expects(:create).with(subject)
|
76
|
+
subject.create
|
77
|
+
end
|
78
|
+
it 'should update the persisted status' do
|
79
|
+
subject.create
|
80
|
+
subject.persisted?.should be_true
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
84
|
+
describe 'update' do
|
85
|
+
before {
|
86
|
+
subject.stubs(:run_callbacks).yields(true)
|
87
|
+
@adapter.stubs(:update).returns(true)
|
88
|
+
}
|
89
|
+
it 'should run the update callbacks' do
|
90
|
+
subject.expects(:run_callbacks).with(:update)
|
91
|
+
subject.update
|
92
|
+
end
|
93
|
+
it 'should call update on the adapter' do
|
94
|
+
@adapter.expects(:update).with(subject)
|
95
|
+
subject.update
|
96
|
+
end
|
97
|
+
end
|
98
|
+
|
99
|
+
describe 'destroy' do
|
100
|
+
before {
|
101
|
+
@adapter.stubs(:destroy).returns(true)
|
102
|
+
}
|
103
|
+
it 'should run the destroy callbacks' do
|
104
|
+
subject.expects(:run_callbacks).with(:destroy)
|
105
|
+
subject.destroy
|
106
|
+
end
|
107
|
+
it 'should call destroy on the adapter' do
|
108
|
+
@adapter.expects(:destroy).with(subject)
|
109
|
+
subject.destroy
|
110
|
+
end
|
111
|
+
it 'should update the destroyed? status' do
|
112
|
+
subject.destroy
|
113
|
+
subject.destroyed?.should be_true
|
114
|
+
end
|
115
|
+
it 'should not be persisted afterwards' do
|
116
|
+
subject.destroy
|
117
|
+
subject.persisted?.should be_false
|
118
|
+
end
|
119
|
+
end
|
120
|
+
|
121
|
+
describe 'reload' do
|
122
|
+
it 'should call reload on the adapter' do
|
123
|
+
@adapter.expects(:reload).with(subject)
|
124
|
+
subject.reload
|
125
|
+
end
|
126
|
+
end
|
127
|
+
|
128
|
+
describe 'update_attributes' do
|
129
|
+
it 'update the attributes hash and save' do
|
130
|
+
subject.expects(:save)
|
131
|
+
subject.update_attributes(:testing => 2)
|
132
|
+
subject.testing.should eql(2)
|
133
|
+
end
|
7
134
|
end
|
8
|
-
it { @klass.should respond_to(:get) }
|
9
135
|
end
|