ripple 0.9.0.beta → 0.9.0.beta2
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/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
|