massive_record 0.1.1 → 0.2.0.beta

Sign up to get free protection for your applications and to get access to all the features.
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