dirt-core 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.
- data/Gemfile +8 -0
- data/Gemfile.lock +46 -0
- data/MIT-LICENSE +23 -0
- data/README +14 -0
- data/doc/BlockValidator.html +272 -0
- data/doc/ClosureValidator.html +276 -0
- data/doc/Dirt.html +158 -0
- data/doc/Dirt/FooBar.html +167 -0
- data/doc/Dirt/HerpZerp.html +161 -0
- data/doc/Dirt/HerpZerp/DerpGerp.html +161 -0
- data/doc/Dirt/HerpZerp/DerpGerp/FooBar.html +167 -0
- data/doc/Dirt/MemoryPersister.html +453 -0
- data/doc/Dirt/MemoryRecord.html +157 -0
- data/doc/Dirt/MissingRecordError.html +157 -0
- data/doc/Dirt/Model.html +320 -0
- data/doc/Dirt/NoPersisterError.html +157 -0
- data/doc/Dirt/Relation.html +338 -0
- data/doc/Dirt/Role.html +345 -0
- data/doc/Dirt/TooManyRecordsError.html +157 -0
- data/doc/Dirt/TransactionError.html +157 -0
- data/doc/ExistenceValidator.html +316 -0
- data/doc/FooBar.html +153 -0
- data/doc/Gemfile.html +131 -0
- data/doc/HerpZerp.html +147 -0
- data/doc/HerpZerp/DerpGerp.html +147 -0
- data/doc/HerpZerp/DerpGerp/FooBar.html +153 -0
- data/doc/Persister.html +311 -0
- data/doc/Persisting.html +413 -0
- data/doc/PresenceValidator.html +281 -0
- data/doc/README.html +132 -0
- data/doc/Role.html +309 -0
- data/doc/Scheduler.html +147 -0
- data/doc/SelfExistenceValidator.html +278 -0
- data/doc/TestPersister.html +411 -0
- data/doc/Validating.html +293 -0
- data/doc/created.rid +18 -0
- data/doc/images/add.png +0 -0
- data/doc/images/brick.png +0 -0
- data/doc/images/brick_link.png +0 -0
- data/doc/images/bug.png +0 -0
- data/doc/images/bullet_black.png +0 -0
- data/doc/images/bullet_toggle_minus.png +0 -0
- data/doc/images/bullet_toggle_plus.png +0 -0
- data/doc/images/date.png +0 -0
- data/doc/images/delete.png +0 -0
- data/doc/images/find.png +0 -0
- data/doc/images/loadingAnimation.gif +0 -0
- data/doc/images/macFFBgHack.png +0 -0
- data/doc/images/package.png +0 -0
- data/doc/images/page_green.png +0 -0
- data/doc/images/page_white_text.png +0 -0
- data/doc/images/page_white_width.png +0 -0
- data/doc/images/plugin.png +0 -0
- data/doc/images/ruby.png +0 -0
- data/doc/images/tag_blue.png +0 -0
- data/doc/images/tag_green.png +0 -0
- data/doc/images/transparent.png +0 -0
- data/doc/images/wrench.png +0 -0
- data/doc/images/wrench_orange.png +0 -0
- data/doc/images/zoom.png +0 -0
- data/doc/index.html +110 -0
- data/doc/js/darkfish.js +155 -0
- data/doc/js/jquery.js +18 -0
- data/doc/js/navigation.js +142 -0
- data/doc/js/search.js +94 -0
- data/doc/js/search_index.js +1 -0
- data/doc/js/searcher.js +228 -0
- data/doc/rdoc.css +543 -0
- data/doc/table_of_contents.html +203 -0
- data/lib/dirt/bdd/matchers.rb +10 -0
- data/lib/dirt/bdd/persister_spec_helper.rb +213 -0
- data/lib/dirt/bdd/shared_examples.rb +29 -0
- data/lib/dirt/contexts/context.rb +15 -0
- data/lib/dirt/core.rb +36 -0
- data/lib/dirt/errors/missing_record_error.rb +4 -0
- data/lib/dirt/errors/no_persister_error.rb +4 -0
- data/lib/dirt/errors/too_many_records_error.rb +4 -0
- data/lib/dirt/errors/transaction_error.rb +4 -0
- data/lib/dirt/models/model_behaviour.rb +47 -0
- data/lib/dirt/persisters/memory_persister.rb +86 -0
- data/lib/dirt/persisters/persister.rb +54 -0
- data/lib/dirt/persisters/relation.rb +38 -0
- data/lib/dirt/roles/persisting.rb +73 -0
- data/lib/dirt/roles/role.rb +32 -0
- data/lib/dirt/roles/validating.rb +27 -0
- data/lib/dirt/roles/validation/closure_validator.rb +15 -0
- data/lib/dirt/roles/validation/existence_validator.rb +53 -0
- data/lib/dirt/roles/validation/presence_validator.rb +21 -0
- data/lib/dirt/roles/validation/self_existence_validator.rb +18 -0
- data/spec/isolations/closure_validator_spec.rb +57 -0
- data/spec/isolations/context_spec.rb +54 -0
- data/spec/isolations/existence_validator_spec.rb +151 -0
- data/spec/isolations/memory_persister_spec.rb +175 -0
- data/spec/isolations/model_spec.rb +91 -0
- data/spec/isolations/persister_spec.rb +113 -0
- data/spec/isolations/persisting_spec.rb +266 -0
- data/spec/isolations/presence_validator_spec.rb +63 -0
- data/spec/isolations/role_spec.rb +116 -0
- data/spec/isolations/self_existence_validator_spec.rb +64 -0
- data/spec/isolations/spec_helper.rb +26 -0
- data/spec/isolations/validating_spec.rb +88 -0
- metadata +161 -0
@@ -0,0 +1,91 @@
|
|
1
|
+
#--
|
2
|
+
# Copyright (c) 2014 Tenjin Inc.
|
3
|
+
#
|
4
|
+
# Permission is hereby granted, free of charge, to any person obtaining
|
5
|
+
# a copy of this software and associated documentation files (the
|
6
|
+
# "Software"), to deal in the Software without restriction, including
|
7
|
+
# without limitation the rights to use, copy, modify, merge, publish,
|
8
|
+
# distribute, sublicense, and/or sell copies of the Software, and to
|
9
|
+
# permit persons to whom the Software is furnished to do so, subject to
|
10
|
+
# the following conditions:
|
11
|
+
#
|
12
|
+
# The above copyright notice and this permission notice shall be
|
13
|
+
# included in all copies or substantial portions of the Software.
|
14
|
+
#
|
15
|
+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
16
|
+
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
17
|
+
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
18
|
+
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
19
|
+
# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
20
|
+
# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
21
|
+
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
22
|
+
#++
|
23
|
+
|
24
|
+
require './spec/isolations/spec_helper'
|
25
|
+
|
26
|
+
module Dirt
|
27
|
+
describe ModelBehaviour do
|
28
|
+
# Need to give it a attributes for testing
|
29
|
+
class Model
|
30
|
+
include ModelBehaviour
|
31
|
+
attr_accessor :test_variable1, :test_variable2
|
32
|
+
end
|
33
|
+
|
34
|
+
let(:expected_value1) { double('a variable') }
|
35
|
+
let(:expected_value2) { double('something else') }
|
36
|
+
|
37
|
+
subject { Model.new(test_variable1: expected_value1, test_variable2: expected_value2) }
|
38
|
+
|
39
|
+
context '#initialize' do
|
40
|
+
it 'should save the given params from the hash' do
|
41
|
+
subject.test_variable1.should == expected_value1
|
42
|
+
subject.test_variable2.should == expected_value2
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
context '#update' do
|
47
|
+
subject { Model.new() }
|
48
|
+
|
49
|
+
it 'should save the given params from the hash' do
|
50
|
+
subject.update(test_variable1: expected_value1, test_variable2: expected_value2)
|
51
|
+
|
52
|
+
subject.test_variable1.should == expected_value1
|
53
|
+
subject.test_variable2.should == expected_value2
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
context '#to_hash' do
|
58
|
+
it 'should return the model data as a hash' do
|
59
|
+
subject.to_hash.should == {test_variable1: expected_value1, test_variable2: expected_value2}
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
context '#==' do
|
64
|
+
it 'should return false vs nil' do
|
65
|
+
subject.==(nil).should be false
|
66
|
+
end
|
67
|
+
|
68
|
+
it 'should return false vs a different object' do
|
69
|
+
subject.==(double('different thingy')).should be false
|
70
|
+
end
|
71
|
+
|
72
|
+
it 'should return true vs itself' do
|
73
|
+
subject.==(subject).should be true
|
74
|
+
end
|
75
|
+
|
76
|
+
it 'should return true vs another object with equivalent values' do
|
77
|
+
other = double('different thingy')
|
78
|
+
|
79
|
+
other.stub(:instance_variable_get).and_return do |*args|
|
80
|
+
if args.first == :@test_variable1
|
81
|
+
expected_value1
|
82
|
+
elsif args.first == :@test_variable2
|
83
|
+
expected_value2
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
87
|
+
subject.==(other).should == true
|
88
|
+
end
|
89
|
+
end
|
90
|
+
end
|
91
|
+
end
|
@@ -0,0 +1,113 @@
|
|
1
|
+
#--
|
2
|
+
# Copyright (c) 2014 Tenjin Inc.
|
3
|
+
#
|
4
|
+
# Permission is hereby granted, free of charge, to any person obtaining
|
5
|
+
# a copy of this software and associated documentation files (the
|
6
|
+
# "Software"), to deal in the Software without restriction, including
|
7
|
+
# without limitation the rights to use, copy, modify, merge, publish,
|
8
|
+
# distribute, sublicense, and/or sell copies of the Software, and to
|
9
|
+
# permit persons to whom the Software is furnished to do so, subject to
|
10
|
+
# the following conditions:
|
11
|
+
#
|
12
|
+
# The above copyright notice and this permission notice shall be
|
13
|
+
# included in all copies or substantial portions of the Software.
|
14
|
+
#
|
15
|
+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
16
|
+
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
17
|
+
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
18
|
+
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
19
|
+
# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
20
|
+
# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
21
|
+
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
22
|
+
#++
|
23
|
+
|
24
|
+
require './spec/isolations/spec_helper'
|
25
|
+
|
26
|
+
module Dirt
|
27
|
+
describe Persister do
|
28
|
+
let(:fake_persister) { double 'Fake Persister' }
|
29
|
+
|
30
|
+
describe '#for' do
|
31
|
+
class FooBar
|
32
|
+
end
|
33
|
+
|
34
|
+
module HerpZerp
|
35
|
+
module DerpGerp
|
36
|
+
class FooBar
|
37
|
+
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
[FooBar, HerpZerp::DerpGerp::FooBar, :foo_bar].each do |arg|
|
43
|
+
context "#{arg} is passed in" do
|
44
|
+
let(:expected_persister) { double('Peristathingy') }
|
45
|
+
|
46
|
+
it 'should save using the given argument and return the expected persister with the appropriate symbol' do
|
47
|
+
Persister.for(arg, expected_persister)
|
48
|
+
Persister.for(:foo_bar).should be expected_persister
|
49
|
+
end
|
50
|
+
|
51
|
+
after(:each) { Persister.clear }
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
context 'no persister for type' do
|
56
|
+
it 'should throw an exception' do
|
57
|
+
expect { Persister.for(:bogus_type) }.to raise_error(NoPersisterError, 'There is no persister for "bogus_types".')
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
describe '#clear' do
|
63
|
+
it 'should empty the persisters hash' do
|
64
|
+
Persister.clear
|
65
|
+
|
66
|
+
Persister.class_variable_get(:@@persisters).should == nil
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
describe "#transaction" do
|
71
|
+
it "should return errors when a Transaction error is raised" do
|
72
|
+
Persister.stub(:for).and_return(fake_persister)
|
73
|
+
expect(fake_persister).to receive(:transaction) do |&block|
|
74
|
+
block.call
|
75
|
+
end
|
76
|
+
|
77
|
+
Persister.transaction([fake_persister]) do
|
78
|
+
raise TransactionError, "The Error"
|
79
|
+
end.should == {errors: ["The Error"]}
|
80
|
+
end
|
81
|
+
|
82
|
+
it "should not rescue non-transaction errors" do
|
83
|
+
Persister.stub(:for).and_return(fake_persister)
|
84
|
+
expect(fake_persister).to receive(:transaction) do |&block|
|
85
|
+
block.call
|
86
|
+
end
|
87
|
+
|
88
|
+
expect { Persister.transaction([fake_persister]) do
|
89
|
+
raise StandardError, "Different Error"
|
90
|
+
end }.to raise_error(StandardError, "Different Error")
|
91
|
+
end
|
92
|
+
|
93
|
+
it "should trigger the block within the transactions of all persisters" do
|
94
|
+
p1, p2, p3 = double('persister'), double('persister'), double('persister')
|
95
|
+
p1.stub(:transaction) do |&block|
|
96
|
+
">#{block.call}<"
|
97
|
+
end
|
98
|
+
|
99
|
+
p2.stub(:transaction) do |&block|
|
100
|
+
">#{block.call}<"
|
101
|
+
end
|
102
|
+
|
103
|
+
p3.stub(:transaction) do |&block|
|
104
|
+
">#{block.call}<"
|
105
|
+
end
|
106
|
+
|
107
|
+
Persister.transaction([p1, p2, p3]) do
|
108
|
+
"Trigger Block"
|
109
|
+
end.should == ">>>Trigger Block<<<"
|
110
|
+
end
|
111
|
+
end
|
112
|
+
end
|
113
|
+
end
|
@@ -0,0 +1,266 @@
|
|
1
|
+
#--
|
2
|
+
# Copyright (c) 2014 Tenjin Inc.
|
3
|
+
#
|
4
|
+
# Permission is hereby granted, free of charge, to any person obtaining
|
5
|
+
# a copy of this software and associated documentation files (the
|
6
|
+
# "Software"), to deal in the Software without restriction, including
|
7
|
+
# without limitation the rights to use, copy, modify, merge, publish,
|
8
|
+
# distribute, sublicense, and/or sell copies of the Software, and to
|
9
|
+
# permit persons to whom the Software is furnished to do so, subject to
|
10
|
+
# the following conditions:
|
11
|
+
#
|
12
|
+
# The above copyright notice and this permission notice shall be
|
13
|
+
# included in all copies or substantial portions of the Software.
|
14
|
+
#
|
15
|
+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
16
|
+
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
17
|
+
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
18
|
+
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
19
|
+
# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
20
|
+
# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
21
|
+
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
22
|
+
#++
|
23
|
+
|
24
|
+
require './spec/isolations/spec_helper'
|
25
|
+
|
26
|
+
module Dirt
|
27
|
+
|
28
|
+
describe Persisting do
|
29
|
+
let(:decorated) { double('decorated', to_hash: {some: 'data'}) }
|
30
|
+
|
31
|
+
subject do
|
32
|
+
Persisting.new(decorated)
|
33
|
+
end
|
34
|
+
|
35
|
+
let(:persister) { MemoryPersister.new(:some_type) }
|
36
|
+
|
37
|
+
before(:each) do
|
38
|
+
Persister.for(:mock, persister)
|
39
|
+
end
|
40
|
+
|
41
|
+
after(:each) do
|
42
|
+
Persister.clear
|
43
|
+
end
|
44
|
+
|
45
|
+
describe '#initialize' do
|
46
|
+
it 'should save the given id' do
|
47
|
+
id = 5
|
48
|
+
p = Persisting.new(decorated, id)
|
49
|
+
p.id.should == id
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
describe '#==' do
|
54
|
+
context 'same id' do
|
55
|
+
let(:decorated) { [5] }
|
56
|
+
|
57
|
+
it 'should be equal with equivalent contents' do
|
58
|
+
clone = [5]
|
59
|
+
decorated.should == clone
|
60
|
+
subject.should == Persisting.new(clone)
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
context 'different id' do
|
65
|
+
it 'should not be equal' do
|
66
|
+
other = Persisting.new(decorated)
|
67
|
+
|
68
|
+
subject.instance_variable_set(:@id, 1)
|
69
|
+
other.instance_variable_set(:@id, 2)
|
70
|
+
|
71
|
+
subject.should_not == other
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
describe '#save' do
|
77
|
+
let(:id) { double('id') }
|
78
|
+
|
79
|
+
context 'persistence completes' do
|
80
|
+
it 'should call persister save with nil id' do
|
81
|
+
persister.should_receive(:save).with(decorated, nil)
|
82
|
+
|
83
|
+
subject.save()
|
84
|
+
end
|
85
|
+
|
86
|
+
it 'should remember the id assinged by persister' do
|
87
|
+
persister.stub(:save).and_return(OpenStruct.new(id: id, data: decorated))
|
88
|
+
|
89
|
+
subject.save()
|
90
|
+
|
91
|
+
subject.id.should == id
|
92
|
+
end
|
93
|
+
|
94
|
+
it 'should return itself' do
|
95
|
+
subject.save().should be subject
|
96
|
+
end
|
97
|
+
end
|
98
|
+
|
99
|
+
context 'persistence fails' do
|
100
|
+
before(:each) do
|
101
|
+
persister.stub(:save).and_return(nil)
|
102
|
+
end
|
103
|
+
|
104
|
+
it 'should call persister save with nil id' do
|
105
|
+
persister.should_receive(:save).with(decorated, nil)
|
106
|
+
|
107
|
+
subject.save()
|
108
|
+
end
|
109
|
+
|
110
|
+
it 'should not remember an id' do
|
111
|
+
subject.save()
|
112
|
+
|
113
|
+
subject.id.should == nil
|
114
|
+
end
|
115
|
+
|
116
|
+
it 'should return nil' do
|
117
|
+
subject.save().should be nil
|
118
|
+
end
|
119
|
+
end
|
120
|
+
end
|
121
|
+
|
122
|
+
context '#load' do
|
123
|
+
context 'there is a record by that id' do
|
124
|
+
let(:id) { persister.save(decorated).id }
|
125
|
+
let(:decorated_hash) { {some: 'data and things'} }
|
126
|
+
|
127
|
+
before(:each) do
|
128
|
+
decorated.stub(:to_hash).and_return(decorated_hash)
|
129
|
+
end
|
130
|
+
|
131
|
+
it 'should load the persisted object into itself' do
|
132
|
+
decorated.should_receive(:update).with(decorated_hash)
|
133
|
+
|
134
|
+
subject.load(id)
|
135
|
+
end
|
136
|
+
|
137
|
+
it 'should keep the id' do
|
138
|
+
decorated.stub(:update)
|
139
|
+
|
140
|
+
subject.load(id).id.should == id
|
141
|
+
end
|
142
|
+
|
143
|
+
it 'should return itself' do
|
144
|
+
decorated.stub(:update)
|
145
|
+
|
146
|
+
subject.load(id).should be subject
|
147
|
+
end
|
148
|
+
end
|
149
|
+
|
150
|
+
context 'no record has that id' do
|
151
|
+
it 'should explode' do
|
152
|
+
expect { subject.load(double('id')) }.to raise_error(MissingRecordError)
|
153
|
+
end
|
154
|
+
end
|
155
|
+
end
|
156
|
+
|
157
|
+
context '#load_by' do
|
158
|
+
let(:attr) { :test_attr }
|
159
|
+
let(:value) { double('test value') }
|
160
|
+
|
161
|
+
let(:record1) { double('record1', to_hash: {some: 'data1'}) }
|
162
|
+
let(:record2) { double('record2', to_hash: {some: 'data2'}) }
|
163
|
+
let(:record3) { double('record3', to_hash: {some: 'data3'}) }
|
164
|
+
|
165
|
+
before(:each) do
|
166
|
+
persister.save(record1)
|
167
|
+
persister.save(record2)
|
168
|
+
persister.save(record3)
|
169
|
+
end
|
170
|
+
|
171
|
+
context 'there is a record by that attribute' do
|
172
|
+
let(:record_hash) { {attr => 'record2\'s hash'} }
|
173
|
+
|
174
|
+
before(:each) do
|
175
|
+
record1.stub(attr).and_return(double('something else'))
|
176
|
+
record2.stub(attr).and_return(double('something else'))
|
177
|
+
record3.stub(attr).and_return(value)
|
178
|
+
|
179
|
+
record3.stub(:to_hash).and_return(record_hash)
|
180
|
+
end
|
181
|
+
|
182
|
+
it 'should load the persisted object into itself' do
|
183
|
+
decorated.should_receive(:update).with(record_hash)
|
184
|
+
|
185
|
+
subject.load_by(attr => value)
|
186
|
+
end
|
187
|
+
|
188
|
+
it 'should return itself' do
|
189
|
+
decorated.stub(:update)
|
190
|
+
|
191
|
+
subject.load_by(attr => value).should be subject
|
192
|
+
end
|
193
|
+
|
194
|
+
it 'should keep the found id' do
|
195
|
+
decorated.stub(:update)
|
196
|
+
|
197
|
+
subject.load_by(attr => value).id.should == 3
|
198
|
+
end
|
199
|
+
end
|
200
|
+
|
201
|
+
context 'multiple records have that attribute' do
|
202
|
+
let(:record_hash) { {record_attr: 'and a value'} }
|
203
|
+
|
204
|
+
before(:each) do
|
205
|
+
record1.stub(attr).and_return(double('something else'))
|
206
|
+
record2.stub(attr).and_return(value)
|
207
|
+
record3.stub(attr).and_return(value)
|
208
|
+
|
209
|
+
record2.stub(:to_hash).and_return(record_hash)
|
210
|
+
end
|
211
|
+
|
212
|
+
it 'should load the first matching persisted object into itself' do
|
213
|
+
decorated.should_receive(:update).with(record_hash)
|
214
|
+
|
215
|
+
subject.load_by(attr => value)
|
216
|
+
end
|
217
|
+
|
218
|
+
it 'should return itself' do
|
219
|
+
decorated.stub(:update)
|
220
|
+
|
221
|
+
subject.load_by(attr => value).should be subject
|
222
|
+
end
|
223
|
+
|
224
|
+
it 'should keep the found id' do
|
225
|
+
decorated.stub(:update)
|
226
|
+
|
227
|
+
subject.load_by(attr => value).id.should == 2
|
228
|
+
end
|
229
|
+
end
|
230
|
+
|
231
|
+
context 'no record has that attribute' do
|
232
|
+
before(:each) do
|
233
|
+
record1.stub(attr).and_return(double('something else'))
|
234
|
+
record2.stub(attr).and_return(double('something else'))
|
235
|
+
record3.stub(attr).and_return(double('something else'))
|
236
|
+
end
|
237
|
+
|
238
|
+
it 'should NOT load the persisted object but explode' do
|
239
|
+
decorated.should_not_receive(:update)
|
240
|
+
|
241
|
+
expect { subject.load_by(attr => value) }.to raise_error(MissingRecordError, "No record matches #{attr} == #{value}.")
|
242
|
+
end
|
243
|
+
end
|
244
|
+
end
|
245
|
+
|
246
|
+
context '#delete' do
|
247
|
+
context 'there is a record by that id' do
|
248
|
+
let(:id) { persister.save(decorated).id }
|
249
|
+
it 'should return the persisting-wrapped deleted object' do
|
250
|
+
deleted = Persisting.new(decorated)
|
251
|
+
|
252
|
+
persister.stub(:delete).and_return(deleted)
|
253
|
+
subject.delete(id).should == deleted
|
254
|
+
end
|
255
|
+
end
|
256
|
+
|
257
|
+
context 'no record has that id' do
|
258
|
+
it 'should return nil' do
|
259
|
+
persister.stub(:delete).and_return(nil)
|
260
|
+
|
261
|
+
expect { subject.delete(double('an_id')) }.to raise_error(MissingRecordError)
|
262
|
+
end
|
263
|
+
end
|
264
|
+
end
|
265
|
+
end
|
266
|
+
end
|