ripple 0.9.0.beta2 → 0.9.0

Sign up to get free protection for your applications and to get access to all the features.
data/Gemfile CHANGED
@@ -11,6 +11,14 @@ platforms :mri do
11
11
  gem 'yajl-ruby'
12
12
  end
13
13
 
14
+ platforms :mri_18, :jruby do
15
+ gem 'ruby-debug'
16
+ end
17
+
18
+ platforms :mri_19 do
19
+ gem 'ruby-debug19'
20
+ end
21
+
14
22
  platforms :jruby do
15
23
  gem 'json'
16
24
  gem 'jruby-openssl'
data/Rakefile CHANGED
@@ -16,122 +16,17 @@ gemspec = Gem::Specification.new do |gem|
16
16
  gem.add_dependency "activesupport", "~>3.0.0"
17
17
  gem.add_dependency "activemodel", "~>3.0.0"
18
18
 
19
- gem.files = %W{
20
- Gemfile
21
- lib/rails/generators/ripple/configuration/configuration_generator.rb
22
- lib/rails/generators/ripple/configuration/templates
23
- lib/rails/generators/ripple/configuration/templates/ripple.yml
24
- lib/rails/generators/ripple/js/js_generator.rb
25
- lib/rails/generators/ripple/js/templates/js/contrib.js
26
- lib/rails/generators/ripple/js/templates/js/iso8601.js
27
- lib/rails/generators/ripple/js/templates/js/ripple.js
28
- lib/rails/generators/ripple/model/model_generator.rb
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
32
- lib/rails/generators/ripple/test/templates/test_server.rb
33
- lib/rails/generators/ripple/test/test_generator.rb
34
- lib/rails/generators/ripple_generator.rb
35
- lib/ripple/associations/embedded.rb
36
- lib/ripple/associations/instantiators.rb
37
- lib/ripple/associations/linked.rb
38
- lib/ripple/associations/many.rb
39
- lib/ripple/associations/many_embedded_proxy.rb
40
- lib/ripple/associations/many_linked_proxy.rb
41
- lib/ripple/associations/one.rb
42
- lib/ripple/associations/one_embedded_proxy.rb
43
- lib/ripple/associations/one_linked_proxy.rb
44
- lib/ripple/associations/proxy.rb
45
- lib/ripple/associations.rb
46
- lib/ripple/attribute_methods/dirty.rb
47
- lib/ripple/attribute_methods/query.rb
48
- lib/ripple/attribute_methods/read.rb
49
- lib/ripple/attribute_methods/write.rb
50
- lib/ripple/attribute_methods.rb
51
- lib/ripple/callbacks.rb
52
- lib/ripple/conversion.rb
53
- lib/ripple/core_ext/casting.rb
54
- lib/ripple/core_ext.rb
55
- lib/ripple/document/bucket_access.rb
56
- lib/ripple/document/finders.rb
57
- lib/ripple/document/key.rb
58
- lib/ripple/document/persistence.rb
59
- lib/ripple/document.rb
60
- lib/ripple/embedded_document/finders.rb
61
- lib/ripple/embedded_document/persistence.rb
62
- lib/ripple/embedded_document.rb
63
- lib/ripple/i18n.rb
64
- lib/ripple/inspection.rb
65
- lib/ripple/locale/en.yml
66
- lib/ripple/nested_attributes.rb
67
- lib/ripple/observable.rb
68
- lib/ripple/properties.rb
69
- lib/ripple/property_type_mismatch.rb
70
- lib/ripple/railtie.rb
71
- lib/ripple/timestamps.rb
72
- lib/ripple/translation.rb
73
- lib/ripple/validations/associated_validator.rb
74
- lib/ripple/validations.rb
75
- lib/ripple.rb
76
- Rakefile
77
- ripple.gemspec
78
- spec/fixtures/config.yml
79
- spec/integration/ripple/associations_spec.rb
80
- spec/integration/ripple/nested_attributes_spec.rb
81
- spec/integration/ripple/persistence_spec.rb
82
- spec/ripple/associations/many_embedded_proxy_spec.rb
83
- spec/ripple/associations/many_linked_proxy_spec.rb
84
- spec/ripple/associations/one_embedded_proxy_spec.rb
85
- spec/ripple/associations/one_linked_proxy_spec.rb
86
- spec/ripple/associations/proxy_spec.rb
87
- spec/ripple/associations_spec.rb
88
- spec/ripple/attribute_methods_spec.rb
89
- spec/ripple/bucket_access_spec.rb
90
- spec/ripple/callbacks_spec.rb
91
- spec/ripple/conversion_spec.rb
92
- spec/ripple/core_ext_spec.rb
93
- spec/ripple/document_spec.rb
94
- spec/ripple/embedded_document/finders_spec.rb
95
- spec/ripple/embedded_document/persistence_spec.rb
96
- spec/ripple/embedded_document_spec.rb
97
- spec/ripple/finders_spec.rb
98
- spec/ripple/inspection_spec.rb
99
- spec/ripple/key_spec.rb
100
- spec/ripple/observable_spec.rb
101
- spec/ripple/persistence_spec.rb
102
- spec/ripple/properties_spec.rb
103
- spec/ripple/ripple_spec.rb
104
- spec/ripple/timestamps_spec.rb
105
- spec/ripple/validations_spec.rb
106
- spec/spec_helper.rb
107
- spec/support/associations/proxies.rb
108
- spec/support/mocks.rb
109
- spec/support/models/address.rb
110
- spec/support/models/box.rb
111
- spec/support/models/car.rb
112
- spec/support/models/cardboard_box.rb
113
- spec/support/models/clock.rb
114
- spec/support/models/customer.rb
115
- spec/support/models/driver.rb
116
- spec/support/models/email.rb
117
- spec/support/models/engine.rb
118
- spec/support/models/family.rb
119
- spec/support/models/favorite.rb
120
- spec/support/models/invoice.rb
121
- spec/support/models/late_invoice.rb
122
- spec/support/models/note.rb
123
- spec/support/models/page.rb
124
- spec/support/models/paid_invoice.rb
125
- spec/support/models/passenger.rb
126
- spec/support/models/seat.rb
127
- spec/support/models/tasks.rb
128
- spec/support/models/tree.rb
129
- spec/support/models/user.rb
130
- spec/support/models/wheel.rb
131
- spec/support/models/widget.rb
132
- spec/support/test_server.rb
133
- spec/support/test_server.yml.example
134
- }
19
+ files = FileList["**/*"]
20
+ # Editor and O/S files
21
+ files.exclude ".DS_Store", "*~", "\#*", ".\#*", "*.swp", "*.tmproj", "tmtags"
22
+ # Generated artifacts
23
+ files.exclude "coverage", "rdoc", "pkg", ".bundle", "*.rbc", ".rvmrc", ".watchr", ".rspec"
24
+ # Project-specific
25
+ files.exclude "Gemfile.lock", %r{spec/support/test_server.yml$}, "bin"
26
+ # Remove directories
27
+ files.exclude {|d| File.directory?(d) }
28
+
29
+ gem.files = files.to_a
135
30
 
136
31
  gem.test_files = gem.files.grep(/_spec\.rb$/)
137
32
  end
@@ -1,6 +1,7 @@
1
1
  # Configure Riak connections for the Ripple library.
2
2
  development:
3
- port: 8098
3
+ http_port: 8098
4
+ pb_port: 8087
4
5
  host: localhost
5
6
 
6
7
  # The test environment has additional keys for configuring the
@@ -11,11 +12,13 @@ development:
11
12
  # * js_source_dir specifies where your custom Javascript functions for
12
13
  # MapReduce should be loaded from. Usually app/mapreduce.
13
14
  test:
14
- port: 9000
15
+ http_port: 9000
16
+ pb_port: 9002
15
17
  host: localhost
16
18
  bin_dir: /usr/local/bin # Default for Homebrew.
17
19
  js_source_dir: <%%= Rails.root + "app/mapreduce" %>
18
20
 
19
21
  production:
20
- port: 8098
22
+ http_port: 8098
23
+ pb_port: 8087
21
24
  host: localhost
@@ -41,6 +41,7 @@ module Ripple
41
41
  autoload :Validations
42
42
  autoload :NestedAttributes
43
43
  autoload :Observable
44
+ autoload :Serialization
44
45
 
45
46
  # Exceptions
46
47
  autoload :PropertyTypeMismatch
@@ -100,7 +101,7 @@ module Ripple
100
101
 
101
102
  private
102
103
  def client_config
103
- config.slice(:host, :port, :prefix, :mapred, :client_id, :http_backend, :solr)
104
+ config.slice(*Riak::Client::VALID_OPTIONS)
104
105
  end
105
106
  end
106
107
 
@@ -123,7 +123,13 @@ module Ripple
123
123
  # @private
124
124
  def attributes_for_persistence
125
125
  self.class.embedded_associations.inject(super) do |attrs, association|
126
- if documents = instance_variable_get(association.ivar)
126
+ documents = instance_variable_get(association.ivar)
127
+ # We must explicitly check #nil? (rather than just saying `if documents`)
128
+ # because documents can be an association proxy that is proxying nil.
129
+ # In this case ruby treats documents as true because it is not _really_ nil,
130
+ # but #nil? will tell us if it is proxying nil.
131
+
132
+ unless documents.nil?
127
133
  attrs[association.name] = documents.is_a?(Array) ? documents.map(&:attributes_for_persistence) : documents.attributes_for_persistence
128
134
  end
129
135
  attrs
@@ -26,6 +26,13 @@ module Ripple
26
26
  self
27
27
  end
28
28
 
29
+ def delete(value)
30
+ load_target
31
+ @target.delete(value)
32
+ replace @target
33
+ self
34
+ end
35
+
29
36
  protected
30
37
  def find_target
31
38
  robjects.map {|robj| klass.send(:instantiate, robj) }
@@ -23,7 +23,14 @@ module Ripple
23
23
  @reflection.verify_type!(doc, @owner)
24
24
  @_doc = doc.respond_to?(:attributes_for_persistence) ? doc.attributes_for_persistence : doc
25
25
  assign_references(doc)
26
- reset
26
+
27
+ if doc.is_a?(@reflection.klass)
28
+ loaded
29
+ @target = doc
30
+ else
31
+ reset
32
+ end
33
+
27
34
  @_doc
28
35
  end
29
36
 
@@ -22,7 +22,11 @@ module Ripple
22
22
  protected
23
23
  def find_target
24
24
  return nil if links.blank?
25
- klass.send(:instantiate,robjects.first)
25
+
26
+ robjs = robjects
27
+ return nil if robjs.blank?
28
+
29
+ klass.send(:instantiate, robjs.first)
26
30
  end
27
31
  end
28
32
  end
@@ -100,12 +100,12 @@ module Ripple
100
100
 
101
101
  protected
102
102
  def method_missing(method, *args, &block)
103
- if load_target
104
- if block_given?
105
- target.send(method, *args) { |*block_args| block.call(*block_args) }
106
- else
107
- target.send(method, *args)
108
- end
103
+ load_target
104
+
105
+ if block_given?
106
+ target.send(method, *args) { |*block_args| block.call(*block_args) }
107
+ else
108
+ target.send(method, *args)
109
109
  end
110
110
  end
111
111
 
@@ -63,6 +63,7 @@ module Ripple
63
63
  include Ripple::Document::Finders
64
64
  include Ripple::Inspection
65
65
  include Ripple::NestedAttributes
66
+ include Ripple::Serialization
66
67
  end
67
68
 
68
69
  module ClassMethods
@@ -38,6 +38,7 @@ module Ripple
38
38
  include Finders
39
39
  include Ripple::Inspection
40
40
  include Ripple::NestedAttributes
41
+ include Ripple::Serialization
41
42
  end
42
43
 
43
44
  module ClassMethods
@@ -45,5 +46,13 @@ module Ripple
45
46
  true
46
47
  end
47
48
  end
49
+
50
+ module InstanceMethods
51
+ def ==(other)
52
+ self.class == other.class &&
53
+ _parent_document == other._parent_document &&
54
+ attributes.except('_type') == other.attributes.except('_type')
55
+ end
56
+ end
48
57
  end
49
58
  end
@@ -0,0 +1,84 @@
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
+ require 'active_model/serialization'
16
+ require 'active_model/serializers/json'
17
+ require 'active_model/serializers/xml'
18
+
19
+ module Ripple
20
+ # Provides methods for serializing Ripple documents to external
21
+ # formats (e.g. JSON). By default, embedded documents will be
22
+ # included in the resulting format.
23
+ module Serialization
24
+ extend ActiveSupport::Concern
25
+ include ::ActiveModel::Serializers::JSON
26
+
27
+ module InstanceMethods
28
+ # Creates a Hash suitable for conversion to an external format.
29
+ # @param [Hash] options (nil) serialization options
30
+ # @option options [Array<Symbol>] :only emit only the specified attributes
31
+ # @option options [Array<Symbol>] :except omit the specified attributes
32
+ # @option options [Array<Symbol>, Hash] :include include the
33
+ # specified associations (with or without extra
34
+ # options). This defaults to all embedded associations.
35
+ # @return [Hash] a hash of attributes and embedded documents
36
+ def serializable_hash(options=nil)
37
+ options = options.try(:clone) || {}
38
+
39
+ unless options.has_key?(:include)
40
+ options[:include] = self.class.embedded_associations.map(&:name)
41
+ end
42
+
43
+ hash = super(options)
44
+
45
+ hash['key'] = key if respond_to?(:key) and key.present?
46
+
47
+ serializable_add_includes(options) do |association, records, opts|
48
+ hash[association.to_s] = records.is_a?(Enumerable) ? records.map {|r| r.serializable_hash(opts) } : records.serializable_hash(opts)
49
+ end
50
+ hash
51
+ end
52
+
53
+ private
54
+ def serializable_add_includes(options={})
55
+ return unless include_associations = options.delete(:include)
56
+
57
+ base_only_or_except = {
58
+ :except => options[:except],
59
+ :only => options[:only]
60
+ }
61
+
62
+ include_has_options = include_associations.is_a?(Hash)
63
+ associations = include_has_options ? include_associations.keys : Array.wrap(include_associations)
64
+
65
+ for association in associations
66
+ records = case self.class.associations[association.to_sym].type
67
+ when :many
68
+ send(association).to_a
69
+ when :one
70
+ send(association)
71
+ end
72
+
73
+ unless records.nil?
74
+ association_options = include_has_options ? include_associations[association] : base_only_or_except
75
+ opts = options.merge(association_options)
76
+ yield(association, records, opts)
77
+ end
78
+ end
79
+
80
+ options[:include] = include_associations
81
+ end
82
+ end
83
+ end
84
+ end
@@ -53,6 +53,10 @@ module Ripple
53
53
  obj = create(attrs, &block)
54
54
  (raise Ripple::DocumentInvalid.new(obj) if obj.new?) || obj
55
55
  end
56
+
57
+ def validates_associated(*attr_names)
58
+ validates_with AssociatedValidator, _merge_attributes(attr_names)
59
+ end
56
60
  end
57
61
 
58
62
  module InstanceMethods
@@ -24,11 +24,5 @@ module Ripple
24
24
  record.errors.add(attribute, :invalid, options.merge(:value => value))
25
25
  end
26
26
  end
27
-
28
- module ClassMethods
29
- def validates_associated(*attr_names)
30
- validates_with AssociatedValidator, _merge_attributes(attr_names)
31
- end
32
- end
33
27
  end
34
28
  end
@@ -2,37 +2,37 @@
2
2
 
3
3
  Gem::Specification.new do |s|
4
4
  s.name = %q{ripple}
5
- s.version = "0.9.0.beta2"
5
+ s.version = "0.9.0"
6
6
 
7
- s.required_rubygems_version = Gem::Requirement.new("> 1.3.1") if s.respond_to? :required_rubygems_version=
7
+ s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
8
8
  s.authors = ["Sean Cribbs"]
9
- s.date = %q{2011-03-28}
9
+ s.date = %q{2011-04-03}
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/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"]
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/serialization.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/serialization_spec.rb", "spec/ripple/timestamps_spec.rb", "spec/ripple/validations/associated_validator_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/clock_observer.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
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/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"]
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/serialization_spec.rb", "spec/ripple/timestamps_spec.rb", "spec/ripple/validations/associated_validator_spec.rb", "spec/ripple/validations_spec.rb"]
18
18
 
19
19
  if s.respond_to? :specification_version then
20
20
  s.specification_version = 3
21
21
 
22
22
  if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
23
23
  s.add_development_dependency(%q<rspec>, ["~> 2.4.0"])
24
- s.add_runtime_dependency(%q<riak-client>, ["~> 0.9.0.beta2"])
24
+ s.add_runtime_dependency(%q<riak-client>, ["~> 0.9.0"])
25
25
  s.add_runtime_dependency(%q<activesupport>, ["~> 3.0.0"])
26
26
  s.add_runtime_dependency(%q<activemodel>, ["~> 3.0.0"])
27
27
  else
28
28
  s.add_dependency(%q<rspec>, ["~> 2.4.0"])
29
- s.add_dependency(%q<riak-client>, ["~> 0.9.0.beta2"])
29
+ s.add_dependency(%q<riak-client>, ["~> 0.9.0"])
30
30
  s.add_dependency(%q<activesupport>, ["~> 3.0.0"])
31
31
  s.add_dependency(%q<activemodel>, ["~> 3.0.0"])
32
32
  end
33
33
  else
34
34
  s.add_dependency(%q<rspec>, ["~> 2.4.0"])
35
- s.add_dependency(%q<riak-client>, ["~> 0.9.0.beta2"])
35
+ s.add_dependency(%q<riak-client>, ["~> 0.9.0"])
36
36
  s.add_dependency(%q<activesupport>, ["~> 3.0.0"])
37
37
  s.add_dependency(%q<activemodel>, ["~> 3.0.0"])
38
38
  end
@@ -1,8 +1,8 @@
1
1
  ripple:
2
- port: 9000
2
+ http_port: 9000
3
3
  host: localhost
4
4
 
5
5
  ripple_rails:
6
6
  development:
7
- port: 9001
8
- host: 127.0.0.1
7
+ http_port: 9001
8
+ host: 127.0.0.1
@@ -58,6 +58,36 @@ describe "Ripple Associations" do
58
58
  @found.profile.user.should == @found
59
59
  end
60
60
 
61
+ it "should not raise an error when a one linked associated record has been deleted" do
62
+ @user.emergency_contact = @friend1
63
+ @user.save
64
+
65
+ @friend1.destroy
66
+ @found = User.find(@user.key)
67
+ @found.emergency_contact.should be_nil
68
+ end
69
+
70
+ it "should allow a many linked record to be deleted from the association but kept in the datastore" do
71
+ @user.friends << @friend1
72
+ @user.save!
73
+
74
+ @user.friends.delete(@friend1)
75
+ @user.save!
76
+
77
+ found_user = User.find(@user.key)
78
+ found_user.friends.should be_empty
79
+ User.find(@friend1.key).should be
80
+ end
81
+
82
+ it "should allow a many embedded record to be deleted from the association" do
83
+ @user.addresses << @billing << @shipping
84
+ @user.save!
85
+
86
+ @user.addresses.delete(@billing)
87
+ @user.save!
88
+ User.find(@user.key).addresses.should == [@shipping]
89
+ end
90
+
61
91
  it "should save many embedded associations" do
62
92
  @user.addresses << @billing << @shipping
63
93
  @user.save
@@ -27,11 +27,14 @@ describe Ripple::Associations::OneEmbeddedProxy do
27
27
  it "should not have a child before one is set" do
28
28
  @parent.child.should be_nil
29
29
  end
30
+
31
+ it "should raise NoMethodError when an undefined method is called on the unset child" do
32
+ expect { @parent.child.some_undefined_method }.to raise_error(NoMethodError)
33
+ end
30
34
 
31
35
  it "should be able to set and get its child" do
32
- Child.stub!(:instantiate).and_return(@child)
33
36
  @parent.child = @child
34
- @parent.child.should == @child
37
+ @parent.child.should equal(@child)
35
38
  end
36
39
 
37
40
  it "should set the parent document on the child when assigning" do
@@ -49,6 +49,13 @@ describe Ripple::Associations do
49
49
  Invoice.instance_methods.map(&:to_sym).should include(:payee?)
50
50
  end
51
51
  end
52
+
53
+ after do
54
+ Invoice.associations.delete(:foo)
55
+ Invoice.associations.delete(:items)
56
+ SubInvoice.associations.delete(:foo) if defined?(SubInvoice)
57
+ Invoice.associations.delete(:payee)
58
+ end
52
59
  end
53
60
 
54
61
  describe Ripple::Association do
@@ -15,6 +15,7 @@ require File.expand_path("../../spec_helper", __FILE__)
15
15
 
16
16
  describe Ripple::EmbeddedDocument do
17
17
  require 'support/models/address'
18
+ require 'support/models/user'
18
19
 
19
20
  it "should have a model name when included" do
20
21
  Address.should respond_to(:model_name)
@@ -24,4 +25,50 @@ describe Ripple::EmbeddedDocument do
24
25
  it "should be embeddable" do
25
26
  Address.should be_embeddable
26
27
  end
28
+
29
+ describe "#==" do
30
+ let(:user_1) { User.create! }
31
+ let(:user_2) { User.create! }
32
+ let(:street_1) { '123 Somewhere St' }
33
+ let(:street_2) { '123 Somewhere Ave' }
34
+ let(:address_1) { Address.new(:street => street_1) }
35
+ let(:address_2) { Address.new(:street => street_1) }
36
+
37
+ before(:each) do
38
+ address_1._parent_document = user_1
39
+ address_2._parent_document = user_1
40
+ end
41
+
42
+ it "returns true when the documents have the same classes, parents and attributes" do
43
+ (address_1 == address_2).should be_true
44
+ (address_2 == address_1).should be_true
45
+ end
46
+
47
+ it "returns true when the documents match and only one of them includes the _type attribute" do
48
+ attrs = address_1.attributes
49
+ address_1.stub(:attributes => attrs.merge('_type' => 'Address'))
50
+
51
+ (address_1 == address_2).should be_true
52
+ (address_2 == address_1).should be_true
53
+ end
54
+
55
+ it "returns false when the parents are different (even if the attributes and classes are the same)" do
56
+ address_2._parent_document = user_2
57
+ (address_1 == address_2).should be_false
58
+ (address_2 == address_1).should be_false
59
+ end
60
+
61
+ it "returns false when the attributes are different (even if the parents and classes are the same)" do
62
+ address_2.street = street_2
63
+ (address_1 == address_2).should be_false
64
+ (address_2 == address_1).should be_false
65
+ end
66
+
67
+ it "returns false then the classes are different (even if the parents and attributes are the same)" do
68
+ special_address = SpecialAddress.new(address_1.attributes)
69
+ special_address._parent_document = address_1._parent_document
70
+ (address_1 == special_address).should be_false
71
+ (special_address == address_1).should be_false
72
+ end
73
+ end
27
74
  end
@@ -30,16 +30,16 @@ describe Ripple do
30
30
 
31
31
  it "should allow setting the client manually" do
32
32
  Ripple.should respond_to(:client=)
33
- client = Riak::Client.new(:port => 9000)
33
+ client = Riak::Client.new(:http_port => 9000)
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
- Ripple.config = {:port => 9000}
40
+ Ripple.config = {:http_port => 9000}
41
41
  Ripple.client.should_not == c
42
- Ripple.client.port.should == 9000
42
+ Ripple.client.http_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
@@ -53,13 +53,13 @@ describe Ripple do
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
- Ripple.client.port.should == 9001
56
+ Ripple.client.http_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
- Ripple.client.port.should == 9000
62
+ Ripple.client.http_port.should == 9000
63
63
  Ripple.client.host.should == 'localhost'
64
64
  end
65
65
 
@@ -0,0 +1,52 @@
1
+ # Copyright 2010 Sean Cribbs, Sonian Inc., and Basho Technologies, Inc.
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+ require File.expand_path("../../spec_helper", __FILE__)
15
+
16
+ describe Ripple::Serialization do
17
+ require 'support/models/invoice'
18
+ require 'support/models/note'
19
+ require 'support/models/customer'
20
+
21
+ it "should provide JSON serialization" do
22
+ Invoice.new.should respond_to(:to_json)
23
+ end
24
+
25
+ context "when serializing" do
26
+ it "should include attributes" do
27
+ Note.new(:text => "Dear Jane,...").serializable_hash.should include('text')
28
+ end
29
+
30
+ it "should include the document key" do
31
+ doc = Invoice.new
32
+ doc.key = "1"
33
+ doc.serializable_hash['key'].should == "1"
34
+ end
35
+
36
+ it "should include embedded documents by default" do
37
+ doc = Invoice.new(:note => {:text => "Dear customer,..."}).serializable_hash
38
+ doc['note'].should eql({'text' => "Dear customer,..."})
39
+ end
40
+
41
+ it "should exclude specified attributes" do
42
+ hash = Invoice.new.serializable_hash(:except => [:created_at])
43
+ hash.should_not include('created_at')
44
+ end
45
+
46
+ it "should limit to specified attributes" do
47
+ hash = Invoice.new.serializable_hash(:only => [:created_at])
48
+ hash.should include('created_at')
49
+ hash.should_not include('updated_at')
50
+ end
51
+ end
52
+ end
@@ -0,0 +1,33 @@
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::Validations::AssociatedValidator do
17
+ require 'support/models/family'
18
+
19
+ let(:child) { Child.new }
20
+ let(:parent) { Parent.new }
21
+ before(:each) { parent.child = child }
22
+
23
+ it "is invalid when the associated record is invalid" do
24
+ child.should_not be_valid
25
+ parent.should_not be_valid
26
+ end
27
+
28
+ it "is valid when the associated record is valid" do
29
+ child.name = 'Coen'
30
+ child.should be_valid
31
+ parent.should be_valid
32
+ end
33
+ end
@@ -26,4 +26,8 @@ RSpec.configure do |config|
26
26
  config.after(:each) do
27
27
  $test_server.recycle if $test_server
28
28
  end
29
+
30
+ config.filter_run :focus => true
31
+ config.run_all_when_everything_filtered = true
32
+ config.debug = true
29
33
  end
@@ -20,3 +20,6 @@ class Address
20
20
  many :notes
21
21
  embedded_in :user
22
22
  end
23
+
24
+ class SpecialAddress < Address
25
+ end
@@ -0,0 +1,16 @@
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
+ class ClockObserver < ActiveModel::Observer
16
+ end
@@ -14,6 +14,7 @@
14
14
  class Parent
15
15
  include Ripple::Document
16
16
  one :child
17
+ validates_associated :child
17
18
  end
18
19
 
19
20
  class Child
@@ -16,4 +16,5 @@ class Invoice
16
16
  include Ripple::Document
17
17
  one :customer
18
18
  one :note
19
+ timestamps!
19
20
  end
@@ -14,4 +14,5 @@
14
14
 
15
15
  class Note
16
16
  include Ripple::EmbeddedDocument
17
+ property :text, String
17
18
  end
@@ -7,7 +7,7 @@ unless $test_server
7
7
  $test_server = Riak::TestServer.new(config.symbolize_keys)
8
8
  $test_server.prepare!
9
9
  $test_server.start
10
- Ripple.config = {:port => 9000 }
10
+ Ripple.config = {:http_port => 9000 }
11
11
  at_exit { $test_server.cleanup }
12
12
  rescue => e
13
13
  warn "Can't run Riak::TestServer specs. Specify the location of your Riak installation in spec/support/test_server.yml. See Riak::TestServer docs for more info."
metadata CHANGED
@@ -1,8 +1,8 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ripple
3
3
  version: !ruby/object:Gem::Version
4
- prerelease: 6
5
- version: 0.9.0.beta2
4
+ prerelease:
5
+ version: 0.9.0
6
6
  platform: ruby
7
7
  authors:
8
8
  - Sean Cribbs
@@ -10,7 +10,7 @@ autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
12
 
13
- date: 2011-03-28 00:00:00 -04:00
13
+ date: 2011-04-03 00:00:00 -04:00
14
14
  default_executable:
15
15
  dependencies:
16
16
  - !ruby/object:Gem::Dependency
@@ -32,7 +32,7 @@ dependencies:
32
32
  requirements:
33
33
  - - ~>
34
34
  - !ruby/object:Gem::Version
35
- version: 0.9.0.beta2
35
+ version: 0.9.0
36
36
  type: :runtime
37
37
  version_requirements: *id002
38
38
  - !ruby/object:Gem::Dependency
@@ -116,6 +116,7 @@ files:
116
116
  - lib/ripple/properties.rb
117
117
  - lib/ripple/property_type_mismatch.rb
118
118
  - lib/ripple/railtie.rb
119
+ - lib/ripple/serialization.rb
119
120
  - lib/ripple/timestamps.rb
120
121
  - lib/ripple/translation.rb
121
122
  - lib/ripple/validations/associated_validator.rb
@@ -149,7 +150,9 @@ files:
149
150
  - spec/ripple/persistence_spec.rb
150
151
  - spec/ripple/properties_spec.rb
151
152
  - spec/ripple/ripple_spec.rb
153
+ - spec/ripple/serialization_spec.rb
152
154
  - spec/ripple/timestamps_spec.rb
155
+ - spec/ripple/validations/associated_validator_spec.rb
153
156
  - spec/ripple/validations_spec.rb
154
157
  - spec/spec_helper.rb
155
158
  - spec/support/associations/proxies.rb
@@ -159,6 +162,7 @@ files:
159
162
  - spec/support/models/car.rb
160
163
  - spec/support/models/cardboard_box.rb
161
164
  - spec/support/models/clock.rb
165
+ - spec/support/models/clock_observer.rb
162
166
  - spec/support/models/customer.rb
163
167
  - spec/support/models/driver.rb
164
168
  - spec/support/models/email.rb
@@ -197,9 +201,9 @@ required_ruby_version: !ruby/object:Gem::Requirement
197
201
  required_rubygems_version: !ruby/object:Gem::Requirement
198
202
  none: false
199
203
  requirements:
200
- - - ">"
204
+ - - ">="
201
205
  - !ruby/object:Gem::Version
202
- version: 1.3.1
206
+ version: "0"
203
207
  requirements: []
204
208
 
205
209
  rubyforge_project:
@@ -233,5 +237,7 @@ test_files:
233
237
  - spec/ripple/persistence_spec.rb
234
238
  - spec/ripple/properties_spec.rb
235
239
  - spec/ripple/ripple_spec.rb
240
+ - spec/ripple/serialization_spec.rb
236
241
  - spec/ripple/timestamps_spec.rb
242
+ - spec/ripple/validations/associated_validator_spec.rb
237
243
  - spec/ripple/validations_spec.rb