langalex-couch_potato 0.2.2 → 0.2.3
Sign up to get free protection for your applications and to get access to all the features.
- data/README.md +4 -2
- data/VERSION.yml +1 -1
- data/lib/couch_potato/database.rb +20 -14
- data/lib/couch_potato/persistence/belongs_to_property.rb +1 -1
- data/lib/couch_potato/persistence/callbacks.rb +65 -77
- data/lib/couch_potato/persistence/dirty_attributes.rb +2 -1
- data/lib/couch_potato/persistence/json.rb +4 -0
- data/lib/couch_potato/persistence/magic_timestamps.rb +1 -1
- data/lib/couch_potato/persistence/properties.rb +18 -2
- data/lib/couch_potato/persistence/simple_property.rb +1 -1
- data/lib/couch_potato/persistence.rb +39 -2
- data/lib/couch_potato/view/custom_view_spec.rb +3 -2
- data/lib/couch_potato/view/custom_views.rb +1 -2
- data/lib/couch_potato/view/model_view_spec.rb +4 -2
- data/lib/couch_potato/view/properties_view_spec.rb +4 -2
- data/lib/couch_potato/view/raw_view_spec.rb +8 -4
- data/lib/couch_potato/view/view_query.rb +1 -2
- data/lib/couch_potato.rb +4 -0
- data/spec/callbacks_spec.rb +31 -5
- data/spec/unit/create_spec.rb +2 -2
- data/spec/unit/database_spec.rb +18 -0
- data/spec/unit/dirty_attributes_spec.rb +3 -3
- metadata +3 -3
- data/lib/couch_potato/persistence/inline_collection.rb +0 -14
data/README.md
CHANGED
@@ -221,10 +221,12 @@ Couch Potato supports the usual lifecycle callbacks known from ActiveRecord:
|
|
221
221
|
include CouchPotato::Persistence
|
222
222
|
|
223
223
|
before_create :do_something_before_create
|
224
|
-
|
224
|
+
before_update {|user, db| user.do_something_on_update}
|
225
225
|
end
|
226
226
|
|
227
|
-
This will call the method do_something_before_create before creating an object and
|
227
|
+
This will call the method do_something_before_create before creating an object and run the given lambda before updating one. Lambda callbacks get passed the model as their first argument. Optionally if a lambda declares two arguments it also gets passed the database object. This is useful for creating other objects or querying views. Method callbacks don't receive any arguments by default but will get passed the database if they declare an argument.
|
228
|
+
|
229
|
+
Supported callbacks are: :before_validation_on_create, :before_validation_on_update, :before_validation_on_save, :before_create, :after_create, :before_update, :after_update, :before_save, :after_save, :before_destroy, :after_destroy.
|
228
230
|
|
229
231
|
#### Testing
|
230
232
|
|
data/VERSION.yml
CHANGED
@@ -5,6 +5,11 @@ module CouchPotato
|
|
5
5
|
|
6
6
|
def initialize(couchrest_database)
|
7
7
|
@database = couchrest_database
|
8
|
+
begin
|
9
|
+
couchrest_database.info
|
10
|
+
rescue RestClient::ResourceNotFound
|
11
|
+
raise "Database '#{couchrest_database.name}' does not exist."
|
12
|
+
end
|
8
13
|
end
|
9
14
|
|
10
15
|
def view(spec)
|
@@ -30,16 +35,17 @@ module CouchPotato
|
|
30
35
|
alias_method :save!, :save_document!
|
31
36
|
|
32
37
|
def destroy_document(document)
|
33
|
-
document.run_callbacks
|
38
|
+
document.run_callbacks :before_destroy, self
|
34
39
|
document._deleted = true
|
35
40
|
database.delete_doc document.to_hash
|
36
|
-
document.run_callbacks
|
41
|
+
document.run_callbacks :after_destroy, self
|
37
42
|
document._id = nil
|
38
43
|
document._rev = nil
|
39
44
|
end
|
40
45
|
alias_method :destroy, :destroy_document
|
41
46
|
|
42
47
|
def load_document(id)
|
48
|
+
raise "Can't load a document without an id (got nil)" if id.nil?
|
43
49
|
begin
|
44
50
|
json = database.get(id)
|
45
51
|
Class.const_get(json['ruby_class']).json_create json
|
@@ -56,29 +62,29 @@ module CouchPotato
|
|
56
62
|
private
|
57
63
|
|
58
64
|
def create_document(document)
|
59
|
-
document.run_callbacks :before_validation_on_save
|
60
|
-
document.run_callbacks :before_validation_on_create
|
65
|
+
document.run_callbacks :before_validation_on_save, self
|
66
|
+
document.run_callbacks :before_validation_on_create, self
|
61
67
|
return unless document.valid?
|
62
|
-
document.run_callbacks :before_save
|
63
|
-
document.run_callbacks :before_create
|
68
|
+
document.run_callbacks :before_save, self
|
69
|
+
document.run_callbacks :before_create, self
|
64
70
|
res = database.save_doc document.to_hash
|
65
71
|
document._rev = res['rev']
|
66
72
|
document._id = res['id']
|
67
|
-
document.run_callbacks :after_save
|
68
|
-
document.run_callbacks :after_create
|
73
|
+
document.run_callbacks :after_save, self
|
74
|
+
document.run_callbacks :after_create, self
|
69
75
|
true
|
70
76
|
end
|
71
77
|
|
72
78
|
def update_document(document)
|
73
|
-
document.run_callbacks
|
74
|
-
document.run_callbacks
|
79
|
+
document.run_callbacks :before_validation_on_save, self
|
80
|
+
document.run_callbacks :before_validation_on_update, self
|
75
81
|
return unless document.valid?
|
76
|
-
document.run_callbacks :before_save
|
77
|
-
document.run_callbacks :before_update
|
82
|
+
document.run_callbacks :before_save, self
|
83
|
+
document.run_callbacks :before_update, self
|
78
84
|
res = database.save_doc document.to_hash
|
79
85
|
document._rev = res['rev']
|
80
|
-
document.run_callbacks :after_save
|
81
|
-
document.run_callbacks :after_update
|
86
|
+
document.run_callbacks :after_save, self
|
87
|
+
document.run_callbacks :after_update, self
|
82
88
|
true
|
83
89
|
end
|
84
90
|
|
@@ -1,6 +1,49 @@
|
|
1
1
|
module CouchPotato
|
2
2
|
module Persistence
|
3
3
|
module Callbacks
|
4
|
+
|
5
|
+
class Callback #:nodoc:
|
6
|
+
def initialize(model, name, database)
|
7
|
+
@model, @name, @database = model, name, database
|
8
|
+
end
|
9
|
+
|
10
|
+
def run
|
11
|
+
if @name.is_a?(Symbol)
|
12
|
+
run_method_callback @name
|
13
|
+
elsif @name.is_a?(Proc)
|
14
|
+
run_lambda_callback @name
|
15
|
+
else
|
16
|
+
raise "Don't know how to handle callback of type #{name.class.name}"
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
private
|
21
|
+
|
22
|
+
def run_method_callback(name)
|
23
|
+
if callback_method(name).arity == 0
|
24
|
+
@model.send name
|
25
|
+
elsif callback_method(name).arity == 1
|
26
|
+
@model.send name, @database
|
27
|
+
else
|
28
|
+
raise "Don't know how to handle method callback with #{callback_method(name).arity} arguments"
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
def callback_method(name)
|
33
|
+
@model.method(name)
|
34
|
+
end
|
35
|
+
|
36
|
+
def run_lambda_callback(lambda)
|
37
|
+
if lambda.arity == 1
|
38
|
+
lambda.call @model
|
39
|
+
elsif lambda.arity == 2
|
40
|
+
lambda.call @model, @database
|
41
|
+
else raise "Don't know how to handle lambda callback with #{lambda.arity} arguments"
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
end
|
46
|
+
|
4
47
|
def self.included(base)
|
5
48
|
base.extend ClassMethods
|
6
49
|
|
@@ -17,89 +60,34 @@ module CouchPotato
|
|
17
60
|
end
|
18
61
|
end
|
19
62
|
|
20
|
-
|
63
|
+
# Runs all callbacks on a model with the given name, i.g. :after_create.
|
64
|
+
#
|
65
|
+
# This method is called by the CouchPotato::Database object when saving/destroying an object
|
66
|
+
def run_callbacks(name, database)
|
21
67
|
return if skip_callbacks
|
22
68
|
self.class.callbacks[name].uniq.each do |callback|
|
23
|
-
|
24
|
-
end
|
25
|
-
end
|
26
|
-
|
27
|
-
private
|
28
|
-
|
29
|
-
def run_callback(name)
|
30
|
-
if name.is_a?(Symbol)
|
31
|
-
self.send name
|
32
|
-
elsif name.is_a?(Proc)
|
33
|
-
name.call self
|
34
|
-
else
|
35
|
-
raise "Don't know how to handle callback of type #{name.class.name}"
|
69
|
+
Callback.new(self, callback, database).run
|
36
70
|
end
|
37
71
|
end
|
38
72
|
|
39
73
|
module ClassMethods
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
def before_create(*names)
|
59
|
-
names.each do |name|
|
60
|
-
callbacks[:before_create] << name
|
61
|
-
end
|
62
|
-
end
|
63
|
-
|
64
|
-
def before_save(*names)
|
65
|
-
names.each do |name|
|
66
|
-
callbacks[:before_save] << name
|
67
|
-
end
|
68
|
-
end
|
69
|
-
|
70
|
-
def before_update(*names)
|
71
|
-
names.each do |name|
|
72
|
-
callbacks[:before_update] << name
|
73
|
-
end
|
74
|
-
end
|
75
|
-
|
76
|
-
def before_destroy(*names)
|
77
|
-
names.each do |name|
|
78
|
-
callbacks[:before_destroy] << name
|
79
|
-
end
|
80
|
-
end
|
81
|
-
|
82
|
-
def after_update(*names)
|
83
|
-
names.each do |name|
|
84
|
-
callbacks[:after_update] << name
|
85
|
-
end
|
86
|
-
end
|
87
|
-
|
88
|
-
def after_save(*names)
|
89
|
-
names.each do |name|
|
90
|
-
callbacks[:after_save] << name
|
91
|
-
end
|
92
|
-
end
|
93
|
-
|
94
|
-
def after_create(*names)
|
95
|
-
names.each do |name|
|
96
|
-
callbacks[:after_create] << name
|
97
|
-
end
|
98
|
-
end
|
99
|
-
|
100
|
-
def after_destroy(*names)
|
101
|
-
names.each do |name|
|
102
|
-
callbacks[:after_destroy] << name
|
74
|
+
[
|
75
|
+
:before_validation_on_create,
|
76
|
+
:before_validation_on_update,
|
77
|
+
:before_validation_on_save,
|
78
|
+
:before_create,
|
79
|
+
:before_save,
|
80
|
+
:before_update,
|
81
|
+
:before_destroy,
|
82
|
+
:after_update,
|
83
|
+
:after_save,
|
84
|
+
:after_create,
|
85
|
+
:after_destroy
|
86
|
+
].each do |callback|
|
87
|
+
define_method callback do |*names|
|
88
|
+
names.each do |name|
|
89
|
+
callbacks[callback] << name
|
90
|
+
end
|
103
91
|
end
|
104
92
|
end
|
105
93
|
end
|
@@ -8,7 +8,8 @@ module CouchPotato
|
|
8
8
|
end
|
9
9
|
end
|
10
10
|
|
11
|
-
|
11
|
+
# returns true if a model has dirty attributes, i.e. their value has changed since the last save
|
12
|
+
def dirty?
|
12
13
|
new? || self.class.properties.inject(false) do |res, property|
|
13
14
|
res || property.dirty?(self)
|
14
15
|
end
|
@@ -5,10 +5,12 @@ module CouchPotato
|
|
5
5
|
base.extend ClassMethods
|
6
6
|
end
|
7
7
|
|
8
|
+
# returns a JSON representation of a model in order to store it in CouchDB
|
8
9
|
def to_json(*args)
|
9
10
|
to_hash.to_json(*args)
|
10
11
|
end
|
11
12
|
|
13
|
+
# returns all the attributes, the ruby class and the _id and _rev of a model as a Hash
|
12
14
|
def to_hash
|
13
15
|
(self.class.properties).inject({}) do |props, property|
|
14
16
|
property.serialize(props, self)
|
@@ -26,6 +28,8 @@ module CouchPotato
|
|
26
28
|
end
|
27
29
|
|
28
30
|
module ClassMethods
|
31
|
+
|
32
|
+
# creates a model instance from JSON
|
29
33
|
def json_create(json)
|
30
34
|
instance = self.new
|
31
35
|
instance._id = json[:_id] || json['_id']
|
@@ -15,11 +15,19 @@ module CouchPotato
|
|
15
15
|
end
|
16
16
|
|
17
17
|
module ClassMethods
|
18
|
+
# returns all the property names of a model class that have been defined using the #property method
|
19
|
+
#
|
20
|
+
# example:
|
21
|
+
# class Book
|
22
|
+
# property :title
|
23
|
+
# property :year
|
24
|
+
# end
|
25
|
+
# Book.property_names # => [:title, :year]
|
18
26
|
def property_names
|
19
27
|
properties.map(&:name)
|
20
28
|
end
|
21
29
|
|
22
|
-
def json_create(json)
|
30
|
+
def json_create(json) #:nodoc:
|
23
31
|
instance = super
|
24
32
|
instance.attributes.each do |name, value|
|
25
33
|
instance.instance_variable_set("@#{name}_was", value)
|
@@ -27,12 +35,20 @@ module CouchPotato
|
|
27
35
|
instance
|
28
36
|
end
|
29
37
|
|
38
|
+
# Declare a proprty on a model class. properties are not typed by default. You can use any of the basic types by JSON (String, Integer, Fixnum, Array, Hash). If you want a property to be of a custom class you have to define it using the :class option.
|
39
|
+
#
|
40
|
+
# example:
|
41
|
+
# class Book
|
42
|
+
# property :title
|
43
|
+
# property :year
|
44
|
+
# property :publisher, :class => Publisher
|
45
|
+
# end
|
30
46
|
def property(name, options = {})
|
31
47
|
clazz = options.delete(:class)
|
32
48
|
properties << (clazz || SimpleProperty).new(self, name, options)
|
33
49
|
end
|
34
50
|
|
35
|
-
def belongs_to(name)
|
51
|
+
def belongs_to(name) #:nodoc:
|
36
52
|
property name, :class => BelongsToProperty
|
37
53
|
end
|
38
54
|
|
@@ -21,19 +21,52 @@ module CouchPotato
|
|
21
21
|
alias_method :id, :_id
|
22
22
|
end
|
23
23
|
end
|
24
|
-
|
24
|
+
|
25
|
+
# initialize a new instance of the model optionally passing it a hash of attributes.
|
26
|
+
# the attributes have to be declared using the #property method
|
27
|
+
#
|
28
|
+
# example:
|
29
|
+
# class Book
|
30
|
+
# include CouchPotato::Persistence
|
31
|
+
# property :title
|
32
|
+
# end
|
33
|
+
# book = Book.new :title => 'Time to Relax'
|
34
|
+
# book.title # => 'Time to Relax'
|
25
35
|
def initialize(attributes = {})
|
26
36
|
attributes.each do |name, value|
|
27
37
|
self.send("#{name}=", value)
|
28
38
|
end if attributes
|
29
39
|
end
|
30
40
|
|
41
|
+
# assign multiple attributes at once.
|
42
|
+
# the attributes have to be declared using the #property method
|
43
|
+
#
|
44
|
+
# example:
|
45
|
+
# class Book
|
46
|
+
# include CouchPotato::Persistence
|
47
|
+
# property :title
|
48
|
+
# property :year
|
49
|
+
# end
|
50
|
+
# book = Book.new
|
51
|
+
# book.attributes = {:title => 'Time to Relax', :year => 2009}
|
52
|
+
# book.title # => 'Time to Relax'
|
53
|
+
# book.year # => 2009
|
31
54
|
def attributes=(hash)
|
32
55
|
hash.each do |attribute, value|
|
33
56
|
self.send "#{attribute}=", value
|
34
57
|
end
|
35
58
|
end
|
36
59
|
|
60
|
+
# returns all of a model's attributes that have been defined using the #property method as a Hash
|
61
|
+
#
|
62
|
+
# example:
|
63
|
+
# class Book
|
64
|
+
# include CouchPotato::Persistence
|
65
|
+
# property :title
|
66
|
+
# property :year
|
67
|
+
# end
|
68
|
+
# book = Book.new :year => 2009
|
69
|
+
# book.attributes # => {:title => nil, :year => 2009}
|
37
70
|
def attributes
|
38
71
|
self.class.properties.inject({}) do |res, property|
|
39
72
|
property.serialize(res, self)
|
@@ -41,15 +74,19 @@ module CouchPotato
|
|
41
74
|
end
|
42
75
|
end
|
43
76
|
|
77
|
+
# returns true if a model hasn't been saved yet, false otherwise
|
44
78
|
def new?
|
45
79
|
_rev.nil?
|
46
80
|
end
|
47
81
|
|
82
|
+
# returns the document id
|
83
|
+
# this is used by rails to construct URLs
|
84
|
+
# can be overridden to for example use slugs for URLs instead if ids
|
48
85
|
def to_param
|
49
86
|
_id
|
50
87
|
end
|
51
88
|
|
52
|
-
def ==(other)
|
89
|
+
def ==(other) #:nodoc:
|
53
90
|
other.class == self.class && self.to_json == other.to_json
|
54
91
|
end
|
55
92
|
|
@@ -1,8 +1,9 @@
|
|
1
1
|
module CouchPotato
|
2
2
|
module View
|
3
3
|
# a view for custom map/reduce functions that still returns model instances
|
4
|
-
#
|
5
|
-
|
4
|
+
#
|
5
|
+
# example:
|
6
|
+
# view :my_custom_view, :map => "function(doc) { emit(doc._id, null); }", :include_docs => true, :type => :custom, :reduce => nil
|
6
7
|
class CustomViewSpec < BaseViewSpec
|
7
8
|
def map_function
|
8
9
|
options[:map]
|
@@ -14,8 +14,7 @@ module CouchPotato
|
|
14
14
|
end
|
15
15
|
|
16
16
|
module ClassMethods
|
17
|
-
|
18
|
-
# declare a couchdb view, for examples on how to use see the *ViewSpec classes in CouchPotato::View
|
17
|
+
# Declare a CouchDB view, for examples on how to use see the *ViewSpec classes in CouchPotato::View
|
19
18
|
def view(view_name, options)
|
20
19
|
self.class.instance_eval do
|
21
20
|
define_method view_name do |view_parameters = {}|
|
@@ -1,7 +1,9 @@
|
|
1
1
|
module CouchPotato
|
2
2
|
module View
|
3
|
-
#
|
4
|
-
#
|
3
|
+
# A view to return model instances by searching its properties
|
4
|
+
#
|
5
|
+
# example:
|
6
|
+
# view :my_view, :key => :name
|
5
7
|
class ModelViewSpec < BaseViewSpec
|
6
8
|
|
7
9
|
def view_parameters
|
@@ -1,7 +1,9 @@
|
|
1
1
|
module CouchPotato
|
2
2
|
module View
|
3
|
-
#
|
4
|
-
#
|
3
|
+
# A view to return model instances with only some properties poulated by searching its properties, e.g. for very large documents where you are only interested in some of their data
|
4
|
+
#
|
5
|
+
# example:
|
6
|
+
# view :my_view, :key => :name, :properties => [:name, :author], :type => :properties
|
5
7
|
class PropertiesViewSpec < ModelViewSpec
|
6
8
|
def map_function
|
7
9
|
"function(doc) {
|
@@ -1,9 +1,13 @@
|
|
1
1
|
module CouchPotato
|
2
|
-
# a view for custom map/reduce functions that returns the raw data fromcouchdb
|
3
|
-
# example: view :my_custom_view, :map => "function(doc) { emit(doc._id, null); }", :type => :raw, :reduce => nil
|
4
|
-
# optionally you can pass in a results filter which you can use to process the raw couchdb results before returning them
|
5
|
-
# example: view :my_custom_view, :map => "function(doc) { emit(doc._id, null); }", :type => :raw, :results_filter => lambda{|results| results['rows].map{|row| row['value']}}
|
6
2
|
module View
|
3
|
+
# A view for custom map/reduce functions that returns the raw data fromcouchdb
|
4
|
+
#
|
5
|
+
# example:
|
6
|
+
# view :my_custom_view, :map => "function(doc) { emit(doc._id, null); }", :type => :raw, :reduce => nil
|
7
|
+
# optionally you can pass in a results filter which you can use to process the raw couchdb results before returning them
|
8
|
+
#
|
9
|
+
# example:
|
10
|
+
# view :my_custom_view, :map => "function(doc) { emit(doc._id, null); }", :type => :raw, :results_filter => lambda{|results| results['rows].map{|row| row['value']}}
|
7
11
|
class RawViewSpec < BaseViewSpec
|
8
12
|
def map_function
|
9
13
|
options[:map]
|
@@ -1,6 +1,6 @@
|
|
1
1
|
module CouchPotato
|
2
2
|
module View
|
3
|
-
|
3
|
+
# Used to query views (and create them if they don't exist). Usually you won't have to use this class directly. Instead it is used internally by the CouchPotato::Database.view method.
|
4
4
|
class ViewQuery
|
5
5
|
def initialize(couchrest_database, design_document_name, view_name, map_function, reduce_function = nil)
|
6
6
|
@database = couchrest_database
|
@@ -38,7 +38,6 @@ module CouchPotato
|
|
38
38
|
def view_url
|
39
39
|
"#{@design_document_name}/#{@view_name}"
|
40
40
|
end
|
41
|
-
|
42
41
|
|
43
42
|
end
|
44
43
|
end
|
data/lib/couch_potato.rb
CHANGED
@@ -11,14 +11,18 @@ require 'validatable'
|
|
11
11
|
module CouchPotato
|
12
12
|
Config = OpenStruct.new
|
13
13
|
|
14
|
+
# Returns a database instance which you can then use to create objects and query views. You have to set the CouchPotato::Config.database_name before this works.
|
14
15
|
def self.database
|
15
16
|
@@__database ||= Database.new(self.couchrest_database)
|
16
17
|
end
|
17
18
|
|
19
|
+
# Returns the underlying CouchRest database object if you want low level access to your CouchDB. You have to set the CouchPotato::Config.database_name before this works.
|
18
20
|
def self.couchrest_database
|
19
21
|
@@__couchrest_database ||= CouchRest.database(full_url_to_database)
|
20
22
|
end
|
21
23
|
|
24
|
+
private
|
25
|
+
|
22
26
|
def self.full_url_to_database
|
23
27
|
database_name = CouchPotato::Config.database_name || raise('No Database configured. Set CouchPotato::Config.database_name')
|
24
28
|
url = database_name
|
data/spec/callbacks_spec.rb
CHANGED
@@ -20,13 +20,23 @@ class CallbackRecorder
|
|
20
20
|
self.send callback, callback
|
21
21
|
end
|
22
22
|
|
23
|
+
view :all, :key => :required_property
|
24
|
+
|
23
25
|
attr_accessor :lambda_works
|
24
|
-
before_create lambda {|model| model.lambda_works = true}
|
26
|
+
before_create lambda {|model| model.lambda_works = true }
|
27
|
+
after_create lambda {|model, db| db.view CallbackRecorder.all}
|
28
|
+
before_update :method_callback_with_argument
|
25
29
|
|
26
30
|
def callbacks
|
27
31
|
@callbacks ||= []
|
28
32
|
end
|
29
33
|
|
34
|
+
private
|
35
|
+
|
36
|
+
def method_callback_with_argument(db)
|
37
|
+
db.view CallbackRecorder.all
|
38
|
+
end
|
39
|
+
|
30
40
|
end
|
31
41
|
|
32
42
|
describe "multiple callbacks at once" do
|
@@ -59,7 +69,7 @@ describe 'create callbacks' do
|
|
59
69
|
|
60
70
|
before(:each) do
|
61
71
|
@recorder = CallbackRecorder.new
|
62
|
-
couchrest_database = stub 'couchrest_database', :save_doc => {'id' => '1', 'rev' => '2'}
|
72
|
+
couchrest_database = stub 'couchrest_database', :save_doc => {'id' => '1', 'rev' => '2'}, :view => {'rows' => []}, :info => nil
|
63
73
|
@db = CouchPotato::Database.new(couchrest_database)
|
64
74
|
end
|
65
75
|
|
@@ -139,7 +149,7 @@ describe "update callbacks" do
|
|
139
149
|
before(:each) do
|
140
150
|
@recorder = CallbackRecorder.new :required_property => 1
|
141
151
|
|
142
|
-
couchrest_database = stub 'couchrest_database', :save_doc => {'id' => '1', 'rev' => '2'}
|
152
|
+
couchrest_database = stub 'couchrest_database', :save_doc => {'id' => '1', 'rev' => '2'}, :view => {'rows' => []}, :info => nil
|
143
153
|
@db = CouchPotato::Database.new(couchrest_database)
|
144
154
|
@db.save_document! @recorder
|
145
155
|
|
@@ -218,7 +228,7 @@ describe "destroy callbacks" do
|
|
218
228
|
|
219
229
|
before(:each) do
|
220
230
|
@recorder = CallbackRecorder.new :required_property => 1
|
221
|
-
couchrest_database = stub 'couchrest_database', :save_doc => {'id' => '1', 'rev' => '2'}, :delete_doc => nil
|
231
|
+
couchrest_database = stub 'couchrest_database', :save_doc => {'id' => '1', 'rev' => '2'}, :delete_doc => nil, :view => {'rows' => []}, :info => nil
|
222
232
|
@db = CouchPotato::Database.new(couchrest_database)
|
223
233
|
@db.save_document! @recorder
|
224
234
|
|
@@ -236,10 +246,26 @@ describe "destroy callbacks" do
|
|
236
246
|
end
|
237
247
|
end
|
238
248
|
|
249
|
+
describe "method callbacks" do
|
250
|
+
it "should pass the database to a method with arity 1" do
|
251
|
+
recorder = CallbackRecorder.new
|
252
|
+
db = stub 'db'
|
253
|
+
db.should_receive(:view)
|
254
|
+
recorder.run_callbacks :before_update, db
|
255
|
+
end
|
256
|
+
end
|
257
|
+
|
239
258
|
describe "lambda callbacks" do
|
240
259
|
it "should run the lambda" do
|
241
260
|
recorder = CallbackRecorder.new
|
242
|
-
recorder.run_callbacks :before_create
|
261
|
+
recorder.run_callbacks :before_create, stub('db')
|
243
262
|
recorder.lambda_works.should be_true
|
244
263
|
end
|
264
|
+
|
265
|
+
it "should pass the database to a lambda with arity 2" do
|
266
|
+
recorder = CallbackRecorder.new
|
267
|
+
db = stub 'db'
|
268
|
+
db.should_receive(:view)
|
269
|
+
recorder.run_callbacks :after_create, db
|
270
|
+
end
|
245
271
|
end
|
data/spec/unit/create_spec.rb
CHANGED
@@ -5,7 +5,7 @@ describe "create" do
|
|
5
5
|
describe "succeeds" do
|
6
6
|
before(:each) do
|
7
7
|
@comment = Comment.new :title => 'my_title'
|
8
|
-
CouchPotato::Database.new(stub('database', :save_doc => {'rev' => '123', 'id' => '456'})).save_document!(@comment)
|
8
|
+
CouchPotato::Database.new(stub('database', :save_doc => {'rev' => '123', 'id' => '456'}, :info => nil)).save_document!(@comment)
|
9
9
|
end
|
10
10
|
|
11
11
|
it "should assign the id" do
|
@@ -28,7 +28,7 @@ describe "create" do
|
|
28
28
|
describe "fails" do
|
29
29
|
before(:each) do
|
30
30
|
@comment = Comment.new
|
31
|
-
CouchPotato::Database.new(stub('database')).save_document(@comment)
|
31
|
+
CouchPotato::Database.new(stub('database', :info => nil)).save_document(@comment)
|
32
32
|
end
|
33
33
|
|
34
34
|
it "should not assign an id" do
|
@@ -0,0 +1,18 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/../spec_helper'
|
2
|
+
|
3
|
+
describe CouchPotato::Database, 'new' do
|
4
|
+
it "should raise an exception if the database doesn't exist" do
|
5
|
+
lambda {
|
6
|
+
CouchPotato::Database.new CouchRest.database('couch_potato_invalid')
|
7
|
+
}.should raise_error('Database \'couch_potato_invalid\' does not exist.')
|
8
|
+
end
|
9
|
+
end
|
10
|
+
|
11
|
+
describe CouchPotato::Database, 'load' do
|
12
|
+
it "should raise an exception if nil given" do
|
13
|
+
db = CouchPotato::Database.new(stub('couchrest db', :info => nil))
|
14
|
+
lambda {
|
15
|
+
db.load nil
|
16
|
+
}.should raise_error("Can't load a document without an id (got nil)")
|
17
|
+
end
|
18
|
+
end
|
@@ -8,7 +8,7 @@ end
|
|
8
8
|
|
9
9
|
describe 'dirty attribute tracking' do
|
10
10
|
before(:each) do
|
11
|
-
@couchrest_db = stub('database', :save_doc => {'id' => '1', 'rev' => '2'})
|
11
|
+
@couchrest_db = stub('database', :save_doc => {'id' => '1', 'rev' => '2'}, :info => nil)
|
12
12
|
@db = CouchPotato::Database.new(@couchrest_db)
|
13
13
|
end
|
14
14
|
|
@@ -68,7 +68,7 @@ describe 'dirty attribute tracking' do
|
|
68
68
|
|
69
69
|
describe "object loaded from database" do
|
70
70
|
before(:each) do
|
71
|
-
couchrest_db = stub('database', :get => {'_id' => '1', '_rev' => '2', 'food' => 'sushi', 'ruby_class' => 'Plate'})
|
71
|
+
couchrest_db = stub('database', :get => {'_id' => '1', '_rev' => '2', 'food' => 'sushi', 'ruby_class' => 'Plate'}, :info => nil)
|
72
72
|
@plate = CouchPotato::Database.new(couchrest_db).load_document '1'
|
73
73
|
end
|
74
74
|
|
@@ -94,7 +94,7 @@ describe 'dirty attribute tracking' do
|
|
94
94
|
|
95
95
|
describe "after save" do
|
96
96
|
it "should reset all attributes to not dirty" do
|
97
|
-
couchrest_db = stub('database', :get => {'_id' => '1', '_rev' => '2', 'food' => 'sushi', 'ruby_class' => 'Plate'}, :save_doc => {})
|
97
|
+
couchrest_db = stub('database', :get => {'_id' => '1', '_rev' => '2', 'food' => 'sushi', 'ruby_class' => 'Plate'}, :info => nil, :save_doc => {})
|
98
98
|
db = CouchPotato::Database.new(couchrest_db)
|
99
99
|
@plate = db.load_document '1'
|
100
100
|
@plate.food = 'burger'
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: langalex-couch_potato
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.2.
|
4
|
+
version: 0.2.3
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Alexander Lang
|
@@ -9,7 +9,7 @@ autorequire:
|
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
11
|
|
12
|
-
date: 2009-05-
|
12
|
+
date: 2009-05-18 00:00:00 -07:00
|
13
13
|
default_executable:
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
@@ -65,7 +65,6 @@ files:
|
|
65
65
|
- lib/couch_potato/persistence/belongs_to_property.rb
|
66
66
|
- lib/couch_potato/persistence/callbacks.rb
|
67
67
|
- lib/couch_potato/persistence/dirty_attributes.rb
|
68
|
-
- lib/couch_potato/persistence/inline_collection.rb
|
69
68
|
- lib/couch_potato/persistence/json.rb
|
70
69
|
- lib/couch_potato/persistence/magic_timestamps.rb
|
71
70
|
- lib/couch_potato/persistence/properties.rb
|
@@ -90,6 +89,7 @@ files:
|
|
90
89
|
- spec/unit
|
91
90
|
- spec/unit/attributes_spec.rb
|
92
91
|
- spec/unit/create_spec.rb
|
92
|
+
- spec/unit/database_spec.rb
|
93
93
|
- spec/unit/dirty_attributes_spec.rb
|
94
94
|
- spec/unit/string_spec.rb
|
95
95
|
- spec/unit/view_query_spec.rb
|