massive_record 0.1.1 → 0.2.0.beta

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.
Files changed (83) hide show
  1. data/CHANGELOG.md +28 -5
  2. data/Gemfile.lock +12 -12
  3. data/README.md +29 -1
  4. data/lib/massive_record/adapters/initialize.rb +18 -0
  5. data/lib/massive_record/adapters/thrift/adapter.rb +25 -0
  6. data/lib/massive_record/adapters/thrift/column_family.rb +24 -0
  7. data/lib/massive_record/adapters/thrift/connection.rb +73 -0
  8. data/lib/massive_record/{thrift → adapters/thrift/hbase}/hbase.rb +0 -0
  9. data/lib/massive_record/{thrift → adapters/thrift/hbase}/hbase_constants.rb +0 -0
  10. data/lib/massive_record/{thrift → adapters/thrift/hbase}/hbase_types.rb +0 -0
  11. data/lib/massive_record/adapters/thrift/row.rb +150 -0
  12. data/lib/massive_record/adapters/thrift/scanner.rb +59 -0
  13. data/lib/massive_record/adapters/thrift/table.rb +169 -0
  14. data/lib/massive_record/orm/attribute_methods/read.rb +2 -1
  15. data/lib/massive_record/orm/base.rb +61 -3
  16. data/lib/massive_record/orm/coders/chained.rb +71 -0
  17. data/lib/massive_record/orm/coders/json.rb +17 -0
  18. data/lib/massive_record/orm/coders/yaml.rb +15 -0
  19. data/lib/massive_record/orm/coders.rb +3 -0
  20. data/lib/massive_record/orm/errors.rb +15 -2
  21. data/lib/massive_record/orm/finders/scope.rb +166 -0
  22. data/lib/massive_record/orm/finders.rb +45 -24
  23. data/lib/massive_record/orm/persistence.rb +4 -4
  24. data/lib/massive_record/orm/relations/interface.rb +170 -0
  25. data/lib/massive_record/orm/relations/metadata.rb +150 -0
  26. data/lib/massive_record/orm/relations/proxy/references_many.rb +229 -0
  27. data/lib/massive_record/orm/relations/proxy/references_one.rb +40 -0
  28. data/lib/massive_record/orm/relations/proxy/references_one_polymorphic.rb +49 -0
  29. data/lib/massive_record/orm/relations/proxy.rb +174 -0
  30. data/lib/massive_record/orm/relations.rb +6 -0
  31. data/lib/massive_record/orm/schema/column_interface.rb +1 -1
  32. data/lib/massive_record/orm/schema/field.rb +62 -27
  33. data/lib/massive_record/orm/single_table_inheritance.rb +21 -0
  34. data/lib/massive_record/version.rb +1 -1
  35. data/lib/massive_record/wrapper/adapter.rb +6 -0
  36. data/lib/massive_record/wrapper/base.rb +6 -7
  37. data/lib/massive_record/wrapper/cell.rb +9 -32
  38. data/lib/massive_record/wrapper/column_families_collection.rb +2 -2
  39. data/lib/massive_record/wrapper/errors.rb +10 -0
  40. data/lib/massive_record/wrapper/tables_collection.rb +1 -1
  41. data/lib/massive_record.rb +5 -12
  42. data/spec/orm/cases/attribute_methods_spec.rb +5 -1
  43. data/spec/orm/cases/base_spec.rb +77 -4
  44. data/spec/orm/cases/column_spec.rb +1 -1
  45. data/spec/orm/cases/finder_default_scope.rb +53 -0
  46. data/spec/orm/cases/finder_scope_spec.rb +288 -0
  47. data/spec/orm/cases/finders_spec.rb +56 -13
  48. data/spec/orm/cases/persistence_spec.rb +20 -5
  49. data/spec/orm/cases/single_table_inheritance_spec.rb +26 -0
  50. data/spec/orm/cases/table_spec.rb +1 -1
  51. data/spec/orm/cases/timestamps_spec.rb +16 -16
  52. data/spec/orm/coders/chained_spec.rb +73 -0
  53. data/spec/orm/coders/json_spec.rb +6 -0
  54. data/spec/orm/coders/yaml_spec.rb +6 -0
  55. data/spec/orm/models/best_friend.rb +7 -0
  56. data/spec/orm/models/friend.rb +4 -0
  57. data/spec/orm/models/person.rb +20 -6
  58. data/spec/orm/models/{person_with_timestamps.rb → person_with_timestamp.rb} +1 -1
  59. data/spec/orm/models/test_class.rb +3 -0
  60. data/spec/orm/relations/interface_spec.rb +207 -0
  61. data/spec/orm/relations/metadata_spec.rb +202 -0
  62. data/spec/orm/relations/proxy/references_many_spec.rb +624 -0
  63. data/spec/orm/relations/proxy/references_one_polymorphic_spec.rb +106 -0
  64. data/spec/orm/relations/proxy/references_one_spec.rb +111 -0
  65. data/spec/orm/relations/proxy_spec.rb +13 -0
  66. data/spec/orm/schema/field_spec.rb +101 -2
  67. data/spec/shared/orm/coders/an_orm_coder.rb +14 -0
  68. data/spec/shared/orm/relations/proxy.rb +154 -0
  69. data/spec/shared/orm/relations/singular_proxy.rb +68 -0
  70. data/spec/spec_helper.rb +1 -0
  71. data/spec/thrift/cases/encoding_spec.rb +28 -7
  72. data/spec/wrapper/cases/adapter_spec.rb +9 -0
  73. data/spec/wrapper/cases/connection_spec.rb +13 -10
  74. data/spec/wrapper/cases/table_spec.rb +85 -85
  75. metadata +74 -22
  76. data/TODO.md +0 -8
  77. data/lib/massive_record/exceptions.rb +0 -11
  78. data/lib/massive_record/wrapper/column_family.rb +0 -22
  79. data/lib/massive_record/wrapper/connection.rb +0 -71
  80. data/lib/massive_record/wrapper/row.rb +0 -173
  81. data/lib/massive_record/wrapper/scanner.rb +0 -61
  82. data/lib/massive_record/wrapper/table.rb +0 -149
  83. data/spec/orm/cases/hbase/connection_spec.rb +0 -13
@@ -0,0 +1,106 @@
1
+ require 'spec_helper'
2
+
3
+ class TestReferencesOnePolymorphicProxy < MassiveRecord::ORM::Relations::Proxy::ReferencesOnePolymorphic; end
4
+
5
+ describe TestReferencesOnePolymorphicProxy do
6
+ include SetUpHbaseConnectionBeforeAll
7
+ include SetTableNamesToTestTable
8
+
9
+ let(:proxy_owner) { TestClass.new }
10
+ let(:proxy_target) { Person.new }
11
+ let(:metadata) { subject.metadata }
12
+
13
+ subject { proxy_owner.send(:relation_proxy, 'attachable') }
14
+
15
+ describe "normal proxy behaviour" do
16
+ before do
17
+ proxy_owner.attachable_type = "person"
18
+ end
19
+
20
+ it_should_behave_like "relation proxy"
21
+ it_should_behave_like "singular proxy"
22
+ end
23
+
24
+
25
+ describe "#find_proxy_target" do
26
+ it "should be able to find proxy_target if foreign_key and type is present in proxy_owner" do
27
+ person = Person.new
28
+ proxy_owner.attachable_id = "ID1"
29
+ proxy_owner.attachable_type = "person"
30
+ Person.should_receive(:find).and_return(person)
31
+ proxy_owner.attachable.should == person
32
+ end
33
+
34
+ it "should not be able to find proxy_target if foreign_key is nil" do
35
+ proxy_owner.attachable_id = nil
36
+ proxy_owner.attachable_type = "person"
37
+ Person.should_not_receive(:find)
38
+ proxy_owner.attachable
39
+ end
40
+
41
+ it "should not be able to find proxy_target if type is nil" do
42
+ proxy_owner.attachable_id = "ID1"
43
+ proxy_owner.attachable_type = nil
44
+ Person.should_not_receive(:find)
45
+ proxy_owner.attachable
46
+ end
47
+ end
48
+
49
+
50
+ describe "setting proxy_target object" do
51
+ it "should set the proxy_target's id as the foreign key in proxy_owner" do
52
+ proxy_owner.attachable = proxy_target
53
+ proxy_owner.attachable_id.should == proxy_target.id
54
+ end
55
+
56
+ it "should set the proxy_target's type in proxy_owner" do
57
+ proxy_owner.attachable_type = nil
58
+ proxy_owner.attachable = proxy_target
59
+ proxy_owner.attachable_type.should == proxy_target.class.to_s.underscore
60
+ end
61
+
62
+ it "should reset the proxy_targets foreign key if proxy_target is nil" do
63
+ proxy_owner.attachable = proxy_target
64
+ proxy_owner.attachable = nil
65
+ proxy_owner.attachable_id.should be_nil
66
+ end
67
+
68
+ it "should reset the proxy_target's type in proxy_owner if proxy_target is nil" do
69
+ proxy_owner.attachable = proxy_target
70
+ proxy_owner.attachable = nil
71
+ proxy_owner.attachable_type.should be_nil
72
+ end
73
+
74
+ it "should not set the proxy_target's id as the foreign key if we are not persisting the foreign key" do
75
+ proxy_owner.stub(:respond_to?).and_return(false)
76
+ proxy_owner.attachable = proxy_target
77
+ proxy_owner.attachable_id.should be_nil
78
+ end
79
+
80
+ it "should not set the proxy_target's type if proxy_owner is not responding to type setter" do
81
+ proxy_owner.attachable_type = nil
82
+ proxy_owner.stub(:respond_to?).and_return(false)
83
+ proxy_owner.attachable = proxy_target
84
+ proxy_owner.attachable_type.should be_nil
85
+ end
86
+
87
+ it "should not set the proxy_target's id as the foreign key if the owner has been destroyed" do
88
+ proxy_owner.should_receive(:destroyed?).and_return true
89
+ proxy_owner.attachable = proxy_target
90
+ proxy_owner.attachable_id.should be_nil
91
+ end
92
+
93
+ it "should not set the proxy_target's type as the foreign key if the owner has been destroyed" do
94
+ proxy_owner.should_receive(:destroyed?).and_return true
95
+ proxy_owner.attachable = proxy_target
96
+ proxy_owner.attachable_type.should be_nil
97
+ end
98
+
99
+
100
+
101
+ it "should set the proxy_target's id as the foreign key even if we are not persisting it if the record responds to setter method" do
102
+ proxy_owner.attachable = proxy_target
103
+ proxy_owner.attachable_id.should == proxy_target.id
104
+ end
105
+ end
106
+ end
@@ -0,0 +1,111 @@
1
+ require 'spec_helper'
2
+
3
+ class TestReferencesOneProxy < MassiveRecord::ORM::Relations::Proxy::ReferencesOne; end
4
+
5
+ describe TestReferencesOneProxy do
6
+ include SetUpHbaseConnectionBeforeAll
7
+ include SetTableNamesToTestTable
8
+
9
+ let(:proxy_owner) { Person.new }
10
+ let(:proxy_target) { PersonWithTimestamp.new }
11
+ let(:metadata) { subject.metadata }
12
+
13
+ subject { proxy_owner.send(:relation_proxy, 'boss') }
14
+
15
+ it_should_behave_like "relation proxy"
16
+ it_should_behave_like "singular proxy"
17
+
18
+ it "should be possible to assign relation in new" do
19
+ lambda { Person.new(:boss => PersonWithTimestamp.new) }.should_not raise_error
20
+ end
21
+
22
+ describe "#find_proxy_target" do
23
+ it "should not try to find anything if foreign key is nil" do
24
+ proxy_owner.boss_id = nil
25
+ PersonWithTimestamp.should_not_receive(:find)
26
+ subject.load_proxy_target.should be_nil
27
+ end
28
+
29
+ it "should try to find the proxy_target if foreign key is set" do
30
+ proxy_owner.boss_id = "id"
31
+ PersonWithTimestamp.should_receive(:find).with("id").and_return(proxy_target)
32
+ subject.load_proxy_target.should == proxy_target
33
+ end
34
+ end
35
+
36
+ describe "find with proc" do
37
+ let(:person) { Person.new }
38
+
39
+ before do
40
+ subject.metadata.find_with = Proc.new { |proxy_target| Person.find("testing-123") }
41
+ proxy_owner.boss_id = nil
42
+ end
43
+
44
+ after do
45
+ subject.metadata.find_with = nil
46
+ end
47
+
48
+ it "should not call find_proxy_target" do
49
+ should_not_receive :find_proxy_target
50
+ subject.load_proxy_target
51
+ end
52
+
53
+ it "should load by given proc" do
54
+ Person.should_receive(:find).with("testing-123").and_return(person)
55
+ subject.load_proxy_target.should == person
56
+ end
57
+ end
58
+
59
+ describe "setting proxy_target object" do
60
+ it "should set the proxy_target's id as the foreign key in proxy_owner" do
61
+ proxy_owner.boss = proxy_target
62
+ proxy_owner.boss_id.should == proxy_target.id
63
+ end
64
+
65
+ it "should reset the proxy_targets foreign key if proxy_target is nil" do
66
+ proxy_owner.boss = proxy_target
67
+ proxy_owner.boss = nil
68
+ proxy_owner.boss_id.should be_nil
69
+ end
70
+
71
+ it "should not set the proxy_target's id as the foreign key if we are not persisting the foreign key" do
72
+ proxy_owner.stub(:respond_to?).and_return(false)
73
+ proxy_owner.boss = proxy_target
74
+ proxy_owner.boss_id.should be_nil
75
+ end
76
+
77
+ it "should not set the proxy_target's id as the foreign key if the owner has been destroyed" do
78
+ proxy_owner.should_receive(:destroyed?).and_return true
79
+ proxy_owner.boss = proxy_target
80
+ proxy_owner.boss_id.should be_nil
81
+ end
82
+
83
+ it "should set the proxy_target's id as the foreign key even if we are not persisting it if the record responds to setter method" do
84
+ proxy_owner.boss = proxy_target
85
+ proxy_owner.boss_id.should == proxy_target.id
86
+ end
87
+
88
+ it "should raise an error if there is a type mismatch" do
89
+ lambda { proxy_owner.boss = Person.new }.should raise_error MassiveRecord::ORM::RelationTypeMismatch
90
+ end
91
+ end
92
+
93
+
94
+ describe "type checking of proxy_targets" do
95
+ let(:metadata) { MassiveRecord::ORM::Relations::Metadata.new 'person' }
96
+ let(:person) { Person.new }
97
+ let(:person_with_timestamp) { PersonWithTimestamp.new }
98
+
99
+ before do
100
+ subject.metadata = metadata
101
+ end
102
+
103
+ it "should not raise error if metadata's class corresponds to given proxy_target" do
104
+ lambda { subject.send :raise_if_type_mismatch, person }.should_not raise_error MassiveRecord::ORM::RelationTypeMismatch
105
+ end
106
+
107
+ it "should not raise error if metadata's class corresponds to given proxy_target" do
108
+ lambda { subject.send :raise_if_type_mismatch, person_with_timestamp }.should raise_error MassiveRecord::ORM::RelationTypeMismatch
109
+ end
110
+ end
111
+ end
@@ -0,0 +1,13 @@
1
+ require 'spec_helper'
2
+
3
+ class TestProxy < MassiveRecord::ORM::Relations::Proxy; end
4
+
5
+ describe TestProxy do
6
+ let(:metadata) { MassiveRecord::ORM::Relations::Metadata.new :person }
7
+
8
+ before do
9
+ subject.metadata = metadata
10
+ end
11
+
12
+ it_should_behave_like "relation proxy"
13
+ end
@@ -29,6 +29,11 @@ describe MassiveRecord::ORM::Schema::Field do
29
29
  field.type.should == :integer
30
30
  end
31
31
 
32
+ it "should take type as an option" do
33
+ field = MassiveRecord::ORM::Schema::Field.new_with_arguments_from_dsl("info", :type => :integer)
34
+ field.type.should == :integer
35
+ end
36
+
32
37
  it "should take the rest as options" do
33
38
  field = MassiveRecord::ORM::Schema::Field.new_with_arguments_from_dsl("info", "integer", :default => 0)
34
39
  field.default.should == 0
@@ -115,9 +120,25 @@ describe MassiveRecord::ORM::Schema::Field do
115
120
  @subject.decode(nil).should be_nil
116
121
  end
117
122
 
123
+ it "should cast symbols to strings" do
124
+ @subject = MassiveRecord::ORM::Schema::Field.new(:name => :status, :type => :string)
125
+ @subject.decode(:value).should == "value"
126
+ end
127
+
128
+ it "should decode string null correctly" do
129
+ @subject = MassiveRecord::ORM::Schema::Field.new(:name => :status, :type => :string)
130
+ @subject.decode(@subject.encode("null")).should == "null"
131
+ end
132
+
133
+ it "should decode string with value nil correctly" do
134
+ @subject = MassiveRecord::ORM::Schema::Field.new(:name => :status, :type => :string)
135
+ @subject.decode(@subject.encode(nil)).should == nil
136
+ end
137
+
118
138
  it "should decode an integer value" do
119
139
  @subject = MassiveRecord::ORM::Schema::Field.new(:name => :status, :type => :integer)
120
140
  @subject.decode("1").should == 1
141
+ @subject.decode(1).should == 1
121
142
  @subject.decode("").should be_nil
122
143
  @subject.decode(nil).should be_nil
123
144
  end
@@ -132,18 +153,96 @@ describe MassiveRecord::ORM::Schema::Field do
132
153
  it "should decode a date type" do
133
154
  today = Date.today
134
155
  @subject = MassiveRecord::ORM::Schema::Field.new(:name => :created_at, :type => :date)
135
- @subject.decode(today.to_s) == today
156
+ @subject.decode(today.to_s).should == today
136
157
  @subject.decode("").should be_nil
137
158
  @subject.decode(nil).should be_nil
138
159
  end
160
+
161
+ it "should set date to nil if date could not be parsed" do
162
+ today = "foobar"
163
+ @subject = MassiveRecord::ORM::Schema::Field.new(:name => :created_at, :type => :date)
164
+ @subject.decode(today).should be_nil
165
+ end
139
166
 
140
167
  it "should decode a time type" do
141
168
  today = Time.now
142
169
  @subject = MassiveRecord::ORM::Schema::Field.new(:name => :created_at, :type => :time)
143
- @subject.decode(today.to_s) == today
170
+ @subject.decode(@subject.coder.dump(today)).to_i.should == today.to_i
144
171
  @subject.decode("").should be_nil
145
172
  @subject.decode(nil).should be_nil
146
173
  end
174
+
175
+ it "should set time to nil if date could not be parsed" do
176
+ today = "foobar"
177
+ @subject = MassiveRecord::ORM::Schema::Field.new(:name => :created_at, :type => :time)
178
+ @subject.decode(today).should be_nil
179
+ end
180
+
181
+ it "should deserialize array" do
182
+ @subject = MassiveRecord::ORM::Schema::Field.new(:name => :status, :type => :array)
183
+ @subject.coder = MassiveRecord::ORM::Coders::JSON.new
184
+ @subject.decode(nil).should == nil
185
+ @subject.decode("").should == nil
186
+ @subject.decode("[]").should == []
187
+ @subject.decode([1, 2].to_json).should == [1, 2]
188
+ end
189
+
190
+ it "should deserialize hash" do
191
+ @subject = MassiveRecord::ORM::Schema::Field.new(:name => :status, :type => :hash)
192
+ @subject.coder = MassiveRecord::ORM::Coders::JSON.new
193
+ @subject.decode(nil).should == nil
194
+ @subject.decode("").should == nil
195
+ @subject.decode("{}").should == {}
196
+ @subject.decode({:foo => 'bar'}.to_json).should == {'foo' => 'bar'}
197
+ end
198
+
199
+ it "should raise an argument if expecting array but getting something else" do
200
+ @subject = MassiveRecord::ORM::Schema::Field.new(:name => :status, :type => :array)
201
+ @subject.coder = MassiveRecord::ORM::Coders::JSON.new
202
+ lambda { @subject.decode("false") }.should raise_error MassiveRecord::ORM::SerializationTypeMismatch
203
+ end
204
+
205
+ it "should raise an argument if expecting hash but getting something else" do
206
+ @subject = MassiveRecord::ORM::Schema::Field.new(:name => :status, :type => :hash)
207
+ @subject.coder = MassiveRecord::ORM::Coders::JSON.new
208
+ lambda { @subject.decode("[]") }.should raise_error MassiveRecord::ORM::SerializationTypeMismatch
209
+ end
210
+
211
+ it "should not raise an argument if expecting hash getting nil" do
212
+ @subject = MassiveRecord::ORM::Schema::Field.new(:name => :status, :type => :hash)
213
+ @subject.coder = MassiveRecord::ORM::Coders::JSON.new
214
+ lambda { @subject.decode("null") }.should_not raise_error MassiveRecord::ORM::SerializationTypeMismatch
215
+ end
216
+ end
217
+
218
+ describe "#encode" do
219
+ before do
220
+ @subject = MassiveRecord::ORM::Schema::Field.new(:name => :status)
221
+ @subject.coder = MassiveRecord::ORM::Coders::JSON.new
222
+ end
223
+
224
+ it "should encode normal strings" do
225
+ @subject.type = :string
226
+ @subject.encode("fooo").should == "fooo"
227
+ end
228
+
229
+ it "should encode string if value is null" do
230
+ @subject.type = :string
231
+ @subject.encode("null").should == @subject.coder.dump("null")
232
+ end
233
+
234
+ it "should encode string if value is nil" do
235
+ @subject.type = :string
236
+ @subject.encode(nil).should == "null"
237
+ end
238
+
239
+ (MassiveRecord::ORM::Schema::Field::TYPES - [:string]).each do |type|
240
+ it "should ask coder to dump value when type is #{type}" do
241
+ @subject.type = type
242
+ @subject.coder.should_receive(:dump)
243
+ @subject.encode("{}")
244
+ end
245
+ end
147
246
  end
148
247
 
149
248
  describe "#unique_name" do
@@ -0,0 +1,14 @@
1
+ shared_examples_for "an orm coder" do
2
+ it { should respond_to :load }
3
+ it { should respond_to :dump }
4
+
5
+ [1, "1", nil, ["foo"], {'foo' => 'bar', "1" => 3}, {'nested' => {'inner' => 'secret'}}].each do |value|
6
+ it "should dump a #{value.class} correctly" do
7
+ subject.dump(value).should == code_with.call(value)
8
+ end
9
+
10
+ it "should load a #{value.class} correctly" do
11
+ subject.load(code_with.call(value)).should == value
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,154 @@
1
+ shared_examples_for "relation proxy" do
2
+ let(:proxy_target) { mock(Object).as_null_object }
3
+ let(:find_proxy_target_returns) { subject.represents_a_collection? ? [proxy_target] : proxy_target }
4
+
5
+ before do
6
+ subject.metadata = mock(MassiveRecord::ORM::Relations::Metadata, :find_with => nil).as_null_object if subject.metadata.nil?
7
+ end
8
+
9
+ %w(proxy_owner proxy_target metadata).each do |method|
10
+ it "should respond to #{method}" do
11
+ should respond_to method
12
+ end
13
+ end
14
+
15
+ it "should be setting values by initializer" do
16
+ proxy = MassiveRecord::ORM::Relations::Proxy.new(:proxy_owner => "proxy_owner", :proxy_target => proxy_target, :metadata => "metadata")
17
+ proxy.proxy_owner.should == "proxy_owner"
18
+ proxy.proxy_target.should == proxy_target
19
+ proxy.metadata.should == "metadata"
20
+ end
21
+
22
+ describe "#loaded" do
23
+ it "should be true when loaded" do
24
+ subject.instance_variable_set :@loaded, true
25
+ should be_loaded
26
+ end
27
+
28
+ it "should be false when not loaded" do
29
+ subject.instance_variable_set :@loaded, false
30
+ should_not be_loaded
31
+ end
32
+
33
+ it "should be loaded when loaded! is called" do
34
+ subject.instance_variable_set :@loaded, false
35
+ subject.loaded!
36
+ should be_loaded
37
+ end
38
+ end
39
+
40
+
41
+ describe "#reset" do
42
+ it "should not be loaded after reset" do
43
+ subject.loaded!
44
+ subject.reset
45
+ should_not be_loaded
46
+ end
47
+
48
+ it "should reset the proxy_target" do
49
+ subject.proxy_target = proxy_target
50
+ subject.reset
51
+ subject.stub(:find_proxy_target?).and_return(false)
52
+ subject.proxy_target.should be_blank
53
+ end
54
+ end
55
+
56
+ describe "#reload" do
57
+ before do
58
+ subject.stub!(:find_proxy_target)
59
+ end
60
+
61
+ it "should reset the proxy" do
62
+ subject.should_receive :reset
63
+ subject.reload
64
+ end
65
+
66
+ it "should call load_proxy_target" do
67
+ subject.should_receive :load_proxy_target
68
+ subject.reload
69
+ end
70
+
71
+ it "should return proxy_target if loaded successfully" do
72
+ subject.should_receive(:can_find_proxy_target?).and_return true
73
+ subject.should_receive(:find_proxy_target) { find_proxy_target_returns }
74
+ subject.reload.should == find_proxy_target_returns
75
+ end
76
+
77
+ it "should return nil if loading of proxy_target failed" do
78
+ subject.stub(:can_find_proxy_target?).and_return true
79
+ subject.should_receive(:find_proxy_target).and_raise MassiveRecord::ORM::RecordNotFound
80
+ subject.reload.should be_blank
81
+ end
82
+ end
83
+
84
+
85
+
86
+
87
+ describe "proxy_target" do
88
+ it "should return the proxy_target if it is present" do
89
+ subject.proxy_target = proxy_target
90
+ subject.proxy_target.should == proxy_target
91
+ end
92
+
93
+ it "should be consodered loaded if a proxy_target has been set" do
94
+ subject.proxy_target = proxy_target
95
+ should be_loaded
96
+ end
97
+
98
+ it "should not try to load proxy_target if it has been loaded" do
99
+ subject.loaded!
100
+ should_not_receive :find_proxy_target
101
+ subject.load_proxy_target.should be_blank
102
+ end
103
+
104
+ it "should try to load the proxy_target if it has not been loaded" do
105
+ subject.stub(:can_find_proxy_target?).and_return true
106
+ subject.should_receive(:find_proxy_target) { find_proxy_target_returns }
107
+ subject.load_proxy_target
108
+ subject.proxy_target.should == find_proxy_target_returns
109
+ end
110
+
111
+ it "should reset proxy if proxy_target's record was not found" do
112
+ subject.stub(:can_find_proxy_target?).and_return true
113
+ subject.should_receive(:find_proxy_target).and_raise MassiveRecord::ORM::RecordNotFound
114
+ subject.load_proxy_target.should be_blank
115
+ end
116
+ end
117
+
118
+
119
+ describe "replace" do
120
+ let(:old_proxy_target) { subject.represents_a_collection? ? [subject.proxy_target_class.new] : subject.proxy_target_class.new }
121
+ let(:new_proxy_target) { subject.represents_a_collection? ? [subject.proxy_target_class.new] : subject.proxy_target_class.new }
122
+
123
+ before do
124
+ subject.proxy_target = old_proxy_target
125
+ end
126
+
127
+ it "should replace the old proxy_target with the new one" do
128
+ subject.replace(new_proxy_target)
129
+ subject.proxy_target.should == new_proxy_target
130
+ end
131
+
132
+ it "should reset the proxy if asked to replace with nil" do
133
+ subject.should_receive(:reset)
134
+ subject.replace(nil)
135
+ end
136
+ end
137
+
138
+ describe "find_with" do
139
+ let(:metadata) { MassiveRecord::ORM::Relations::Metadata.new 'person', :find_with => Proc.new { |proxy_target| Person.find("testing-123") }}
140
+ let(:person) { Person.new }
141
+
142
+ before do
143
+ subject.metadata = metadata
144
+ subject.stub(:can_find_proxy_target?).and_return(true)
145
+ end
146
+
147
+ it "should use metadata's find with if exists" do
148
+ Person.should_receive(:find).with("testing-123").and_return(person)
149
+
150
+ should_not_receive :find_proxy_target
151
+ subject.load_proxy_target
152
+ end
153
+ end
154
+ end