ripple 0.6.1 → 0.7.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.
Files changed (110) hide show
  1. data/Rakefile +61 -48
  2. data/lib/ripple.rb +5 -1
  3. data/lib/ripple/core_ext/casting.rb +3 -0
  4. data/lib/ripple/document.rb +6 -2
  5. data/lib/ripple/document/associations.rb +154 -0
  6. data/lib/ripple/document/{persistence/callbacks.rb → associations/embedded.rb} +20 -24
  7. data/lib/ripple/document/associations/instantiators.rb +41 -0
  8. data/lib/{riak/util/translation.rb → ripple/document/associations/linked.rb} +14 -11
  9. data/lib/ripple/document/associations/many.rb +52 -0
  10. data/lib/ripple/document/associations/many_embedded_proxy.rb +49 -0
  11. data/lib/{riak/i18n.rb → ripple/document/associations/one.rb} +18 -2
  12. data/lib/ripple/document/associations/one_embedded_proxy.rb +41 -0
  13. data/lib/ripple/document/associations/proxy.rb +125 -0
  14. data/lib/ripple/document/attribute_methods.rb +8 -1
  15. data/lib/ripple/document/attribute_methods/read.rb +4 -0
  16. data/lib/ripple/document/attribute_methods/write.rb +4 -0
  17. data/lib/ripple/document/bucket_access.rb +1 -1
  18. data/lib/ripple/document/callbacks.rb +75 -0
  19. data/lib/ripple/document/finders.rb +50 -3
  20. data/lib/ripple/document/persistence.rb +14 -6
  21. data/lib/ripple/document/validations.rb +35 -7
  22. data/lib/ripple/document/validations/associated_validator.rb +37 -0
  23. data/lib/ripple/embedded_document.rb +8 -2
  24. data/lib/{riak/map_reduce_error.rb → ripple/embedded_document/conversion.rb} +19 -5
  25. data/lib/{riak/invalid_response.rb → ripple/embedded_document/finders.rb} +17 -8
  26. data/lib/ripple/embedded_document/persistence.rb +75 -13
  27. data/lib/ripple/locale/en.yml +7 -1
  28. data/{spec/riak/net_http_backend_spec.rb → lib/ripple/railtie.rb} +17 -13
  29. data/spec/fixtures/config.yml +3 -0
  30. data/spec/integration/ripple/associations_spec.rb +81 -0
  31. data/spec/integration/ripple/persistence_spec.rb +54 -0
  32. data/spec/ripple/associations/many_embedded_proxy_spec.rb +124 -0
  33. data/spec/ripple/associations/one_embedded_proxy_spec.rb +130 -0
  34. data/spec/ripple/associations/proxy_spec.rb +78 -0
  35. data/spec/ripple/associations_spec.rb +111 -0
  36. data/spec/ripple/attribute_methods_spec.rb +37 -16
  37. data/spec/ripple/bucket_access_spec.rb +3 -14
  38. data/spec/ripple/callbacks_spec.rb +53 -9
  39. data/spec/ripple/document_spec.rb +22 -6
  40. data/spec/ripple/embedded_document/conversion_spec.rb +35 -0
  41. data/spec/{riak/headers_spec.rb → ripple/embedded_document/finders_spec.rb} +17 -14
  42. data/spec/ripple/embedded_document/persistence_spec.rb +86 -0
  43. data/spec/ripple/embedded_document_spec.rb +1 -26
  44. data/spec/ripple/finders_spec.rb +66 -30
  45. data/spec/ripple/persistence_spec.rb +33 -21
  46. data/spec/ripple/properties_spec.rb +1 -7
  47. data/spec/ripple/ripple_spec.rb +10 -0
  48. data/spec/ripple/timestamps_spec.rb +12 -19
  49. data/spec/ripple/validations_spec.rb +48 -6
  50. data/spec/spec_helper.rb +4 -10
  51. data/spec/support/associations/proxies.rb +16 -0
  52. data/spec/support/integration.rb +4 -0
  53. data/spec/support/mocks.rb +3 -0
  54. data/spec/support/models/address.rb +8 -0
  55. data/spec/support/models/box.rb +6 -0
  56. data/spec/support/models/cardboard_box.rb +3 -0
  57. data/spec/support/models/clock.rb +6 -0
  58. data/spec/support/models/customer.rb +4 -0
  59. data/spec/support/models/email.rb +4 -0
  60. data/spec/support/models/family.rb +14 -0
  61. data/spec/support/models/favorite.rb +4 -0
  62. data/spec/support/models/invoice.rb +6 -0
  63. data/spec/support/models/late_invoice.rb +3 -0
  64. data/spec/support/models/note.rb +4 -0
  65. data/spec/support/models/page.rb +4 -0
  66. data/spec/support/models/paid_invoice.rb +4 -0
  67. data/spec/support/models/tree.rb +3 -0
  68. data/spec/support/models/user.rb +6 -0
  69. data/spec/support/models/widget.rb +6 -0
  70. metadata +111 -138
  71. data/.document +0 -5
  72. data/.gitignore +0 -26
  73. data/CONTRIBUTORS.textile +0 -5
  74. data/LICENSE +0 -13
  75. data/README.textile +0 -128
  76. data/RELEASE_NOTES.textile +0 -68
  77. data/VERSION +0 -1
  78. data/lib/riak.rb +0 -46
  79. data/lib/riak/bucket.rb +0 -157
  80. data/lib/riak/client.rb +0 -139
  81. data/lib/riak/client/curb_backend.rb +0 -82
  82. data/lib/riak/client/http_backend.rb +0 -209
  83. data/lib/riak/client/net_http_backend.rb +0 -49
  84. data/lib/riak/failed_request.rb +0 -37
  85. data/lib/riak/link.rb +0 -73
  86. data/lib/riak/locale/en.yml +0 -37
  87. data/lib/riak/map_reduce.rb +0 -248
  88. data/lib/riak/robject.rb +0 -258
  89. data/lib/riak/util/escape.rb +0 -12
  90. data/lib/riak/util/fiber1.8.rb +0 -48
  91. data/lib/riak/util/headers.rb +0 -44
  92. data/lib/riak/util/multipart.rb +0 -52
  93. data/lib/riak/walk_spec.rb +0 -117
  94. data/ripple.gemspec +0 -169
  95. data/spec/fixtures/cat.jpg +0 -0
  96. data/spec/fixtures/multipart-blank.txt +0 -7
  97. data/spec/fixtures/multipart-with-body.txt +0 -16
  98. data/spec/riak/bucket_spec.rb +0 -230
  99. data/spec/riak/client_spec.rb +0 -174
  100. data/spec/riak/curb_backend_spec.rb +0 -50
  101. data/spec/riak/escape_spec.rb +0 -17
  102. data/spec/riak/http_backend_spec.rb +0 -131
  103. data/spec/riak/link_spec.rb +0 -82
  104. data/spec/riak/map_reduce_spec.rb +0 -352
  105. data/spec/riak/multipart_spec.rb +0 -36
  106. data/spec/riak/object_spec.rb +0 -532
  107. data/spec/riak/walk_spec_spec.rb +0 -208
  108. data/spec/spec.opts +0 -1
  109. data/spec/support/http_backend_implementation_examples.rb +0 -215
  110. data/spec/support/mock_server.rb +0 -58
@@ -0,0 +1,3 @@
1
+ ripple:
2
+ port: 9000
3
+ host: localhost
@@ -0,0 +1,81 @@
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 Associations" do
17
+ before :all do
18
+ switch_to_test_node
19
+ Object.module_eval do
20
+ class User
21
+ include Ripple::Document
22
+ one :profile
23
+ many :addresses
24
+ property :email, String, :presence => true
25
+ end
26
+ class Profile
27
+ include Ripple::EmbeddedDocument
28
+ property :name, String, :presence => true
29
+ embedded_in :user
30
+ end
31
+ class Address
32
+ include Ripple::EmbeddedDocument
33
+ property :street, String, :presence => true
34
+ property :kind, String, :presence => true
35
+ embedded_in :user
36
+ end
37
+ end
38
+ end
39
+
40
+ before :each do
41
+ @user = User.new(:email => 'riak@ripple.com')
42
+ @profile = Profile.new(:name => 'Ripple')
43
+ @billing = Address.new(:street => '123 Somewhere Dr', :kind => 'billing')
44
+ @shipping = Address.new(:street => '321 Anywhere Pl', :kind => 'shipping')
45
+ end
46
+
47
+ it "should save one embedded associations" do
48
+ @user.profile = @profile
49
+ @user.save
50
+ @found = User.find(@user.key)
51
+ @found.profile.name.should == 'Ripple'
52
+ @found.profile.should be_a(Profile)
53
+ @found.profile.user.should == @found
54
+ end
55
+
56
+ it "should save many embedded associations" do
57
+ @user.addresses << @billing << @shipping
58
+ @user.save
59
+ @found = User.find(@user.key)
60
+ @found.addresses.count.should == 2
61
+ @bill = @found.addresses.detect {|a| a.kind == 'billing'}
62
+ @ship = @found.addresses.detect {|a| a.kind == 'shipping'}
63
+ @bill.street.should == '123 Somewhere Dr'
64
+ @ship.street.should == '321 Anywhere Pl'
65
+ @bill.user.should == @found
66
+ @ship.user.should == @found
67
+ @bill.should be_a(Address)
68
+ @ship.should be_a(Address)
69
+ end
70
+
71
+ after :each do
72
+ User.destroy_all
73
+ end
74
+
75
+ after :all do
76
+ Object.send(:remove_const, :User)
77
+ Object.send(:remove_const, :Profile)
78
+ Object.send(:remove_const, :Address)
79
+ end
80
+
81
+ end
@@ -0,0 +1,54 @@
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 Persistence" do
17
+ before :all do
18
+ switch_to_test_node
19
+ Object.module_eval do
20
+ class Widget
21
+ include Ripple::Document
22
+ property :name, String
23
+ property :size, Integer
24
+ end
25
+ end
26
+ end
27
+
28
+ before :each do
29
+ @widget = Widget.new
30
+ end
31
+
32
+ it "should save an object to the riak database" do
33
+ @widget.save
34
+ @found = Widget.find(@widget.key)
35
+ @found.should be_a(Widget)
36
+ end
37
+
38
+ it "should save attributes properly to riak" do
39
+ @widget.attributes = {:name => 'Sprocket', :size => 10}
40
+ @widget.save
41
+ @found = Widget.find(@widget.key)
42
+ @found.name.should == 'Sprocket'
43
+ @found.size.should == 10
44
+ end
45
+
46
+ after :each do
47
+ Widget.destroy_all
48
+ end
49
+
50
+ after :all do
51
+ Object.send(:remove_const, :Widget)
52
+ end
53
+
54
+ end
@@ -0,0 +1,124 @@
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::Associations::ManyEmbeddedProxy do
17
+ require 'support/models/user'
18
+ require 'support/models/address'
19
+ require 'support/models/note'
20
+
21
+ before :each do
22
+ @user = User.new
23
+ @address = Address.new
24
+ @addr = Address.new(:street => '123 Somewhere')
25
+ @note = Note.new
26
+ end
27
+
28
+ it "should not have children before any are set" do
29
+ @user.addresses.should == []
30
+ end
31
+
32
+ it "should be able to set and get its children" do
33
+ Address.stub!(:instantiate).and_return(@address)
34
+ @user.addresses = [@address]
35
+ @user.addresses.should == [@address]
36
+ end
37
+
38
+ it "should set the parent document on the children when assigning" do
39
+ @user.addresses = [@address]
40
+ @address._parent_document.should == @user
41
+ end
42
+
43
+ it "should return the assignment when assigning" do
44
+ rtn = @user.addresses = [@address]
45
+ rtn.should == [@address]
46
+ end
47
+
48
+ it "should set the parent document on the children when accessing" do
49
+ @user.addresses = [@address]
50
+ @user.addresses.first._parent_document.should == @user
51
+ end
52
+
53
+ it "should be able to replace its children with different children" do
54
+ @user.addresses = [@address]
55
+ @user.addresses.first.street.should be_blank
56
+ @user.addresses = [@addr]
57
+ @user.addresses.first.street.should == '123 Somewhere'
58
+ end
59
+
60
+ it "should be able to add to its children" do
61
+ Address.stub!(:instantiate).and_return(@address)
62
+ @user.addresses = [@address]
63
+ @user.addresses << @address
64
+ @user.addresses.should == [@address, @address]
65
+ end
66
+
67
+ it "should be able to chain calls to adding children" do
68
+ Address.stub!(:instantiate).and_return(@address)
69
+ @user.addresses = [@address]
70
+ @user.addresses << @address << @address << @address
71
+ @user.addresses.should == [@address, @address, @address, @address]
72
+ end
73
+
74
+ it "should set the parent document when adding to its children" do
75
+ @user.addresses << @address
76
+ @user.addresses.first._parent_document.should == @user
77
+ end
78
+
79
+ it "should be able to count its children" do
80
+ @user.addresses = [@address, @address]
81
+ @user.addresses.count.should == 2
82
+ end
83
+
84
+ it "should be able to build a new child" do
85
+ Address.stub!(:new).and_return(@address)
86
+ @user.addresses.build.should == @address
87
+ end
88
+
89
+ it "should assign a parent to the children created with instantiate_target" do
90
+ Address.stub!(:new).and_return(@address)
91
+ @address._parent_document.should be_nil
92
+ @user.addresses.build._parent_document.should == @user
93
+ end
94
+
95
+ it "should validate the children when saving the parent" do
96
+ @user.valid?.should be_true
97
+ @user.addresses << @address
98
+ @address.valid?.should be_false
99
+ @user.valid?.should be_false
100
+ end
101
+
102
+ it "should not save the root document when a child is invalid" do
103
+ @user.addresses << @address
104
+ @user.save.should be_false
105
+ end
106
+
107
+ it "should allow embedding documents in embedded documents" do
108
+ @user.addresses << @address
109
+ @address.notes << @note
110
+ @note._root_document.should == @user
111
+ @note._parent_document.should == @address
112
+ end
113
+
114
+ it "should allow assiging child documents as an array of hashes" do
115
+ @user.attributes = {'addresses' => [{'street' => '123 Somewhere'}]}
116
+ @user.addresses.first.street.should == '123 Somewhere'
117
+ end
118
+
119
+ it "should return an array from to_ary" do
120
+ Address.stub!(:instantiate).and_return(@address)
121
+ @user.addresses << @address
122
+ @user.addresses.to_ary.should == [@address]
123
+ end
124
+ end
@@ -0,0 +1,130 @@
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::Associations::OneEmbeddedProxy do
17
+ require 'support/models/family'
18
+ require 'support/models/user'
19
+ require 'support/models/address'
20
+
21
+ before :each do
22
+ @parent = Parent.new
23
+ @child = Child.new
24
+ @gchild = Grandchild.new
25
+ end
26
+
27
+ it "should not have a child before one is set" do
28
+ @parent.child.should be_nil
29
+ end
30
+
31
+ it "should be able to set and get its child" do
32
+ Child.stub!(:instantiate).and_return(@child)
33
+ @parent.child = @child
34
+ @parent.child.should == @child
35
+ end
36
+
37
+ it "should set the parent document on the child when assigning" do
38
+ @parent.child = @child
39
+ @child._parent_document.should == @parent
40
+ end
41
+
42
+ it "should return the assignment when assigning" do
43
+ rtn = @parent.child = @child
44
+ rtn.should == @child
45
+ end
46
+
47
+ it "should set the parent document on the child when accessing" do
48
+ @parent.child = @child
49
+ @parent.child._parent_document.should == @parent
50
+ end
51
+
52
+ it "should be able to replace its child with a different child" do
53
+ @son = Child.new(:name => 'Son')
54
+ @parent.child = @child
55
+ @parent.child.name.should be_blank
56
+ @parent.child = @son
57
+ @parent.child.name.should == 'Son'
58
+ end
59
+
60
+ it "should be able to build a new child" do
61
+ Child.stub!(:new).and_return(@child)
62
+ @parent.child.build.should == @child
63
+ end
64
+
65
+ it "should assign a parent to the child created with instantiate_target" do
66
+ Child.stub!(:new).and_return(@child)
67
+ @child._parent_document.should be_nil
68
+ @parent.child.build._parent_document.should == @parent
69
+ end
70
+
71
+ it "should validate the child when saving the parent" do
72
+ @parent.valid?.should be_true
73
+ @child.name = ''
74
+ @parent.child = @child
75
+ @child.valid?.should be_false
76
+ @parent.valid?.should be_false
77
+ end
78
+
79
+ it "should not save the root document when a child is invalid" do
80
+ @parent.child = @child
81
+ @parent.save.should be_false
82
+ end
83
+
84
+ it "should allow embedding documents in embedded documents" do
85
+ @parent.child = @child
86
+ @child.gchild = @gchild
87
+ @gchild._root_document.should == @parent
88
+ @gchild._parent_document.should == @child
89
+ end
90
+
91
+ describe "callbacks" do
92
+ before :each do
93
+ $pinger = mock("callback verifier")
94
+ end
95
+
96
+ it "should run callbacks for the child and documents" do
97
+ $pinger.should_receive(:ping).once
98
+ Child.before_validation { $pinger.ping }
99
+ @child = Child.new
100
+ @child.valid?
101
+ end
102
+
103
+ # this will work using parent and child classes, but only run by itself
104
+ # it also works using different classes, but only run in this file
105
+ # IDK why that is, but my Yakshaver 2000 just ran out of juice
106
+
107
+ # does this even matter? we call valid? all over the place and that
108
+ # will trigger the callback anyway.
109
+ # you probably shouldn't use validation callbacks and expect them to
110
+ # *only* run once
111
+
112
+ # it "should run callbacks for the parent and child and documents respectivly" do
113
+ # $pinger = mock("callback verifier")
114
+ # $pinger.should_receive(:ping).once
115
+ # $pinger.should_receive(:pong).once
116
+ # Child.before_validation { $pinger.ping }
117
+ # Parent.before_validation { $pinger.pong }
118
+ # @child = Child.new
119
+ # @parent = Parent.new
120
+ # @parent.child = @child
121
+ # @parent.valid?
122
+ # end
123
+
124
+ after :each do
125
+ Child.reset_callbacks(:validation)
126
+ Parent.reset_callbacks(:validation)
127
+ end
128
+ end
129
+
130
+ end
@@ -0,0 +1,78 @@
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::Associations::Proxy do
17
+ require 'support/associations/proxies'
18
+
19
+ before :each do
20
+ @owner = mock('owner')
21
+ @owner.stub!(:new?).and_return(false)
22
+ @association = mock('association')
23
+ @association.stub!(:options).and_return({:extend => []})
24
+
25
+ @proxy = FakeProxy.new(@owner, @association)
26
+ @nil_proxy = FakeNilProxy.new(@owner, @association)
27
+ @blank_proxy = FakeBlankProxy.new(@owner, @association)
28
+ end
29
+
30
+ it "should pretend to be the target class" do
31
+ @proxy.should be_kind_of(Array)
32
+ end
33
+
34
+ it "should set the target to nil when reset" do
35
+ @proxy.reset
36
+ @proxy.target.should be_nil
37
+ end
38
+
39
+ describe "delegation" do
40
+ it "should inspect the target" do
41
+ @proxy.inspect.should == "[1, 2]"
42
+ end
43
+
44
+ it "should respond to the same methods as the target" do
45
+ [:each, :size].each do |m|
46
+ @proxy.should respond_to(m)
47
+ end
48
+ @proxy.should_not respond_to(:gsub)
49
+ end
50
+
51
+ it "should send to the proxy if it responds to the method" do
52
+ @proxy.send(:reset)
53
+ @proxy.target.should be_nil
54
+ end
55
+
56
+ it "should send to the target if target responds to the method" do
57
+ @proxy.send(:size).should == 2
58
+ end
59
+
60
+ it "should send resulting in a method missing if neither the proxy nor the target respond to the method" do
61
+ lambda { @proxy.send(:gsub) }.should raise_error(NoMethodError)
62
+ end
63
+ end
64
+
65
+ describe "when target is nil" do
66
+ subject { @nil_proxy }
67
+ it { should be_nil }
68
+ it { should be_blank }
69
+ it { should_not be_present }
70
+ end
71
+
72
+ describe "when the target is blank" do
73
+ subject { @blank_proxy }
74
+ it { should_not be_nil }
75
+ it { should be_blank }
76
+ it { should_not be_present }
77
+ end
78
+ end