ripple 0.9.0.beta → 0.9.0.beta2
Sign up to get free protection for your applications and to get access to all the features.
- data/Gemfile +7 -6
- data/Rakefile +6 -3
- data/lib/rails/generators/ripple/js/templates/js/iso8601.js +76 -0
- data/lib/rails/generators/ripple/observer/observer_generator.rb +30 -0
- data/lib/rails/generators/ripple/observer/templates/observer.rb +4 -0
- data/lib/rails/generators/ripple/test/templates/test_server.rb +5 -1
- data/lib/ripple/attribute_methods.rb +6 -4
- data/lib/ripple/callbacks.rb +1 -1
- data/lib/ripple/core_ext/casting.rb +4 -4
- data/lib/ripple/document/finders.rb +8 -9
- data/lib/ripple/document/persistence.rb +5 -3
- data/lib/ripple/observable.rb +39 -0
- data/lib/ripple/translation.rb +1 -0
- data/lib/ripple.rb +22 -2
- data/ripple.gemspec +11 -12
- data/spec/ripple/associations/proxy_spec.rb +1 -1
- data/spec/ripple/attribute_methods_spec.rb +13 -1
- data/spec/ripple/callbacks_spec.rb +9 -0
- data/spec/ripple/core_ext_spec.rb +55 -4
- data/spec/ripple/finders_spec.rb +11 -9
- data/spec/ripple/observable_spec.rb +134 -0
- data/spec/ripple/persistence_spec.rb +23 -1
- data/spec/ripple/ripple_spec.rb +24 -5
- data/spec/ripple/validations_spec.rb +18 -10
- metadata +12 -41
data/Gemfile
CHANGED
@@ -1,16 +1,17 @@
|
|
1
|
-
source :
|
1
|
+
source :rubygems
|
2
2
|
|
3
3
|
gem 'bundler'
|
4
4
|
gem 'riak-client', :path => "../riak-client"
|
5
5
|
gem 'activemodel', '~>3.0.0'
|
6
|
-
gem 'rspec', '~>2.
|
6
|
+
gem 'rspec', '~>2.4.0'
|
7
7
|
gem 'tzinfo'
|
8
8
|
gem 'rake'
|
9
9
|
|
10
|
-
|
10
|
+
platforms :mri do
|
11
|
+
gem 'yajl-ruby'
|
12
|
+
end
|
13
|
+
|
14
|
+
platforms :jruby do
|
11
15
|
gem 'json'
|
12
16
|
gem 'jruby-openssl'
|
13
|
-
else
|
14
|
-
gem 'yajl-ruby'
|
15
|
-
gem 'curb', '>0.6'
|
16
17
|
end
|
data/Rakefile
CHANGED
@@ -11,7 +11,7 @@ gemspec = Gem::Specification.new do |gem|
|
|
11
11
|
gem.email = "sean@basho.com"
|
12
12
|
gem.homepage = "http://seancribbs.github.com/ripple"
|
13
13
|
gem.authors = ["Sean Cribbs"]
|
14
|
-
gem.add_development_dependency "rspec", "~>2.
|
14
|
+
gem.add_development_dependency "rspec", "~>2.4.0"
|
15
15
|
gem.add_dependency "riak-client", "~>#{version}"
|
16
16
|
gem.add_dependency "activesupport", "~>3.0.0"
|
17
17
|
gem.add_dependency "activemodel", "~>3.0.0"
|
@@ -23,10 +23,12 @@ gemspec = Gem::Specification.new do |gem|
|
|
23
23
|
lib/rails/generators/ripple/configuration/templates/ripple.yml
|
24
24
|
lib/rails/generators/ripple/js/js_generator.rb
|
25
25
|
lib/rails/generators/ripple/js/templates/js/contrib.js
|
26
|
+
lib/rails/generators/ripple/js/templates/js/iso8601.js
|
26
27
|
lib/rails/generators/ripple/js/templates/js/ripple.js
|
27
28
|
lib/rails/generators/ripple/model/model_generator.rb
|
28
|
-
lib/rails/generators/ripple/model/templates
|
29
29
|
lib/rails/generators/ripple/model/templates/model.rb
|
30
|
+
lib/rails/generators/ripple/observer/observer_generator.rb
|
31
|
+
lib/rails/generators/ripple/observer/templates/observer.rb
|
30
32
|
lib/rails/generators/ripple/test/templates/test_server.rb
|
31
33
|
lib/rails/generators/ripple/test/test_generator.rb
|
32
34
|
lib/rails/generators/ripple_generator.rb
|
@@ -60,9 +62,9 @@ gemspec = Gem::Specification.new do |gem|
|
|
60
62
|
lib/ripple/embedded_document.rb
|
61
63
|
lib/ripple/i18n.rb
|
62
64
|
lib/ripple/inspection.rb
|
63
|
-
lib/ripple/locale
|
64
65
|
lib/ripple/locale/en.yml
|
65
66
|
lib/ripple/nested_attributes.rb
|
67
|
+
lib/ripple/observable.rb
|
66
68
|
lib/ripple/properties.rb
|
67
69
|
lib/ripple/property_type_mismatch.rb
|
68
70
|
lib/ripple/railtie.rb
|
@@ -95,6 +97,7 @@ gemspec = Gem::Specification.new do |gem|
|
|
95
97
|
spec/ripple/finders_spec.rb
|
96
98
|
spec/ripple/inspection_spec.rb
|
97
99
|
spec/ripple/key_spec.rb
|
100
|
+
spec/ripple/observable_spec.rb
|
98
101
|
spec/ripple/persistence_spec.rb
|
99
102
|
spec/ripple/properties_spec.rb
|
100
103
|
spec/ripple/ripple_spec.rb
|
@@ -0,0 +1,76 @@
|
|
1
|
+
// Written by Paul Sowden, 2005
|
2
|
+
// http://delete.me.uk/2005/03/iso8601.html
|
3
|
+
// Released under the Academic Free License
|
4
|
+
|
5
|
+
Date.prototype.setISO8601 = function (string) {
|
6
|
+
var regexp = "([0-9]{4})(-([0-9]{2})(-([0-9]{2})" +
|
7
|
+
"(T([0-9]{2}):([0-9]{2})(:([0-9]{2})(\.([0-9]+))?)?" +
|
8
|
+
"(Z|(([-+])([0-9]{2}):([0-9]{2})))?)?)?)?";
|
9
|
+
var d = string.match(new RegExp(regexp));
|
10
|
+
|
11
|
+
var offset = 0;
|
12
|
+
var date = new Date(d[1], 0, 1);
|
13
|
+
|
14
|
+
if (d[3]) { date.setMonth(d[3] - 1); }
|
15
|
+
if (d[5]) { date.setDate(d[5]); }
|
16
|
+
if (d[7]) { date.setHours(d[7]); }
|
17
|
+
if (d[8]) { date.setMinutes(d[8]); }
|
18
|
+
if (d[10]) { date.setSeconds(d[10]); }
|
19
|
+
if (d[12]) { date.setMilliseconds(Number("0." + d[12]) * 1000); }
|
20
|
+
if (d[14]) {
|
21
|
+
offset = (Number(d[16]) * 60) + Number(d[17]);
|
22
|
+
offset *= ((d[15] == '-') ? 1 : -1);
|
23
|
+
}
|
24
|
+
|
25
|
+
offset -= date.getTimezoneOffset();
|
26
|
+
time = (Number(date) + (offset * 60 * 1000));
|
27
|
+
this.setTime(Number(time));
|
28
|
+
}
|
29
|
+
|
30
|
+
Date.prototype.iso8601 = function (format, offset) {
|
31
|
+
/* accepted values for the format [1-6]:
|
32
|
+
1 Year:
|
33
|
+
YYYY (eg 1997)
|
34
|
+
2 Year and month:
|
35
|
+
YYYY-MM (eg 1997-07)
|
36
|
+
3 Complete date:
|
37
|
+
YYYY-MM-DD (eg 1997-07-16)
|
38
|
+
4 Complete date plus hours and minutes:
|
39
|
+
YYYY-MM-DDThh:mmTZD (eg 1997-07-16T19:20+01:00)
|
40
|
+
5 Complete date plus hours, minutes and seconds:
|
41
|
+
YYYY-MM-DDThh:mm:ssTZD (eg 1997-07-16T19:20:30+01:00)
|
42
|
+
6 Complete date plus hours, minutes, seconds and a decimal
|
43
|
+
fraction of a second
|
44
|
+
YYYY-MM-DDThh:mm:ss.sTZD (eg 1997-07-16T19:20:30.45+01:00)
|
45
|
+
*/
|
46
|
+
if (!format) { var format = 6; }
|
47
|
+
if (!offset) {
|
48
|
+
var offset = 'Z';
|
49
|
+
var date = this;
|
50
|
+
} else {
|
51
|
+
var d = offset.match(/([-+])([0-9]{2}):([0-9]{2})/);
|
52
|
+
var offsetnum = (Number(d[2]) * 60) + Number(d[3]);
|
53
|
+
offsetnum *= ((d[1] == '-') ? -1 : 1);
|
54
|
+
var date = new Date(Number(Number(this) + (offsetnum * 60000)));
|
55
|
+
}
|
56
|
+
|
57
|
+
var zeropad = function (num) { return ((num < 10) ? '0' : '') + num; }
|
58
|
+
|
59
|
+
var str = "";
|
60
|
+
str += date.getUTCFullYear();
|
61
|
+
if (format > 1) { str += "-" + zeropad(date.getUTCMonth() + 1); }
|
62
|
+
if (format > 2) { str += "-" + zeropad(date.getUTCDate()); }
|
63
|
+
if (format > 3) {
|
64
|
+
str += "T" + zeropad(date.getUTCHours()) +
|
65
|
+
":" + zeropad(date.getUTCMinutes());
|
66
|
+
}
|
67
|
+
if (format > 5) {
|
68
|
+
var secs = Number(date.getUTCSeconds() + "." +
|
69
|
+
((date.getUTCMilliseconds() < 100) ? '0' : '') +
|
70
|
+
zeropad(date.getUTCMilliseconds()));
|
71
|
+
str += ":" + zeropad(secs);
|
72
|
+
} else if (format > 4) { str += ":" + zeropad(date.getUTCSeconds()); }
|
73
|
+
|
74
|
+
if (format > 3) { str += offset; }
|
75
|
+
return str;
|
76
|
+
}
|
@@ -0,0 +1,30 @@
|
|
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
|
+
|
15
|
+
require 'rails/generators/ripple_generator'
|
16
|
+
|
17
|
+
module Ripple
|
18
|
+
module Generators
|
19
|
+
class ObserverGenerator < NamedBase
|
20
|
+
desc 'Creates an observer for Ripple documents'
|
21
|
+
check_class_collision :suffix => "Observer"
|
22
|
+
|
23
|
+
def create_observer_file
|
24
|
+
template 'observer.rb', File.join("app/models", class_path, "#{file_name}_observer.rb")
|
25
|
+
end
|
26
|
+
|
27
|
+
hook_for :test_framework
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
@@ -8,7 +8,11 @@ module Ripple
|
|
8
8
|
def test_server_config
|
9
9
|
{
|
10
10
|
:app_config => {
|
11
|
-
:riak_kv => {
|
11
|
+
:riak_kv => {
|
12
|
+
:js_source_dir => Ripple.config.delete(:js_source_dir),
|
13
|
+
:map_cache_size => 0, # 0.14
|
14
|
+
:vnode_cache_entries => 0 # 0.13
|
15
|
+
},
|
12
16
|
:riak_core => { :web_port => Ripple.config[:port] || 8098 }
|
13
17
|
},
|
14
18
|
:bin_dir => Ripple.config.delete(:bin_dir),
|
@@ -33,6 +33,8 @@ module Ripple
|
|
33
33
|
include Query
|
34
34
|
include Dirty
|
35
35
|
include ActiveModel::MassAssignmentSecurity
|
36
|
+
|
37
|
+
attr_protected :key
|
36
38
|
end
|
37
39
|
|
38
40
|
module ClassMethods
|
@@ -55,17 +57,17 @@ module Ripple
|
|
55
57
|
# nor embedded documents.
|
56
58
|
# @return [Hash] all document attributes, by key
|
57
59
|
def attributes
|
58
|
-
self.class.properties.values.inject(
|
60
|
+
self.class.properties.values.inject(@attributes.with_indifferent_access) do |hash, prop|
|
59
61
|
hash[prop.key] = attribute(prop.key)
|
60
62
|
hash
|
61
|
-
end
|
63
|
+
end
|
62
64
|
end
|
63
65
|
|
64
66
|
# Mass assign the document's attributes.
|
65
67
|
# @param [Hash] attrs the attributes to assign
|
66
|
-
def attributes=(attrs)
|
68
|
+
def attributes=(attrs, guard_protected_attrs = true)
|
67
69
|
raise ArgumentError, t('attribute_hash') unless Hash === attrs
|
68
|
-
sanitize_for_mass_assignment(attrs).each do |k,v|
|
70
|
+
(guard_protected_attrs ? sanitize_for_mass_assignment(attrs) : attrs).each do |k,v|
|
69
71
|
next if k.to_sym == :key
|
70
72
|
if respond_to?("#{k}=")
|
71
73
|
__send__("#{k}=",v)
|
data/lib/ripple/callbacks.rb
CHANGED
@@ -97,7 +97,7 @@ FalseClass.module_eval(&boolean_cast)
|
|
97
97
|
# @private
|
98
98
|
class Time
|
99
99
|
def as_json(options={})
|
100
|
-
self.utc.
|
100
|
+
self.utc.send(Ripple.date_format)
|
101
101
|
end
|
102
102
|
|
103
103
|
def self.ripple_cast(value)
|
@@ -109,7 +109,7 @@ end
|
|
109
109
|
# @private
|
110
110
|
class Date
|
111
111
|
def as_json(options={})
|
112
|
-
self.to_s(
|
112
|
+
self.to_s(Ripple.date_format)
|
113
113
|
end
|
114
114
|
|
115
115
|
def self.ripple_cast(value)
|
@@ -121,7 +121,7 @@ end
|
|
121
121
|
# @private
|
122
122
|
class DateTime
|
123
123
|
def as_json(options={})
|
124
|
-
self.utc.to_s(
|
124
|
+
self.utc.to_s(Ripple.date_format)
|
125
125
|
end
|
126
126
|
|
127
127
|
def self.ripple_cast(value)
|
@@ -134,7 +134,7 @@ end
|
|
134
134
|
module ActiveSupport
|
135
135
|
class TimeWithZone
|
136
136
|
def as_json(options={})
|
137
|
-
self.utc.
|
137
|
+
self.utc.send(Ripple.date_format)
|
138
138
|
end
|
139
139
|
end
|
140
140
|
end
|
@@ -14,7 +14,7 @@
|
|
14
14
|
require 'ripple'
|
15
15
|
|
16
16
|
module Ripple
|
17
|
-
|
17
|
+
|
18
18
|
# Raised by <tt>find!</tt> when a document cannot be found with the given key.
|
19
19
|
# begin
|
20
20
|
# Example.find!('badkey')
|
@@ -34,7 +34,7 @@ module Ripple
|
|
34
34
|
end
|
35
35
|
end
|
36
36
|
end
|
37
|
-
|
37
|
+
|
38
38
|
module Document
|
39
39
|
module Finders
|
40
40
|
extend ActiveSupport::Concern
|
@@ -60,7 +60,7 @@ module Ripple
|
|
60
60
|
return find_one(args.first) if args.size == 1
|
61
61
|
args.map {|key| find_one(key) }
|
62
62
|
end
|
63
|
-
|
63
|
+
|
64
64
|
# Retrieve single or multiple documents from Riak
|
65
65
|
# but raise Ripple::DocumentNotFound if a key can
|
66
66
|
# not be found in the bucket.
|
@@ -69,15 +69,15 @@ module Ripple
|
|
69
69
|
raise DocumentNotFound.new(args, found) if !found || Array(found).include?(nil)
|
70
70
|
found
|
71
71
|
end
|
72
|
-
|
72
|
+
|
73
73
|
# Find the first object using the first key in the
|
74
|
-
# bucket's keys using find. You should not expect to
|
74
|
+
# bucket's keys using find. You should not expect to
|
75
75
|
# actually get the first object you added to the bucket.
|
76
76
|
# This is just a convenience method.
|
77
77
|
def first
|
78
78
|
find(bucket.keys.first)
|
79
79
|
end
|
80
|
-
|
80
|
+
|
81
81
|
# Find the first object using the first key in the
|
82
82
|
# bucket's keys using find!
|
83
83
|
def first!
|
@@ -112,15 +112,14 @@ module Ripple
|
|
112
112
|
def find_one(key)
|
113
113
|
instantiate(bucket.get(key, quorums.slice(:r)))
|
114
114
|
rescue Riak::FailedRequest => fr
|
115
|
-
|
116
|
-
raise fr
|
115
|
+
raise fr unless fr.not_found?
|
117
116
|
end
|
118
117
|
|
119
118
|
def instantiate(robject)
|
120
119
|
klass = robject.data['_type'].constantize rescue self
|
121
120
|
klass.new.tap do |doc|
|
122
121
|
doc.key = robject.key
|
123
|
-
robject.data.except("_type")
|
122
|
+
doc.__send__(:attributes=, robject.data.except("_type"), false) if robject.data
|
124
123
|
doc.instance_variable_set(:@new, false)
|
125
124
|
doc.instance_variable_set(:@robject, robject)
|
126
125
|
end
|
@@ -70,14 +70,16 @@ module Ripple
|
|
70
70
|
# Saves the document in Riak.
|
71
71
|
# @return [true,false] whether the document succeeded in saving
|
72
72
|
def save(*args)
|
73
|
+
really_save(*args)
|
74
|
+
end
|
75
|
+
|
76
|
+
def really_save(*args)
|
73
77
|
robject.key = key if robject.key != key
|
74
78
|
robject.data = attributes_for_persistence
|
75
79
|
robject.store(self.class.quorums.slice(:w,:dw))
|
76
80
|
self.key = robject.key
|
77
81
|
@new = false
|
78
82
|
true
|
79
|
-
rescue Riak::FailedRequest
|
80
|
-
false
|
81
83
|
end
|
82
84
|
|
83
85
|
# Reloads the document from Riak
|
@@ -85,7 +87,7 @@ module Ripple
|
|
85
87
|
def reload
|
86
88
|
return self if new?
|
87
89
|
robject.reload(:force => true)
|
88
|
-
@robject.data.except("_type")
|
90
|
+
self.__send__(:attributes=, @robject.data.except("_type"), false)
|
89
91
|
self
|
90
92
|
end
|
91
93
|
|
@@ -0,0 +1,39 @@
|
|
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 'ripple'
|
15
|
+
|
16
|
+
module Ripple
|
17
|
+
module Observable
|
18
|
+
extend ActiveSupport::Concern
|
19
|
+
include ActiveModel::Observing
|
20
|
+
|
21
|
+
included do
|
22
|
+
set_callback(:create, :before) { notify_observers :before_create }
|
23
|
+
set_callback(:create, :after) { notify_observers :after_create }
|
24
|
+
|
25
|
+
set_callback(:update, :before) { notify_observers :before_update }
|
26
|
+
set_callback(:update, :after) { notify_observers :after_update }
|
27
|
+
|
28
|
+
set_callback(:save, :before) { notify_observers :before_save }
|
29
|
+
set_callback(:save, :after) { notify_observers :after_save }
|
30
|
+
|
31
|
+
set_callback(:destroy, :before) { notify_observers :before_destroy }
|
32
|
+
set_callback(:destroy, :after) { notify_observers :after_destroy }
|
33
|
+
|
34
|
+
set_callback(:validation, :before) { notify_observers :before_validation }
|
35
|
+
set_callback(:validation, :after) { notify_observers :after_validation }
|
36
|
+
end
|
37
|
+
|
38
|
+
end
|
39
|
+
end
|
data/lib/ripple/translation.rb
CHANGED
data/lib/ripple.rb
CHANGED
@@ -18,6 +18,7 @@ require 'active_support/json'
|
|
18
18
|
require 'active_model'
|
19
19
|
require 'ripple/i18n'
|
20
20
|
require 'ripple/core_ext'
|
21
|
+
require 'ripple/translation'
|
21
22
|
|
22
23
|
# Contains the classes and modules related to the ODM built on top of
|
23
24
|
# the basic Riak client.
|
@@ -46,12 +47,11 @@ module Ripple
|
|
46
47
|
|
47
48
|
# Utilities
|
48
49
|
autoload :Inspection
|
49
|
-
autoload :Translation
|
50
50
|
|
51
51
|
class << self
|
52
52
|
# @return [Riak::Client] The client for the current thread.
|
53
53
|
def client
|
54
|
-
Thread.current[:ripple_client] ||= Riak::Client.new(
|
54
|
+
Thread.current[:ripple_client] ||= Riak::Client.new(client_config)
|
55
55
|
end
|
56
56
|
|
57
57
|
# Sets the client for the current thread.
|
@@ -71,6 +71,21 @@ module Ripple
|
|
71
71
|
@config ||= {}
|
72
72
|
end
|
73
73
|
|
74
|
+
# The format in which date/time objects will be serialized to
|
75
|
+
# strings in JSON. Defaults to :iso8601, and can be set in
|
76
|
+
# Ripple.config.
|
77
|
+
# @return [Symbol] the date format
|
78
|
+
def date_format
|
79
|
+
(config[:date_format] ||= :iso8601).to_sym
|
80
|
+
end
|
81
|
+
|
82
|
+
# Sets the format for date/time objects that are serialized to
|
83
|
+
# JSON.
|
84
|
+
# @param [Symbol] format the date format
|
85
|
+
def date_format=(format)
|
86
|
+
config[:date_format] = format.to_sym
|
87
|
+
end
|
88
|
+
|
74
89
|
# Loads the Ripple configuration from a given YAML file.
|
75
90
|
# Evaluates the configuration with ERB before loading.
|
76
91
|
def load_configuration(config_file, config_keys = [:ripple])
|
@@ -82,6 +97,11 @@ module Ripple
|
|
82
97
|
raise Ripple::MissingConfiguration.new(config_file)
|
83
98
|
end
|
84
99
|
alias_method :load_config, :load_configuration
|
100
|
+
|
101
|
+
private
|
102
|
+
def client_config
|
103
|
+
config.slice(:host, :port, :prefix, :mapred, :client_id, :http_backend, :solr)
|
104
|
+
end
|
85
105
|
end
|
86
106
|
|
87
107
|
# Exception raised when the path passed to
|
data/ripple.gemspec
CHANGED
@@ -2,38 +2,37 @@
|
|
2
2
|
|
3
3
|
Gem::Specification.new do |s|
|
4
4
|
s.name = %q{ripple}
|
5
|
-
s.version = "0.9.0.
|
5
|
+
s.version = "0.9.0.beta2"
|
6
6
|
|
7
7
|
s.required_rubygems_version = Gem::Requirement.new("> 1.3.1") if s.respond_to? :required_rubygems_version=
|
8
8
|
s.authors = ["Sean Cribbs"]
|
9
|
-
s.date = %q{
|
9
|
+
s.date = %q{2011-03-28}
|
10
10
|
s.description = %q{ripple is an object-mapper library for Riak, the distributed database by Basho. It uses ActiveModel to provide an experience that integrates well with Rails 3 applications.}
|
11
11
|
s.email = %q{sean@basho.com}
|
12
|
-
s.files = ["Gemfile", "lib/rails/generators/ripple/configuration/configuration_generator.rb", "lib/rails/generators/ripple/configuration/templates/ripple.yml", "lib/rails/generators/ripple/js/js_generator.rb", "lib/rails/generators/ripple/js/templates/js/contrib.js", "lib/rails/generators/ripple/js/templates/js/ripple.js", "lib/rails/generators/ripple/model/model_generator.rb", "lib/rails/generators/ripple/model/templates/model.rb", "lib/rails/generators/ripple/test/templates/test_server.rb", "lib/rails/generators/ripple/test/test_generator.rb", "lib/rails/generators/ripple_generator.rb", "lib/ripple/associations/embedded.rb", "lib/ripple/associations/instantiators.rb", "lib/ripple/associations/linked.rb", "lib/ripple/associations/many.rb", "lib/ripple/associations/many_embedded_proxy.rb", "lib/ripple/associations/many_linked_proxy.rb", "lib/ripple/associations/one.rb", "lib/ripple/associations/one_embedded_proxy.rb", "lib/ripple/associations/one_linked_proxy.rb", "lib/ripple/associations/proxy.rb", "lib/ripple/associations.rb", "lib/ripple/attribute_methods/dirty.rb", "lib/ripple/attribute_methods/query.rb", "lib/ripple/attribute_methods/read.rb", "lib/ripple/attribute_methods/write.rb", "lib/ripple/attribute_methods.rb", "lib/ripple/callbacks.rb", "lib/ripple/conversion.rb", "lib/ripple/core_ext/casting.rb", "lib/ripple/core_ext.rb", "lib/ripple/document/bucket_access.rb", "lib/ripple/document/finders.rb", "lib/ripple/document/key.rb", "lib/ripple/document/persistence.rb", "lib/ripple/document.rb", "lib/ripple/embedded_document/finders.rb", "lib/ripple/embedded_document/persistence.rb", "lib/ripple/embedded_document.rb", "lib/ripple/i18n.rb", "lib/ripple/inspection.rb", "lib/ripple/locale/en.yml", "lib/ripple/nested_attributes.rb", "lib/ripple/properties.rb", "lib/ripple/property_type_mismatch.rb", "lib/ripple/railtie.rb", "lib/ripple/timestamps.rb", "lib/ripple/translation.rb", "lib/ripple/validations/associated_validator.rb", "lib/ripple/validations.rb", "lib/ripple.rb", "Rakefile", "ripple.gemspec", "spec/fixtures/config.yml", "spec/integration/ripple/associations_spec.rb", "spec/integration/ripple/nested_attributes_spec.rb", "spec/integration/ripple/persistence_spec.rb", "spec/ripple/associations/many_embedded_proxy_spec.rb", "spec/ripple/associations/many_linked_proxy_spec.rb", "spec/ripple/associations/one_embedded_proxy_spec.rb", "spec/ripple/associations/one_linked_proxy_spec.rb", "spec/ripple/associations/proxy_spec.rb", "spec/ripple/associations_spec.rb", "spec/ripple/attribute_methods_spec.rb", "spec/ripple/bucket_access_spec.rb", "spec/ripple/callbacks_spec.rb", "spec/ripple/conversion_spec.rb", "spec/ripple/core_ext_spec.rb", "spec/ripple/document_spec.rb", "spec/ripple/embedded_document/finders_spec.rb", "spec/ripple/embedded_document/persistence_spec.rb", "spec/ripple/embedded_document_spec.rb", "spec/ripple/finders_spec.rb", "spec/ripple/inspection_spec.rb", "spec/ripple/key_spec.rb", "spec/ripple/persistence_spec.rb", "spec/ripple/properties_spec.rb", "spec/ripple/ripple_spec.rb", "spec/ripple/timestamps_spec.rb", "spec/ripple/validations_spec.rb", "spec/spec_helper.rb", "spec/support/associations/proxies.rb", "spec/support/mocks.rb", "spec/support/models/address.rb", "spec/support/models/box.rb", "spec/support/models/car.rb", "spec/support/models/cardboard_box.rb", "spec/support/models/clock.rb", "spec/support/models/customer.rb", "spec/support/models/driver.rb", "spec/support/models/email.rb", "spec/support/models/engine.rb", "spec/support/models/family.rb", "spec/support/models/favorite.rb", "spec/support/models/invoice.rb", "spec/support/models/late_invoice.rb", "spec/support/models/note.rb", "spec/support/models/page.rb", "spec/support/models/paid_invoice.rb", "spec/support/models/passenger.rb", "spec/support/models/seat.rb", "spec/support/models/tasks.rb", "spec/support/models/tree.rb", "spec/support/models/user.rb", "spec/support/models/wheel.rb", "spec/support/models/widget.rb", "spec/support/test_server.rb", "spec/support/test_server.yml.example"]
|
12
|
+
s.files = ["Gemfile", "lib/rails/generators/ripple/configuration/configuration_generator.rb", "lib/rails/generators/ripple/configuration/templates/ripple.yml", "lib/rails/generators/ripple/js/js_generator.rb", "lib/rails/generators/ripple/js/templates/js/contrib.js", "lib/rails/generators/ripple/js/templates/js/iso8601.js", "lib/rails/generators/ripple/js/templates/js/ripple.js", "lib/rails/generators/ripple/model/model_generator.rb", "lib/rails/generators/ripple/model/templates/model.rb", "lib/rails/generators/ripple/observer/observer_generator.rb", "lib/rails/generators/ripple/observer/templates/observer.rb", "lib/rails/generators/ripple/test/templates/test_server.rb", "lib/rails/generators/ripple/test/test_generator.rb", "lib/rails/generators/ripple_generator.rb", "lib/ripple/associations/embedded.rb", "lib/ripple/associations/instantiators.rb", "lib/ripple/associations/linked.rb", "lib/ripple/associations/many.rb", "lib/ripple/associations/many_embedded_proxy.rb", "lib/ripple/associations/many_linked_proxy.rb", "lib/ripple/associations/one.rb", "lib/ripple/associations/one_embedded_proxy.rb", "lib/ripple/associations/one_linked_proxy.rb", "lib/ripple/associations/proxy.rb", "lib/ripple/associations.rb", "lib/ripple/attribute_methods/dirty.rb", "lib/ripple/attribute_methods/query.rb", "lib/ripple/attribute_methods/read.rb", "lib/ripple/attribute_methods/write.rb", "lib/ripple/attribute_methods.rb", "lib/ripple/callbacks.rb", "lib/ripple/conversion.rb", "lib/ripple/core_ext/casting.rb", "lib/ripple/core_ext.rb", "lib/ripple/document/bucket_access.rb", "lib/ripple/document/finders.rb", "lib/ripple/document/key.rb", "lib/ripple/document/persistence.rb", "lib/ripple/document.rb", "lib/ripple/embedded_document/finders.rb", "lib/ripple/embedded_document/persistence.rb", "lib/ripple/embedded_document.rb", "lib/ripple/i18n.rb", "lib/ripple/inspection.rb", "lib/ripple/locale/en.yml", "lib/ripple/nested_attributes.rb", "lib/ripple/observable.rb", "lib/ripple/properties.rb", "lib/ripple/property_type_mismatch.rb", "lib/ripple/railtie.rb", "lib/ripple/timestamps.rb", "lib/ripple/translation.rb", "lib/ripple/validations/associated_validator.rb", "lib/ripple/validations.rb", "lib/ripple.rb", "Rakefile", "ripple.gemspec", "spec/fixtures/config.yml", "spec/integration/ripple/associations_spec.rb", "spec/integration/ripple/nested_attributes_spec.rb", "spec/integration/ripple/persistence_spec.rb", "spec/ripple/associations/many_embedded_proxy_spec.rb", "spec/ripple/associations/many_linked_proxy_spec.rb", "spec/ripple/associations/one_embedded_proxy_spec.rb", "spec/ripple/associations/one_linked_proxy_spec.rb", "spec/ripple/associations/proxy_spec.rb", "spec/ripple/associations_spec.rb", "spec/ripple/attribute_methods_spec.rb", "spec/ripple/bucket_access_spec.rb", "spec/ripple/callbacks_spec.rb", "spec/ripple/conversion_spec.rb", "spec/ripple/core_ext_spec.rb", "spec/ripple/document_spec.rb", "spec/ripple/embedded_document/finders_spec.rb", "spec/ripple/embedded_document/persistence_spec.rb", "spec/ripple/embedded_document_spec.rb", "spec/ripple/finders_spec.rb", "spec/ripple/inspection_spec.rb", "spec/ripple/key_spec.rb", "spec/ripple/observable_spec.rb", "spec/ripple/persistence_spec.rb", "spec/ripple/properties_spec.rb", "spec/ripple/ripple_spec.rb", "spec/ripple/timestamps_spec.rb", "spec/ripple/validations_spec.rb", "spec/spec_helper.rb", "spec/support/associations/proxies.rb", "spec/support/mocks.rb", "spec/support/models/address.rb", "spec/support/models/box.rb", "spec/support/models/car.rb", "spec/support/models/cardboard_box.rb", "spec/support/models/clock.rb", "spec/support/models/customer.rb", "spec/support/models/driver.rb", "spec/support/models/email.rb", "spec/support/models/engine.rb", "spec/support/models/family.rb", "spec/support/models/favorite.rb", "spec/support/models/invoice.rb", "spec/support/models/late_invoice.rb", "spec/support/models/note.rb", "spec/support/models/page.rb", "spec/support/models/paid_invoice.rb", "spec/support/models/passenger.rb", "spec/support/models/seat.rb", "spec/support/models/tasks.rb", "spec/support/models/tree.rb", "spec/support/models/user.rb", "spec/support/models/wheel.rb", "spec/support/models/widget.rb", "spec/support/test_server.rb", "spec/support/test_server.yml.example"]
|
13
13
|
s.homepage = %q{http://seancribbs.github.com/ripple}
|
14
14
|
s.require_paths = ["lib"]
|
15
|
-
s.rubygems_version = %q{1.
|
15
|
+
s.rubygems_version = %q{1.6.1}
|
16
16
|
s.summary = %q{ripple is an object-mapper library for Riak, the distributed database by Basho.}
|
17
|
-
s.test_files = ["spec/integration/ripple/associations_spec.rb", "spec/integration/ripple/nested_attributes_spec.rb", "spec/integration/ripple/persistence_spec.rb", "spec/ripple/associations/many_embedded_proxy_spec.rb", "spec/ripple/associations/many_linked_proxy_spec.rb", "spec/ripple/associations/one_embedded_proxy_spec.rb", "spec/ripple/associations/one_linked_proxy_spec.rb", "spec/ripple/associations/proxy_spec.rb", "spec/ripple/associations_spec.rb", "spec/ripple/attribute_methods_spec.rb", "spec/ripple/bucket_access_spec.rb", "spec/ripple/callbacks_spec.rb", "spec/ripple/conversion_spec.rb", "spec/ripple/core_ext_spec.rb", "spec/ripple/document_spec.rb", "spec/ripple/embedded_document/finders_spec.rb", "spec/ripple/embedded_document/persistence_spec.rb", "spec/ripple/embedded_document_spec.rb", "spec/ripple/finders_spec.rb", "spec/ripple/inspection_spec.rb", "spec/ripple/key_spec.rb", "spec/ripple/persistence_spec.rb", "spec/ripple/properties_spec.rb", "spec/ripple/ripple_spec.rb", "spec/ripple/timestamps_spec.rb", "spec/ripple/validations_spec.rb"]
|
17
|
+
s.test_files = ["spec/integration/ripple/associations_spec.rb", "spec/integration/ripple/nested_attributes_spec.rb", "spec/integration/ripple/persistence_spec.rb", "spec/ripple/associations/many_embedded_proxy_spec.rb", "spec/ripple/associations/many_linked_proxy_spec.rb", "spec/ripple/associations/one_embedded_proxy_spec.rb", "spec/ripple/associations/one_linked_proxy_spec.rb", "spec/ripple/associations/proxy_spec.rb", "spec/ripple/associations_spec.rb", "spec/ripple/attribute_methods_spec.rb", "spec/ripple/bucket_access_spec.rb", "spec/ripple/callbacks_spec.rb", "spec/ripple/conversion_spec.rb", "spec/ripple/core_ext_spec.rb", "spec/ripple/document_spec.rb", "spec/ripple/embedded_document/finders_spec.rb", "spec/ripple/embedded_document/persistence_spec.rb", "spec/ripple/embedded_document_spec.rb", "spec/ripple/finders_spec.rb", "spec/ripple/inspection_spec.rb", "spec/ripple/key_spec.rb", "spec/ripple/observable_spec.rb", "spec/ripple/persistence_spec.rb", "spec/ripple/properties_spec.rb", "spec/ripple/ripple_spec.rb", "spec/ripple/timestamps_spec.rb", "spec/ripple/validations_spec.rb"]
|
18
18
|
|
19
19
|
if s.respond_to? :specification_version then
|
20
|
-
current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
|
21
20
|
s.specification_version = 3
|
22
21
|
|
23
22
|
if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
|
24
|
-
s.add_development_dependency(%q<rspec>, ["~> 2.
|
25
|
-
s.add_runtime_dependency(%q<riak-client>, ["~> 0.9.0.
|
23
|
+
s.add_development_dependency(%q<rspec>, ["~> 2.4.0"])
|
24
|
+
s.add_runtime_dependency(%q<riak-client>, ["~> 0.9.0.beta2"])
|
26
25
|
s.add_runtime_dependency(%q<activesupport>, ["~> 3.0.0"])
|
27
26
|
s.add_runtime_dependency(%q<activemodel>, ["~> 3.0.0"])
|
28
27
|
else
|
29
|
-
s.add_dependency(%q<rspec>, ["~> 2.
|
30
|
-
s.add_dependency(%q<riak-client>, ["~> 0.9.0.
|
28
|
+
s.add_dependency(%q<rspec>, ["~> 2.4.0"])
|
29
|
+
s.add_dependency(%q<riak-client>, ["~> 0.9.0.beta2"])
|
31
30
|
s.add_dependency(%q<activesupport>, ["~> 3.0.0"])
|
32
31
|
s.add_dependency(%q<activemodel>, ["~> 3.0.0"])
|
33
32
|
end
|
34
33
|
else
|
35
|
-
s.add_dependency(%q<rspec>, ["~> 2.
|
36
|
-
s.add_dependency(%q<riak-client>, ["~> 0.9.0.
|
34
|
+
s.add_dependency(%q<rspec>, ["~> 2.4.0"])
|
35
|
+
s.add_dependency(%q<riak-client>, ["~> 0.9.0.beta2"])
|
37
36
|
s.add_dependency(%q<activesupport>, ["~> 3.0.0"])
|
38
37
|
s.add_dependency(%q<activemodel>, ["~> 3.0.0"])
|
39
38
|
end
|
@@ -185,8 +185,20 @@ describe Ripple::AttributeMethods do
|
|
185
185
|
lambda { @widget.attributes = nil }.should raise_error(ArgumentError)
|
186
186
|
end
|
187
187
|
|
188
|
-
it "should protect attributes from mass assignment" do
|
188
|
+
it "should protect attributes from mass assignment when initialized" do
|
189
189
|
@widget = Widget.new(:manufactured => true)
|
190
190
|
@widget.manufactured.should be_false
|
191
191
|
end
|
192
|
+
|
193
|
+
it "should protect attributes from mass assignment by default" do
|
194
|
+
@widget = Widget.new
|
195
|
+
@widget.attributes = { :manufactured => true }
|
196
|
+
@widget.manufactured.should be_false
|
197
|
+
end
|
198
|
+
|
199
|
+
it "should allow protected attributes to be mass assigned" do
|
200
|
+
@widget = Widget.new
|
201
|
+
@widget.send(:attributes=, { :manufactured => true }, false)
|
202
|
+
@widget.manufactured.should be_true
|
203
|
+
end
|
192
204
|
end
|
@@ -77,6 +77,15 @@ describe Ripple::Callbacks do
|
|
77
77
|
@box.destroy
|
78
78
|
end
|
79
79
|
|
80
|
+
it "should call save and validate callbacks in the correct order" do
|
81
|
+
Box.before_validation { $pinger.ping(:v) }
|
82
|
+
Box.before_save { $pinger.ping(:s) }
|
83
|
+
$pinger.should_receive(:ping).with(:v).ordered
|
84
|
+
$pinger.should_receive(:ping).with(:s).ordered
|
85
|
+
@box = Box.new
|
86
|
+
@box.save
|
87
|
+
end
|
88
|
+
|
80
89
|
describe "validation callbacks" do
|
81
90
|
it "should call validation callbacks" do
|
82
91
|
Box.before_validation { $pinger.ping }
|
@@ -14,35 +14,86 @@
|
|
14
14
|
require File.expand_path("../../spec_helper", __FILE__)
|
15
15
|
|
16
16
|
describe Time do
|
17
|
-
|
17
|
+
before { @date_format = Ripple.date_format }
|
18
|
+
after { Ripple.date_format = @date_format }
|
19
|
+
|
20
|
+
it "serializes to JSON in UTC, ISO 8601 format by default" do
|
21
|
+
Time.utc(2010,3,16,12).as_json.should == "2010-03-16T12:00:00Z"
|
22
|
+
end
|
23
|
+
|
24
|
+
it "serializes to JSON in UTC, RFC822 format when specified" do
|
25
|
+
Ripple.date_format = :rfc822
|
18
26
|
Time.utc(2010,3,16,12).as_json.should == "Tue, 16 Mar 2010 12:00:00 -0000"
|
19
27
|
end
|
20
28
|
end
|
21
29
|
|
22
30
|
describe Date do
|
23
|
-
|
31
|
+
before { @date_format = Ripple.date_format }
|
32
|
+
after { Ripple.date_format = @date_format }
|
33
|
+
|
34
|
+
it "serializes to JSON ISO 8601 format by default" do
|
35
|
+
Date.civil(2010,3,16).as_json.should == "2010-03-16"
|
36
|
+
end
|
37
|
+
|
38
|
+
it "serializes to JSON in UTC, RFC822 format when specified" do
|
39
|
+
Ripple.date_format = :rfc822
|
24
40
|
Date.civil(2010,3,16).as_json.should == "16 Mar 2010"
|
25
41
|
end
|
26
42
|
end
|
27
43
|
|
28
44
|
describe DateTime do
|
45
|
+
before { @date_format = Ripple.date_format }
|
46
|
+
after { Ripple.date_format = @date_format }
|
47
|
+
|
29
48
|
before :each do
|
30
49
|
Time.zone = :utc
|
31
50
|
end
|
32
51
|
|
33
|
-
it "serializes to JSON in UTC,
|
52
|
+
it "serializes to JSON in UTC, ISO 8601 format by default" do
|
53
|
+
DateTime.civil(2010,3,16,12).as_json.should == "2010-03-16T12:00:00+00:00"
|
54
|
+
end
|
55
|
+
|
56
|
+
it "serializes to JSON in UTC, RFC822 format when specified" do
|
57
|
+
Ripple.date_format = :rfc822
|
34
58
|
DateTime.civil(2010,3,16,12).as_json.should == "Tue, 16 Mar 2010 12:00:00 +0000"
|
35
59
|
end
|
36
60
|
end
|
37
61
|
|
38
62
|
describe ActiveSupport::TimeWithZone do
|
39
|
-
|
63
|
+
before { @date_format = Ripple.date_format }
|
64
|
+
after { Ripple.date_format = @date_format }
|
65
|
+
|
66
|
+
it "serializes to JSON in UTC, ISO 8601 format by default" do
|
67
|
+
time = Time.utc(2010,3,16,12)
|
68
|
+
zone = ActiveSupport::TimeZone['Alaska']
|
69
|
+
ActiveSupport::TimeWithZone.new(time, zone).as_json.should == "2010-03-16T12:00:00Z"
|
70
|
+
end
|
71
|
+
|
72
|
+
it "serializes to JSON in UTC, RFC822 format when specified" do
|
73
|
+
Ripple.date_format = :rfc822
|
40
74
|
time = Time.utc(2010,3,16,12)
|
41
75
|
zone = ActiveSupport::TimeZone['Alaska']
|
42
76
|
ActiveSupport::TimeWithZone.new(time, zone).as_json.should == "Tue, 16 Mar 2010 12:00:00 -0000"
|
43
77
|
end
|
44
78
|
end
|
45
79
|
|
80
|
+
describe String do
|
81
|
+
it "can parse RFC 822 and ISO 8601 times" do
|
82
|
+
'Tue, 16 Mar 2010 12:00:00 -0000'.to_time.should == Time.utc(2010,3,16,12)
|
83
|
+
'2010-03-16T12:00:00Z'.to_time.should == Time.utc(2010,3,16,12)
|
84
|
+
end
|
85
|
+
|
86
|
+
it "can parse RFC 822 and ISO 8601 dates" do
|
87
|
+
'16 Mar 2010'.to_date.should == Date.civil(2010,3,16)
|
88
|
+
'2010-3-16'.to_date.should == Date.civil(2010,3,16)
|
89
|
+
end
|
90
|
+
|
91
|
+
it "can parse RFC 822 and ISO 8601 datetimes" do
|
92
|
+
'Tue, 16 Mar 2010 12:00:00 +0000'.to_datetime.should == DateTime.civil(2010,3,16,12)
|
93
|
+
'2010-03-16T12:00:00+00:00'.to_datetime.should == DateTime.civil(2010,3,16,12)
|
94
|
+
end
|
95
|
+
end
|
96
|
+
|
46
97
|
describe "Boolean" do
|
47
98
|
it "should be available to properties on documents" do
|
48
99
|
lambda {
|
data/spec/ripple/finders_spec.rb
CHANGED
@@ -75,9 +75,11 @@ describe Ripple::Document::Finders do
|
|
75
75
|
lambda { Box.find!("square") }.should_not raise_error(Ripple::DocumentNotFound)
|
76
76
|
end
|
77
77
|
|
78
|
-
it "should
|
79
|
-
@plain.raw_data = '{"non_existent_property":"
|
80
|
-
|
78
|
+
it "should put properties we don't know about into the attributes" do
|
79
|
+
@plain.raw_data = '{"non_existent_property":"some_value"}'
|
80
|
+
box = Box.find("square")
|
81
|
+
box[:non_existent_property].should == "some_value"
|
82
|
+
box.should_not respond_to(:non_existent_property)
|
81
83
|
end
|
82
84
|
|
83
85
|
it "should return the document when calling find!" do
|
@@ -86,18 +88,18 @@ describe Ripple::Document::Finders do
|
|
86
88
|
end
|
87
89
|
|
88
90
|
it "should return nil when no object exists at that key" do
|
89
|
-
@bucket.should_receive(:get).with("square", {}).and_raise(Riak::
|
91
|
+
@bucket.should_receive(:get).with("square", {}).and_raise(Riak::HTTPFailedRequest.new(:get, 200, 404, {}, "404 not found"))
|
90
92
|
box = Box.find("square")
|
91
93
|
box.should be_nil
|
92
94
|
end
|
93
95
|
|
94
96
|
it "should raise DocumentNotFound when using find! if no object exists at that key" do
|
95
|
-
@bucket.should_receive(:get).with("square", {}).and_raise(Riak::
|
97
|
+
@bucket.should_receive(:get).with("square", {}).and_raise(Riak::HTTPFailedRequest.new(:get, 200, 404, {}, "404 not found"))
|
96
98
|
lambda { Box.find!("square") }.should raise_error(Ripple::DocumentNotFound, "Couldn't find document with key: square")
|
97
99
|
end
|
98
100
|
|
99
101
|
it "should re-raise the failed request exception if not a 404" do
|
100
|
-
@bucket.should_receive(:get).with("square", {}).and_raise(Riak::
|
102
|
+
@bucket.should_receive(:get).with("square", {}).and_raise(Riak::HTTPFailedRequest.new(:get, 200, 500, {}, "500 internal server error"))
|
101
103
|
lambda { Box.find("square") }.should raise_error(Riak::FailedRequest)
|
102
104
|
end
|
103
105
|
|
@@ -123,7 +125,7 @@ describe Ripple::Document::Finders do
|
|
123
125
|
describe "when using find with missing keys" do
|
124
126
|
before :each do
|
125
127
|
@bucket.should_receive(:get).with("square", {}).and_return(@plain)
|
126
|
-
@bucket.should_receive(:get).with("rectangle", {}).and_raise(Riak::
|
128
|
+
@bucket.should_receive(:get).with("rectangle", {}).and_raise(Riak::HTTPFailedRequest.new(:get, 200, 404, {}, "404 not found"))
|
127
129
|
end
|
128
130
|
|
129
131
|
it "should return nil for documents that no longer exist" do
|
@@ -153,7 +155,7 @@ describe Ripple::Document::Finders do
|
|
153
155
|
it "should exclude objects that are not found" do
|
154
156
|
@bucket.should_receive(:keys).and_return(["square", "rectangle"])
|
155
157
|
@bucket.should_receive(:get).with("square", {}).and_return(@plain)
|
156
|
-
@bucket.should_receive(:get).with("rectangle", {}).and_raise(Riak::
|
158
|
+
@bucket.should_receive(:get).with("rectangle", {}).and_raise(Riak::HTTPFailedRequest.new(:get, 200, 404, {}, "404 not found"))
|
157
159
|
boxes = Box.all
|
158
160
|
boxes.should have(1).item
|
159
161
|
boxes.first.shape.should == "square"
|
@@ -162,7 +164,7 @@ describe Ripple::Document::Finders do
|
|
162
164
|
it "should yield found objects to the passed block, excluding missing objects, and return an empty array" do
|
163
165
|
@bucket.should_receive(:keys).and_yield(["square"]).and_yield(["rectangle"])
|
164
166
|
@bucket.should_receive(:get).with("square", {}).and_return(@plain)
|
165
|
-
@bucket.should_receive(:get).with("rectangle", {}).and_raise(Riak::
|
167
|
+
@bucket.should_receive(:get).with("rectangle", {}).and_raise(Riak::HTTPFailedRequest.new(:get, 200, 404, {}, "404 not found"))
|
166
168
|
@block = mock()
|
167
169
|
@block.should_receive(:ping).once
|
168
170
|
Box.all do |box|
|
@@ -0,0 +1,134 @@
|
|
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::Observable do
|
17
|
+
require 'support/models/clock'
|
18
|
+
require 'support/models/clock_observer'
|
19
|
+
|
20
|
+
before :each do
|
21
|
+
@client = Ripple.client
|
22
|
+
@backend = mock("Backend", :store_object => true)
|
23
|
+
@client.stub!(:backend).and_return(@backend)
|
24
|
+
@clock = Clock.new
|
25
|
+
@observer = ClockObserver.instance
|
26
|
+
end
|
27
|
+
|
28
|
+
context "given a document is created" do
|
29
|
+
it "should notify all observers twice" do
|
30
|
+
Clock.should_receive(:notify_observers).exactly(6).times
|
31
|
+
@clock.save
|
32
|
+
end
|
33
|
+
|
34
|
+
context "before creating the document" do
|
35
|
+
it "should call Observer#before_create" do
|
36
|
+
@observer.should_receive(:before_create)
|
37
|
+
@clock.save
|
38
|
+
end
|
39
|
+
|
40
|
+
it "should call Observer#before_save" do
|
41
|
+
@observer.should_receive(:before_save)
|
42
|
+
@clock.save
|
43
|
+
end
|
44
|
+
|
45
|
+
it "should call Observer#before_validation" do
|
46
|
+
@observer.should_receive(:before_validation)
|
47
|
+
@clock.save
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
context "after creating the document" do
|
52
|
+
it "should call Observer#after_create" do
|
53
|
+
@observer.should_receive(:after_create)
|
54
|
+
@clock.save
|
55
|
+
end
|
56
|
+
|
57
|
+
it "should call Observer#after_save" do
|
58
|
+
@observer.should_receive(:after_save)
|
59
|
+
@clock.save
|
60
|
+
end
|
61
|
+
|
62
|
+
it "should call Observer#after_validation" do
|
63
|
+
@observer.should_receive(:after_validation)
|
64
|
+
@clock.save
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
context "given a document is updated" do
|
70
|
+
before(:each) do
|
71
|
+
@clock.stub!(:new?).and_return(false)
|
72
|
+
end
|
73
|
+
|
74
|
+
it "should notify all observers twice" do
|
75
|
+
Clock.should_receive(:notify_observers).exactly(6).times
|
76
|
+
@clock.save
|
77
|
+
end
|
78
|
+
|
79
|
+
context "before updating the document" do
|
80
|
+
it "should call Observer#before_update" do
|
81
|
+
@observer.should_receive(:before_update)
|
82
|
+
@clock.save
|
83
|
+
end
|
84
|
+
|
85
|
+
it "should call Observer#before_save" do
|
86
|
+
@observer.should_receive(:before_save)
|
87
|
+
@clock.save
|
88
|
+
end
|
89
|
+
|
90
|
+
it "should call Observer#before_validation" do
|
91
|
+
@observer.should_receive(:before_validation)
|
92
|
+
@clock.save
|
93
|
+
end
|
94
|
+
end
|
95
|
+
|
96
|
+
context "after updating the document" do
|
97
|
+
it "should call Observer#after_update" do
|
98
|
+
@observer.should_receive(:after_update)
|
99
|
+
@clock.save
|
100
|
+
end
|
101
|
+
|
102
|
+
it "should call Observer#after_save" do
|
103
|
+
@observer.should_receive(:after_save)
|
104
|
+
@clock.save
|
105
|
+
end
|
106
|
+
|
107
|
+
it "should call Observer#after_validation" do
|
108
|
+
@observer.should_receive(:after_validation)
|
109
|
+
@clock.save
|
110
|
+
end
|
111
|
+
end
|
112
|
+
end
|
113
|
+
|
114
|
+
context "given a document is destroyed" do
|
115
|
+
it "should notify all observers twice" do
|
116
|
+
Clock.should_receive(:notify_observers).twice
|
117
|
+
@clock.destroy
|
118
|
+
end
|
119
|
+
|
120
|
+
context "before destroying the document" do
|
121
|
+
it "should call Observer#before_destroy" do
|
122
|
+
@observer.should_receive(:before_destroy)
|
123
|
+
@clock.destroy
|
124
|
+
end
|
125
|
+
end
|
126
|
+
|
127
|
+
context "after destroy the document" do
|
128
|
+
it "should call Observer#after_destroy" do
|
129
|
+
@observer.should_receive(:after_destroy)
|
130
|
+
@clock.destroy
|
131
|
+
end
|
132
|
+
end
|
133
|
+
end
|
134
|
+
end
|
@@ -68,7 +68,7 @@ describe Ripple::Document::Persistence do
|
|
68
68
|
end
|
69
69
|
|
70
70
|
it "should instantiate and save a new object to riak" do
|
71
|
-
json = @widget.attributes.merge(:size => 10, :shipped_at => "
|
71
|
+
json = @widget.attributes.merge(:size => 10, :shipped_at => "2000-01-01T20:15:01Z", :_type => 'Widget').to_json
|
72
72
|
@backend.should_receive(:store_object) do |obj, _, _, _|
|
73
73
|
obj.raw_data.should == json
|
74
74
|
obj.key.should be_nil
|
@@ -96,6 +96,28 @@ describe Ripple::Document::Persistence do
|
|
96
96
|
@widget.should_not be_a_new_record
|
97
97
|
end
|
98
98
|
|
99
|
+
it "should save the attributes not having a corresponding property" do
|
100
|
+
attrs = @widget.attributes.merge("_type" => "Widget", "unknown_property" => "a_value")
|
101
|
+
@backend.should_receive(:store_object) do |obj, _, _, _|
|
102
|
+
obj.data.should == attrs
|
103
|
+
obj.key.should be_nil
|
104
|
+
# Simulate loading the response with the key
|
105
|
+
obj.key = "new_widget"
|
106
|
+
end
|
107
|
+
@widget["unknown_property"] = "a_value"
|
108
|
+
@widget.save
|
109
|
+
@widget.key.should == "new_widget"
|
110
|
+
@widget.should_not be_a_new_record
|
111
|
+
@widget.changes.should be_blank
|
112
|
+
end
|
113
|
+
|
114
|
+
it "should allow unexpected exceptions to be raised" do
|
115
|
+
robject = mock("robject", :key => @widget.key, "data=" => true)
|
116
|
+
robject.should_receive(:store).and_raise(Riak::HTTPFailedRequest.new(:post, 200, 404, {}, "404 not found"))
|
117
|
+
@widget.stub!(:robject).and_return(robject)
|
118
|
+
lambda { @widget.save }.should raise_error(Riak::FailedRequest)
|
119
|
+
end
|
120
|
+
|
99
121
|
it "should reload a saved object" do
|
100
122
|
json = @widget.attributes.merge(:_type => "Widget").to_json
|
101
123
|
@backend.should_receive(:store_object) do |obj, _, _, _|
|
data/spec/ripple/ripple_spec.rb
CHANGED
@@ -34,32 +34,51 @@ describe Ripple do
|
|
34
34
|
Ripple.client = client
|
35
35
|
Ripple.client.should == client
|
36
36
|
end
|
37
|
-
|
37
|
+
|
38
38
|
it "should reset the client when the configuration changes" do
|
39
39
|
c = Ripple.client
|
40
40
|
Ripple.config = {:port => 9000}
|
41
41
|
Ripple.client.should_not == c
|
42
42
|
Ripple.client.port.should == 9000
|
43
43
|
end
|
44
|
-
|
44
|
+
|
45
45
|
it "should raise No Such File or Directory when given a bad configuration file" do
|
46
46
|
lambda { Ripple.load_config('not-here') }.should raise_error(Ripple::MissingConfiguration)
|
47
47
|
end
|
48
|
-
|
48
|
+
|
49
49
|
it "should pass an empty hash into configure if the configuration file is missing the key" do
|
50
50
|
Ripple.should_receive(:config=).with({})
|
51
51
|
Ripple.load_config(File.join(File.dirname(__FILE__), '..', 'fixtures', 'config.yml'), [:ripple, 'not-here'])
|
52
52
|
end
|
53
|
-
|
53
|
+
|
54
54
|
it "should select the configuration hash from the config keys provided" do
|
55
55
|
Ripple.load_config(File.join(File.dirname(__FILE__), '..', 'fixtures', 'config.yml'), ['ripple_rails', 'development'])
|
56
56
|
Ripple.client.port.should == 9001
|
57
57
|
Ripple.client.host.should == '127.0.0.1'
|
58
58
|
end
|
59
|
-
|
59
|
+
|
60
60
|
it "should apply the configuration under the ripple key" do
|
61
61
|
Ripple.load_config(File.join(File.dirname(__FILE__), '..', 'fixtures', 'config.yml'))
|
62
62
|
Ripple.client.port.should == 9000
|
63
63
|
Ripple.client.host.should == 'localhost'
|
64
64
|
end
|
65
|
+
|
66
|
+
describe "date format" do
|
67
|
+
before { @date_format = Ripple.date_format }
|
68
|
+
after { Ripple.date_format = @date_format }
|
69
|
+
|
70
|
+
it "should default to :iso8601" do
|
71
|
+
Ripple.date_format.should == :iso8601
|
72
|
+
end
|
73
|
+
|
74
|
+
it "should allow setting via the config" do
|
75
|
+
Ripple.config = {"date_format" => "rfc822"}
|
76
|
+
Ripple.date_format.should == :rfc822
|
77
|
+
end
|
78
|
+
|
79
|
+
it "should allow setting manually" do
|
80
|
+
Ripple.date_format = "rfc822"
|
81
|
+
Ripple.date_format.should == :rfc822
|
82
|
+
end
|
83
|
+
end
|
65
84
|
end
|
@@ -41,20 +41,20 @@ describe Ripple::Validations do
|
|
41
41
|
@box.should_receive(:valid?).and_return(false)
|
42
42
|
@box.save.should be_false
|
43
43
|
end
|
44
|
-
|
44
|
+
|
45
45
|
it "should allow skipping validations by passing save :validate => false" do
|
46
46
|
Ripple.client.http.stub!(:perform).and_return(mock_response)
|
47
47
|
@box.should_not_receive(:valid?)
|
48
48
|
@box.save(:validate => false).should be_true
|
49
49
|
end
|
50
|
-
|
50
|
+
|
51
51
|
describe "when using save! on an invalid record" do
|
52
52
|
before(:each) { @box.stub!(:valid?).and_return(false) }
|
53
|
-
|
53
|
+
|
54
54
|
it "should raise DocumentInvalid" do
|
55
55
|
lambda { @box.save! }.should raise_error(Ripple::DocumentInvalid)
|
56
56
|
end
|
57
|
-
|
57
|
+
|
58
58
|
it "should raise an exception that has the invalid document" do
|
59
59
|
begin
|
60
60
|
@box.save!
|
@@ -63,26 +63,34 @@ describe Ripple::Validations do
|
|
63
63
|
end
|
64
64
|
end
|
65
65
|
end
|
66
|
-
|
66
|
+
|
67
67
|
it "should not raise an error when save! is called and the document is valid" do
|
68
68
|
@box.stub!(:save).and_return(true)
|
69
69
|
@box.stub!(:valid?).and_return(true)
|
70
70
|
lambda { @box.save! }.should_not raise_error(Ripple::DocumentInvalid)
|
71
71
|
end
|
72
|
-
|
72
|
+
|
73
73
|
it "should return true from save! when no exception is raised" do
|
74
74
|
@box.stub!(:save).and_return(true)
|
75
75
|
@box.stub!(:valid?).and_return(true)
|
76
76
|
@box.save!.should be_true
|
77
77
|
end
|
78
|
-
|
78
|
+
|
79
|
+
it "should allow unexpected exceptions to be raised" do
|
80
|
+
robject = mock("robject", :key => @box.key, "data=" => true)
|
81
|
+
robject.should_receive(:store).and_raise(Riak::HTTPFailedRequest.new(:post, 200, 404, {}, "404 not found"))
|
82
|
+
@box.stub!(:robject).and_return(robject)
|
83
|
+
@box.stub!(:valid?).and_return(true)
|
84
|
+
lambda { @box.save! }.should raise_error(Riak::FailedRequest)
|
85
|
+
end
|
86
|
+
|
79
87
|
it "should not raise an error when creating a box with create! succeeds" do
|
80
88
|
@box.stub!(:new?).and_return(false)
|
81
89
|
Box.stub(:create).and_return(@box)
|
82
90
|
lambda { @new_box = Box.create! }.should_not raise_error(Ripple::DocumentInvalid)
|
83
91
|
@new_box.should == @box
|
84
92
|
end
|
85
|
-
|
93
|
+
|
86
94
|
it "should raise an error when creating a box with create! fails" do
|
87
95
|
@box.stub!(:new?).and_return(true)
|
88
96
|
Box.stub(:create).and_return(@box)
|
@@ -102,8 +110,8 @@ describe Ripple::Validations do
|
|
102
110
|
@box.should be_valid
|
103
111
|
Box.properties.delete :size
|
104
112
|
end
|
105
|
-
|
113
|
+
|
106
114
|
after :each do
|
107
115
|
Box.reset_callbacks(:validate)
|
108
|
-
end
|
116
|
+
end
|
109
117
|
end
|
metadata
CHANGED
@@ -1,14 +1,8 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: ripple
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
|
5
|
-
|
6
|
-
segments:
|
7
|
-
- 0
|
8
|
-
- 9
|
9
|
-
- 0
|
10
|
-
- beta
|
11
|
-
version: 0.9.0.beta
|
4
|
+
prerelease: 6
|
5
|
+
version: 0.9.0.beta2
|
12
6
|
platform: ruby
|
13
7
|
authors:
|
14
8
|
- Sean Cribbs
|
@@ -16,7 +10,7 @@ autorequire:
|
|
16
10
|
bindir: bin
|
17
11
|
cert_chain: []
|
18
12
|
|
19
|
-
date:
|
13
|
+
date: 2011-03-28 00:00:00 -04:00
|
20
14
|
default_executable:
|
21
15
|
dependencies:
|
22
16
|
- !ruby/object:Gem::Dependency
|
@@ -27,12 +21,7 @@ dependencies:
|
|
27
21
|
requirements:
|
28
22
|
- - ~>
|
29
23
|
- !ruby/object:Gem::Version
|
30
|
-
|
31
|
-
segments:
|
32
|
-
- 2
|
33
|
-
- 0
|
34
|
-
- 0
|
35
|
-
version: 2.0.0
|
24
|
+
version: 2.4.0
|
36
25
|
type: :development
|
37
26
|
version_requirements: *id001
|
38
27
|
- !ruby/object:Gem::Dependency
|
@@ -43,13 +32,7 @@ dependencies:
|
|
43
32
|
requirements:
|
44
33
|
- - ~>
|
45
34
|
- !ruby/object:Gem::Version
|
46
|
-
|
47
|
-
segments:
|
48
|
-
- 0
|
49
|
-
- 9
|
50
|
-
- 0
|
51
|
-
- beta
|
52
|
-
version: 0.9.0.beta
|
35
|
+
version: 0.9.0.beta2
|
53
36
|
type: :runtime
|
54
37
|
version_requirements: *id002
|
55
38
|
- !ruby/object:Gem::Dependency
|
@@ -60,11 +43,6 @@ dependencies:
|
|
60
43
|
requirements:
|
61
44
|
- - ~>
|
62
45
|
- !ruby/object:Gem::Version
|
63
|
-
hash: 7
|
64
|
-
segments:
|
65
|
-
- 3
|
66
|
-
- 0
|
67
|
-
- 0
|
68
46
|
version: 3.0.0
|
69
47
|
type: :runtime
|
70
48
|
version_requirements: *id003
|
@@ -76,11 +54,6 @@ dependencies:
|
|
76
54
|
requirements:
|
77
55
|
- - ~>
|
78
56
|
- !ruby/object:Gem::Version
|
79
|
-
hash: 7
|
80
|
-
segments:
|
81
|
-
- 3
|
82
|
-
- 0
|
83
|
-
- 0
|
84
57
|
version: 3.0.0
|
85
58
|
type: :runtime
|
86
59
|
version_requirements: *id004
|
@@ -98,9 +71,12 @@ files:
|
|
98
71
|
- lib/rails/generators/ripple/configuration/templates/ripple.yml
|
99
72
|
- lib/rails/generators/ripple/js/js_generator.rb
|
100
73
|
- lib/rails/generators/ripple/js/templates/js/contrib.js
|
74
|
+
- lib/rails/generators/ripple/js/templates/js/iso8601.js
|
101
75
|
- lib/rails/generators/ripple/js/templates/js/ripple.js
|
102
76
|
- lib/rails/generators/ripple/model/model_generator.rb
|
103
77
|
- lib/rails/generators/ripple/model/templates/model.rb
|
78
|
+
- lib/rails/generators/ripple/observer/observer_generator.rb
|
79
|
+
- lib/rails/generators/ripple/observer/templates/observer.rb
|
104
80
|
- lib/rails/generators/ripple/test/templates/test_server.rb
|
105
81
|
- lib/rails/generators/ripple/test/test_generator.rb
|
106
82
|
- lib/rails/generators/ripple_generator.rb
|
@@ -136,6 +112,7 @@ files:
|
|
136
112
|
- lib/ripple/inspection.rb
|
137
113
|
- lib/ripple/locale/en.yml
|
138
114
|
- lib/ripple/nested_attributes.rb
|
115
|
+
- lib/ripple/observable.rb
|
139
116
|
- lib/ripple/properties.rb
|
140
117
|
- lib/ripple/property_type_mismatch.rb
|
141
118
|
- lib/ripple/railtie.rb
|
@@ -168,6 +145,7 @@ files:
|
|
168
145
|
- spec/ripple/finders_spec.rb
|
169
146
|
- spec/ripple/inspection_spec.rb
|
170
147
|
- spec/ripple/key_spec.rb
|
148
|
+
- spec/ripple/observable_spec.rb
|
171
149
|
- spec/ripple/persistence_spec.rb
|
172
150
|
- spec/ripple/properties_spec.rb
|
173
151
|
- spec/ripple/ripple_spec.rb
|
@@ -215,25 +193,17 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
215
193
|
requirements:
|
216
194
|
- - ">="
|
217
195
|
- !ruby/object:Gem::Version
|
218
|
-
hash: 3
|
219
|
-
segments:
|
220
|
-
- 0
|
221
196
|
version: "0"
|
222
197
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
223
198
|
none: false
|
224
199
|
requirements:
|
225
200
|
- - ">"
|
226
201
|
- !ruby/object:Gem::Version
|
227
|
-
hash: 25
|
228
|
-
segments:
|
229
|
-
- 1
|
230
|
-
- 3
|
231
|
-
- 1
|
232
202
|
version: 1.3.1
|
233
203
|
requirements: []
|
234
204
|
|
235
205
|
rubyforge_project:
|
236
|
-
rubygems_version: 1.
|
206
|
+
rubygems_version: 1.6.1
|
237
207
|
signing_key:
|
238
208
|
specification_version: 3
|
239
209
|
summary: ripple is an object-mapper library for Riak, the distributed database by Basho.
|
@@ -259,6 +229,7 @@ test_files:
|
|
259
229
|
- spec/ripple/finders_spec.rb
|
260
230
|
- spec/ripple/inspection_spec.rb
|
261
231
|
- spec/ripple/key_spec.rb
|
232
|
+
- spec/ripple/observable_spec.rb
|
262
233
|
- spec/ripple/persistence_spec.rb
|
263
234
|
- spec/ripple/properties_spec.rb
|
264
235
|
- spec/ripple/ripple_spec.rb
|