ripple 0.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/.document +5 -0
- data/.gitignore +26 -0
- data/LICENSE +13 -0
- data/README.textile +126 -0
- data/RELEASE_NOTES.textile +24 -0
- data/Rakefile +61 -0
- data/VERSION +1 -0
- data/lib/riak.rb +45 -0
- data/lib/riak/bucket.rb +105 -0
- data/lib/riak/client.rb +138 -0
- data/lib/riak/client/curb_backend.rb +63 -0
- data/lib/riak/client/http_backend.rb +209 -0
- data/lib/riak/client/net_http_backend.rb +49 -0
- data/lib/riak/failed_request.rb +37 -0
- data/lib/riak/i18n.rb +15 -0
- data/lib/riak/invalid_response.rb +25 -0
- data/lib/riak/link.rb +54 -0
- data/lib/riak/locale/en.yml +37 -0
- data/lib/riak/map_reduce.rb +240 -0
- data/lib/riak/map_reduce_error.rb +20 -0
- data/lib/riak/robject.rb +234 -0
- data/lib/riak/util/headers.rb +44 -0
- data/lib/riak/util/multipart.rb +52 -0
- data/lib/riak/util/translation.rb +29 -0
- data/lib/riak/walk_spec.rb +113 -0
- data/lib/ripple.rb +48 -0
- data/lib/ripple/core_ext/casting.rb +96 -0
- data/lib/ripple/document.rb +60 -0
- data/lib/ripple/document/attribute_methods.rb +111 -0
- data/lib/ripple/document/attribute_methods/dirty.rb +52 -0
- data/lib/ripple/document/attribute_methods/query.rb +49 -0
- data/lib/ripple/document/attribute_methods/read.rb +38 -0
- data/lib/ripple/document/attribute_methods/write.rb +36 -0
- data/lib/ripple/document/bucket_access.rb +38 -0
- data/lib/ripple/document/finders.rb +84 -0
- data/lib/ripple/document/persistence.rb +93 -0
- data/lib/ripple/document/persistence/callbacks.rb +48 -0
- data/lib/ripple/document/properties.rb +85 -0
- data/lib/ripple/document/validations.rb +44 -0
- data/lib/ripple/embedded_document.rb +38 -0
- data/lib/ripple/embedded_document/persistence.rb +46 -0
- data/lib/ripple/i18n.rb +15 -0
- data/lib/ripple/locale/en.yml +16 -0
- data/lib/ripple/property_type_mismatch.rb +23 -0
- data/lib/ripple/translation.rb +24 -0
- data/ripple.gemspec +159 -0
- data/spec/fixtures/cat.jpg +0 -0
- data/spec/fixtures/multipart-blank.txt +7 -0
- data/spec/fixtures/multipart-with-body.txt +16 -0
- data/spec/riak/bucket_spec.rb +141 -0
- data/spec/riak/client_spec.rb +169 -0
- data/spec/riak/curb_backend_spec.rb +50 -0
- data/spec/riak/headers_spec.rb +34 -0
- data/spec/riak/http_backend_spec.rb +136 -0
- data/spec/riak/link_spec.rb +50 -0
- data/spec/riak/map_reduce_spec.rb +347 -0
- data/spec/riak/multipart_spec.rb +36 -0
- data/spec/riak/net_http_backend_spec.rb +28 -0
- data/spec/riak/object_spec.rb +444 -0
- data/spec/riak/walk_spec_spec.rb +208 -0
- data/spec/ripple/attribute_methods_spec.rb +149 -0
- data/spec/ripple/bucket_access_spec.rb +48 -0
- data/spec/ripple/callbacks_spec.rb +86 -0
- data/spec/ripple/document_spec.rb +35 -0
- data/spec/ripple/embedded_document_spec.rb +52 -0
- data/spec/ripple/finders_spec.rb +146 -0
- data/spec/ripple/persistence_spec.rb +89 -0
- data/spec/ripple/properties_spec.rb +195 -0
- data/spec/ripple/ripple_spec.rb +43 -0
- data/spec/ripple/validations_spec.rb +64 -0
- data/spec/spec.opts +1 -0
- data/spec/spec_helper.rb +32 -0
- data/spec/support/http_backend_implementation_examples.rb +215 -0
- data/spec/support/mock_server.rb +58 -0
- metadata +221 -0
@@ -0,0 +1,149 @@
|
|
1
|
+
# Copyright 2010 Sean Cribbs, Sonian Inc., and Basho Technologies, Inc.
|
2
|
+
#
|
3
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
4
|
+
# you may not use this file except in compliance with the License.
|
5
|
+
# You may obtain a copy of the License at
|
6
|
+
#
|
7
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
8
|
+
#
|
9
|
+
# Unless required by applicable law or agreed to in writing, software
|
10
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
11
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
12
|
+
# See the License for the specific language governing permissions and
|
13
|
+
# limitations under the License.
|
14
|
+
require File.expand_path("../../spec_helper", __FILE__)
|
15
|
+
|
16
|
+
describe Ripple::Document::AttributeMethods do
|
17
|
+
before :all do
|
18
|
+
class Widget
|
19
|
+
include Ripple::Document
|
20
|
+
property :size, Integer
|
21
|
+
property :name, String, :default => "widget"
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
before :each do
|
26
|
+
@widget = Widget.new
|
27
|
+
end
|
28
|
+
|
29
|
+
describe "object key" do
|
30
|
+
it "should provide access to the key" do
|
31
|
+
@widget.should respond_to(:key)
|
32
|
+
@widget.key.should be_nil
|
33
|
+
end
|
34
|
+
|
35
|
+
it "should provide a mutator for the key" do
|
36
|
+
@widget.should respond_to(:key=)
|
37
|
+
@widget.key = "cog"
|
38
|
+
@widget.key.should == "cog"
|
39
|
+
end
|
40
|
+
|
41
|
+
it "should accept the key in mass assignment" do
|
42
|
+
@widget.attributes = {:key => "cog"}
|
43
|
+
@widget.key.should == "cog"
|
44
|
+
end
|
45
|
+
|
46
|
+
end
|
47
|
+
|
48
|
+
describe "accessors" do
|
49
|
+
it "should be defined for defined properties" do
|
50
|
+
@widget.should respond_to(:size)
|
51
|
+
@widget.should respond_to(:name)
|
52
|
+
end
|
53
|
+
|
54
|
+
it "should return nil if no default is defined on the property" do
|
55
|
+
@widget.size.should be_nil
|
56
|
+
end
|
57
|
+
|
58
|
+
it "should return the property default if defined and not set" do
|
59
|
+
@widget.name.should == "widget"
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
describe "mutators" do
|
64
|
+
it "should have mutators for defined properties" do
|
65
|
+
@widget.should respond_to(:size=)
|
66
|
+
@widget.should respond_to(:name=)
|
67
|
+
end
|
68
|
+
|
69
|
+
it "should assign the value of the attribute" do
|
70
|
+
@widget.size = 10
|
71
|
+
@widget.size.should == 10
|
72
|
+
end
|
73
|
+
|
74
|
+
it "should type cast assigned values automatically" do
|
75
|
+
@widget.name = :so_what
|
76
|
+
@widget.name.should == "so_what"
|
77
|
+
end
|
78
|
+
|
79
|
+
it "should raise an error when assigning a bad value" do
|
80
|
+
lambda { @widget.size = true }.should raise_error(Ripple::PropertyTypeMismatch)
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
84
|
+
describe "query methods" do
|
85
|
+
it "should be defined for defined properties" do
|
86
|
+
@widget.should respond_to(:size?)
|
87
|
+
@widget.should respond_to(:name?)
|
88
|
+
end
|
89
|
+
|
90
|
+
it "should be false when the attribute is nil" do
|
91
|
+
@widget.size.should be_nil
|
92
|
+
@widget.size?.should be_false
|
93
|
+
end
|
94
|
+
|
95
|
+
it "should be true when the attribute has a value present" do
|
96
|
+
@widget.size = 10
|
97
|
+
@widget.size?.should be_true
|
98
|
+
end
|
99
|
+
|
100
|
+
it "should be false for 0 values" do
|
101
|
+
@widget.size = 0
|
102
|
+
@widget.size?.should be_false
|
103
|
+
end
|
104
|
+
|
105
|
+
it "should be false for empty values" do
|
106
|
+
@widget.name = ""
|
107
|
+
@widget.name?.should be_false
|
108
|
+
end
|
109
|
+
end
|
110
|
+
|
111
|
+
it "should track changes to attributes" do
|
112
|
+
@widget.name = "foobar"
|
113
|
+
@widget.changed?.should be_true
|
114
|
+
@widget.name_changed?.should be_true
|
115
|
+
@widget.name_change.should == ["widget", "foobar"]
|
116
|
+
@widget.changes.should == {"name" => ["widget", "foobar"]}
|
117
|
+
end
|
118
|
+
|
119
|
+
|
120
|
+
it "should refresh the attribute methods when adding a new property" do
|
121
|
+
Widget.should_receive(:undefine_attribute_methods)
|
122
|
+
Widget.property :start_date, Date
|
123
|
+
Widget.properties.delete(:start_date) # cleanup
|
124
|
+
end
|
125
|
+
|
126
|
+
it "should provide a hash representation of all of the attributes" do
|
127
|
+
@widget.attributes.should == {"name" => "widget", "size" => nil}
|
128
|
+
end
|
129
|
+
|
130
|
+
it "should load attributes from mass assignment" do
|
131
|
+
@widget.attributes = {"name" => "Riak", "size" => 100000 }
|
132
|
+
@widget.name.should == "Riak"
|
133
|
+
@widget.size.should == 100000
|
134
|
+
end
|
135
|
+
|
136
|
+
it "should assign attributes on initialization" do
|
137
|
+
@widget = Widget.new(:name => "Riak")
|
138
|
+
@widget.name.should == "Riak"
|
139
|
+
end
|
140
|
+
|
141
|
+
it "should have no changed attributes after initialization" do
|
142
|
+
@widget = Widget.new(:name => "Riak")
|
143
|
+
@widget.changes.should be_blank
|
144
|
+
end
|
145
|
+
|
146
|
+
after :all do
|
147
|
+
Object.send(:remove_const, :Widget)
|
148
|
+
end
|
149
|
+
end
|
@@ -0,0 +1,48 @@
|
|
1
|
+
# Copyright 2010 Sean Cribbs, Sonian Inc., and Basho Technologies, Inc.
|
2
|
+
#
|
3
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
4
|
+
# you may not use this file except in compliance with the License.
|
5
|
+
# You may obtain a copy of the License at
|
6
|
+
#
|
7
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
8
|
+
#
|
9
|
+
# Unless required by applicable law or agreed to in writing, software
|
10
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
11
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
12
|
+
# See the License for the specific language governing permissions and
|
13
|
+
# limitations under the License.
|
14
|
+
require File.expand_path("../spec_helper", File.dirname(__FILE__))
|
15
|
+
|
16
|
+
describe Ripple::Document::BucketAccess do
|
17
|
+
before :all do
|
18
|
+
class Invoice; include Ripple::Document; end
|
19
|
+
class LateInvoice < Invoice; end
|
20
|
+
class PaidInvoice < Invoice; self.bucket_name = "paid"; end
|
21
|
+
end
|
22
|
+
|
23
|
+
it "should use the plural model name as the bucket name" do
|
24
|
+
Invoice.bucket_name.should == "invoices"
|
25
|
+
end
|
26
|
+
|
27
|
+
it "should use the parent bucket name by default (SBI)" do
|
28
|
+
LateInvoice.bucket_name.should == "invoices"
|
29
|
+
end
|
30
|
+
|
31
|
+
it "should allow a class to set the bucket name" do
|
32
|
+
PaidInvoice.bucket_name.should == "paid"
|
33
|
+
end
|
34
|
+
|
35
|
+
it "should allow access to the bucket" do
|
36
|
+
bucket = Riak::Bucket.new(Ripple.client, "invoices")
|
37
|
+
Ripple.client.should_receive(:[]).with("invoices", {:keys => false}).and_return(bucket)
|
38
|
+
Invoice.bucket.should == bucket
|
39
|
+
end
|
40
|
+
|
41
|
+
after :all do
|
42
|
+
Object.module_eval do
|
43
|
+
remove_const(:PaidInvoice)
|
44
|
+
remove_const(:LateInvoice)
|
45
|
+
remove_const(:Invoice)
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
@@ -0,0 +1,86 @@
|
|
1
|
+
# Copyright 2010 Sean Cribbs, Sonian Inc., and Basho Technologies, Inc.
|
2
|
+
#
|
3
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
4
|
+
# you may not use this file except in compliance with the License.
|
5
|
+
# You may obtain a copy of the License at
|
6
|
+
#
|
7
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
8
|
+
#
|
9
|
+
# Unless required by applicable law or agreed to in writing, software
|
10
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
11
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
12
|
+
# See the License for the specific language governing permissions and
|
13
|
+
# limitations under the License.
|
14
|
+
require File.expand_path("../../spec_helper", __FILE__)
|
15
|
+
|
16
|
+
describe Ripple::Document::Persistence::Callbacks do
|
17
|
+
before :all do
|
18
|
+
class Box; include Ripple::Document; property :shape, String end
|
19
|
+
end
|
20
|
+
|
21
|
+
it "should add create, update, save, and destroy callback declarations" do
|
22
|
+
[:save, :create, :update, :destroy].each do |event|
|
23
|
+
Box.private_instance_methods.should include("_run_#{event}_callbacks")
|
24
|
+
[:before, :after, :around].each do |time|
|
25
|
+
Box.should respond_to("#{time}_#{event}")
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
describe "invoking callbacks" do
|
31
|
+
before :each do
|
32
|
+
response = {:headers => {"content-type" => ["application/json"]}, :body => "{}"}
|
33
|
+
@client = Ripple.client
|
34
|
+
@http = mock("HTTP Backend", :get => response, :put => response, :post => response, :delete => response)
|
35
|
+
@client.stub!(:http).and_return(@http)
|
36
|
+
$pinger = mock("callback verifier")
|
37
|
+
end
|
38
|
+
|
39
|
+
it "should call save callbacks on save" do
|
40
|
+
Box.before_save { $pinger.ping }
|
41
|
+
Box.after_save { $pinger.ping }
|
42
|
+
Box.around_save(lambda { $pinger.ping })
|
43
|
+
$pinger.should_receive(:ping).exactly(3).times
|
44
|
+
@box = Box.new
|
45
|
+
@box.save
|
46
|
+
end
|
47
|
+
|
48
|
+
it "should call create callbacks on save when the document is new" do
|
49
|
+
Box.before_create { $pinger.ping }
|
50
|
+
Box.after_create { $pinger.ping }
|
51
|
+
Box.around_create(lambda { $pinger.ping })
|
52
|
+
$pinger.should_receive(:ping).exactly(3).times
|
53
|
+
@box = Box.new
|
54
|
+
@box.save
|
55
|
+
end
|
56
|
+
|
57
|
+
it "should call update callbacks on save when the document is not new" do
|
58
|
+
Box.before_update { $pinger.ping }
|
59
|
+
Box.after_update { $pinger.ping }
|
60
|
+
Box.around_update(lambda { $pinger.ping })
|
61
|
+
$pinger.should_receive(:ping).exactly(3).times
|
62
|
+
@box = Box.new
|
63
|
+
@box.stub!(:new?).and_return(false)
|
64
|
+
@box.save
|
65
|
+
end
|
66
|
+
|
67
|
+
it "should call destroy callbacks" do
|
68
|
+
Box.before_destroy { $pinger.ping }
|
69
|
+
Box.after_destroy { $pinger.ping }
|
70
|
+
Box.around_destroy(lambda { $pinger.ping })
|
71
|
+
$pinger.should_receive(:ping).exactly(3).times
|
72
|
+
@box = Box.new
|
73
|
+
@box.destroy
|
74
|
+
end
|
75
|
+
|
76
|
+
after :each do
|
77
|
+
[:save, :create, :update, :destroy].each do |type|
|
78
|
+
Box.reset_callbacks(type)
|
79
|
+
end
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
83
|
+
after :all do
|
84
|
+
Object.send(:remove_const, :Box)
|
85
|
+
end
|
86
|
+
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
# Copyright 2010 Sean Cribbs, Sonian Inc., and Basho Technologies, Inc.
|
2
|
+
#
|
3
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
4
|
+
# you may not use this file except in compliance with the License.
|
5
|
+
# You may obtain a copy of the License at
|
6
|
+
#
|
7
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
8
|
+
#
|
9
|
+
# Unless required by applicable law or agreed to in writing, software
|
10
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
11
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
12
|
+
# See the License for the specific language governing permissions and
|
13
|
+
# limitations under the License.
|
14
|
+
require File.expand_path("../spec_helper", File.dirname(__FILE__))
|
15
|
+
|
16
|
+
describe Ripple::Document do
|
17
|
+
before :all do
|
18
|
+
class Page; include Ripple::Document; end
|
19
|
+
end
|
20
|
+
|
21
|
+
it "should add bucket access methods to classes when included" do
|
22
|
+
Page.metaclass.included_modules.should include(Ripple::Document::BucketAccess)
|
23
|
+
Page.should respond_to(:bucket_name)
|
24
|
+
Page.should respond_to(:bucket)
|
25
|
+
Page.should respond_to(:bucket_name=)
|
26
|
+
end
|
27
|
+
|
28
|
+
it "should not be embeddable" do
|
29
|
+
Page.should_not be_embeddable
|
30
|
+
end
|
31
|
+
|
32
|
+
after :all do
|
33
|
+
Object.module_eval { remove_const(:Page) }
|
34
|
+
end
|
35
|
+
end
|
@@ -0,0 +1,52 @@
|
|
1
|
+
# Copyright 2010 Sean Cribbs, Sonian Inc., and Basho Technologies, Inc.
|
2
|
+
#
|
3
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
4
|
+
# you may not use this file except in compliance with the License.
|
5
|
+
# You may obtain a copy of the License at
|
6
|
+
#
|
7
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
8
|
+
#
|
9
|
+
# Unless required by applicable law or agreed to in writing, software
|
10
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
11
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
12
|
+
# See the License for the specific language governing permissions and
|
13
|
+
# limitations under the License.
|
14
|
+
require File.expand_path("../../spec_helper", __FILE__)
|
15
|
+
|
16
|
+
describe Ripple::EmbeddedDocument do
|
17
|
+
before :all do
|
18
|
+
class Address; include Ripple::EmbeddedDocument; end
|
19
|
+
end
|
20
|
+
|
21
|
+
it "should have a model name when included" do
|
22
|
+
Address.should respond_to(:model_name)
|
23
|
+
Address.model_name.should be_kind_of(ActiveModel::Name)
|
24
|
+
end
|
25
|
+
|
26
|
+
it "should be embeddable" do
|
27
|
+
Address.should be_embeddable
|
28
|
+
end
|
29
|
+
|
30
|
+
describe "persistence" do
|
31
|
+
before :each do
|
32
|
+
@root = mock("root document")
|
33
|
+
@root.stub!(:new?).and_return(true)
|
34
|
+
@addr = Address.new
|
35
|
+
@addr._root_document = @root
|
36
|
+
end
|
37
|
+
|
38
|
+
it "should delegate new? to the root document" do
|
39
|
+
@root.should_receive(:new?).and_return(true)
|
40
|
+
@addr.should be_new
|
41
|
+
end
|
42
|
+
|
43
|
+
it "should delegate save to the root document" do
|
44
|
+
@root.should_receive(:save).and_return(true)
|
45
|
+
@addr.save.should be_true
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
after :all do
|
50
|
+
Object.send(:remove_const, :Address)
|
51
|
+
end
|
52
|
+
end
|
@@ -0,0 +1,146 @@
|
|
1
|
+
# Copyright 2010 Sean Cribbs, Sonian Inc., and Basho Technologies, Inc.
|
2
|
+
#
|
3
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
4
|
+
# you may not use this file except in compliance with the License.
|
5
|
+
# You may obtain a copy of the License at
|
6
|
+
#
|
7
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
8
|
+
#
|
9
|
+
# Unless required by applicable law or agreed to in writing, software
|
10
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
11
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
12
|
+
# See the License for the specific language governing permissions and
|
13
|
+
# limitations under the License.
|
14
|
+
require File.expand_path("../../spec_helper", __FILE__)
|
15
|
+
|
16
|
+
describe Ripple::Document::Finders do
|
17
|
+
before :all do
|
18
|
+
class Box
|
19
|
+
include Ripple::Document
|
20
|
+
property :shape, String
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
before :each do
|
25
|
+
@http = mock("HTTP Backend")
|
26
|
+
@client = Ripple.client
|
27
|
+
@client.stub!(:http).and_return(@http)
|
28
|
+
@bucket = Riak::Bucket.new(@client, "boxes")
|
29
|
+
@client.stub!(:[]).and_return(@bucket)
|
30
|
+
end
|
31
|
+
|
32
|
+
it "should return an empty array if no keys are passed to find" do
|
33
|
+
Box.find().should == []
|
34
|
+
end
|
35
|
+
|
36
|
+
describe "finding single documents" do
|
37
|
+
it "should find a single document by key and assign its attributes" do
|
38
|
+
@http.should_receive(:get).with(200, "/raw/", "boxes", "square", {}, {}).and_return({:code => 200, :headers => {"content-type" => ["application/json"]}, :body => '{"shape":"square"}'})
|
39
|
+
box = Box.find("square")
|
40
|
+
box.should be_kind_of(Box)
|
41
|
+
box.shape.should == "square"
|
42
|
+
box.key.should == "square"
|
43
|
+
box.instance_variable_get(:@robject).should_not be_nil
|
44
|
+
box.should_not be_new_record
|
45
|
+
end
|
46
|
+
|
47
|
+
it "should return nil when no object exists at that key" do
|
48
|
+
@http.should_receive(:get).with(200, "/raw/", "boxes", "square", {}, {}).and_raise(Riak::FailedRequest.new(:get, 200, 404, {}, "404 not found"))
|
49
|
+
box = Box.find("square")
|
50
|
+
box.should be_nil
|
51
|
+
end
|
52
|
+
|
53
|
+
it "should re-raise the failed request exception if not a 404" do
|
54
|
+
@http.should_receive(:get).with(200, "/raw/", "boxes", "square", {}, {}).and_raise(Riak::FailedRequest.new(:get, 200, 500, {}, "500 internal server error"))
|
55
|
+
lambda { Box.find("square") }.should raise_error(Riak::FailedRequest)
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
describe "finding multiple documents" do
|
60
|
+
it "should find multiple documents by the keys" do
|
61
|
+
@http.should_receive(:get).with(200, "/raw/", "boxes", "square", {}, {}).and_return({:code => 200, :headers => {"content-type" => ["application/json"]}, :body => '{"shape":"square"}'})
|
62
|
+
@http.should_receive(:get).with(200, "/raw/", "boxes", "rectangle", {}, {}).and_return({:code => 200, :headers => {"content-type" => ["application/json"]}, :body => '{"shape":"rectangle"}'})
|
63
|
+
boxes = Box.find("square", "rectangle")
|
64
|
+
boxes.should have(2).items
|
65
|
+
boxes.first.shape.should == "square"
|
66
|
+
boxes.last.shape.should == "rectangle"
|
67
|
+
end
|
68
|
+
|
69
|
+
it "should return nil for documents that no longer exist" do
|
70
|
+
@http.should_receive(:get).with(200, "/raw/", "boxes", "square", {}, {}).and_return({:code => 200, :headers => {"content-type" => ["application/json"]}, :body => '{"shape":"square"}'})
|
71
|
+
@http.should_receive(:get).with(200, "/raw/", "boxes", "rectangle", {}, {}).and_raise(Riak::FailedRequest.new(:get, 200, 404, {}, "404 not found"))
|
72
|
+
boxes = Box.find("square", "rectangle")
|
73
|
+
boxes.should have(2).items
|
74
|
+
boxes.first.shape.should == "square"
|
75
|
+
boxes.last.should be_nil
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
describe "finding all documents in the bucket" do
|
80
|
+
it "should load all objects in the bucket" do
|
81
|
+
@bucket.should_receive(:keys).and_return(["square", "rectangle"])
|
82
|
+
@http.should_receive(:get).with(200, "/raw/", "boxes", "square", {}, {}).and_return({:code => 200, :headers => {"content-type" => ["application/json"]}, :body => '{"shape":"square"}'})
|
83
|
+
@http.should_receive(:get).with(200, "/raw/", "boxes", "rectangle", {}, {}).and_return({:code => 200, :headers => {"content-type" => ["application/json"]}, :body => '{"shape":"rectangle"}'})
|
84
|
+
boxes = Box.all
|
85
|
+
boxes.should have(2).items
|
86
|
+
boxes.first.shape.should == "square"
|
87
|
+
boxes.last.shape.should == "rectangle"
|
88
|
+
end
|
89
|
+
|
90
|
+
it "should exclude objects that are not found" do
|
91
|
+
@bucket.should_receive(:keys).and_return(["square", "rectangle"])
|
92
|
+
@http.should_receive(:get).with(200, "/raw/", "boxes", "square", {}, {}).and_return({:code => 200, :headers => {"content-type" => ["application/json"]}, :body => '{"shape":"square"}'})
|
93
|
+
@http.should_receive(:get).with(200, "/raw/", "boxes", "rectangle", {}, {}).and_raise(Riak::FailedRequest.new(:get, 200, 404, {}, "404 not found"))
|
94
|
+
boxes = Box.all
|
95
|
+
boxes.should have(1).item
|
96
|
+
boxes.first.shape.should == "square"
|
97
|
+
end
|
98
|
+
|
99
|
+
it "should yield found objects to the passed block and return an empty array" do
|
100
|
+
@bucket.should_receive(:keys).and_yield("square").and_yield("rectangle")
|
101
|
+
@http.should_receive(:get).with(200, "/raw/", "boxes", "square", {}, {}).and_return({:code => 200, :headers => {"content-type" => ["application/json"]}, :body => '{"shape":"square"}'})
|
102
|
+
@http.should_receive(:get).with(200, "/raw/", "boxes", "rectangle", {}, {}).and_return({:code => 200, :headers => {"content-type" => ["application/json"]}, :body => '{"shape":"rectangle"}'})
|
103
|
+
@block = mock()
|
104
|
+
@block.should_receive(:ping).twice
|
105
|
+
Box.all do |box|
|
106
|
+
@block.ping
|
107
|
+
["square", "rectangle"].should include(box.shape)
|
108
|
+
end.should == []
|
109
|
+
end
|
110
|
+
|
111
|
+
it "should yield found objects to the passed block, excluding missing objects, and return an empty array" do
|
112
|
+
@bucket.should_receive(:keys).and_yield("square").and_yield("rectangle")
|
113
|
+
@http.should_receive(:get).with(200, "/raw/", "boxes", "square", {}, {}).and_return({:code => 200, :headers => {"content-type" => ["application/json"]}, :body => '{"shape":"square"}'})
|
114
|
+
@http.should_receive(:get).with(200, "/raw/", "boxes", "rectangle", {}, {}).and_raise(Riak::FailedRequest.new(:get, 200, 404, {}, "404 not found"))
|
115
|
+
@block = mock()
|
116
|
+
@block.should_receive(:ping).once
|
117
|
+
Box.all do |box|
|
118
|
+
@block.ping
|
119
|
+
["square", "rectangle"].should include(box.shape)
|
120
|
+
end.should == []
|
121
|
+
end
|
122
|
+
end
|
123
|
+
|
124
|
+
describe "single-bucket inheritance" do
|
125
|
+
before :all do
|
126
|
+
class CardboardBox < Box; end
|
127
|
+
end
|
128
|
+
|
129
|
+
it "should instantiate as the proper type if defined in the document" do
|
130
|
+
@http.should_receive(:get).with(200, "/raw/", "boxes", "square", {}, {}).and_return({:code => 200, :headers => {"content-type" => ["application/json"]}, :body => '{"shape":"square"}'})
|
131
|
+
@http.should_receive(:get).with(200, "/raw/", "boxes", "rectangle", {}, {}).and_return({:code => 200, :headers => {"content-type" => ["application/json"]}, :body => '{"shape":"rectangle", "_type":"CardboardBox"}'})
|
132
|
+
boxes = Box.find("square", "rectangle")
|
133
|
+
boxes.should have(2).items
|
134
|
+
boxes.first.should_not be_kind_of(CardboardBox)
|
135
|
+
boxes.last.should be_kind_of(CardboardBox)
|
136
|
+
end
|
137
|
+
|
138
|
+
after :all do
|
139
|
+
Object.send(:remove_const, :CardboardBox)
|
140
|
+
end
|
141
|
+
end
|
142
|
+
|
143
|
+
after :all do
|
144
|
+
Object.send(:remove_const, :Box)
|
145
|
+
end
|
146
|
+
end
|