couchobject 0.5.0 → 0.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/History.txt +10 -0
- data/Manifest.txt +30 -6
- data/README.txt +580 -42
- data/TODO +2 -2
- data/config/hoe.rb +1 -1
- data/lib/couch_object.rb +7 -2
- data/lib/couch_object/database.rb +19 -34
- data/lib/couch_object/document.rb +13 -6
- data/lib/couch_object/error_classes.rb +110 -0
- data/lib/couch_object/persistable.rb +954 -36
- data/lib/couch_object/persistable/has_many_relations_array.rb +91 -0
- data/lib/couch_object/persistable/meta_classes.rb +568 -0
- data/lib/couch_object/persistable/overloaded_methods.rb +209 -0
- data/lib/couch_object/server.rb +1 -1
- data/lib/couch_object/utils.rb +44 -0
- data/lib/couch_object/version.rb +1 -1
- data/lib/couch_object/view.rb +129 -6
- data/script/console +0 -0
- data/script/destroy +0 -0
- data/script/generate +0 -0
- data/script/txt2html +0 -0
- data/spec/database_spec.rb +23 -31
- data/spec/database_spec.rb.orig +173 -0
- data/spec/document_spec.rb +21 -3
- data/spec/integration/database_integration_spec.rb +46 -15
- data/spec/integration/integration_helper.rb +3 -3
- data/spec/persistable/callback.rb +44 -0
- data/spec/persistable/callback_spec.rb +44 -0
- data/spec/persistable/cloning.rb +77 -0
- data/spec/persistable/cloning_spec.rb +77 -0
- data/spec/persistable/comparing_objects.rb +350 -0
- data/spec/persistable/comparing_objects_spec.rb +350 -0
- data/spec/persistable/deleting.rb +113 -0
- data/spec/persistable/deleting_spec.rb +113 -0
- data/spec/persistable/error_messages.rb +32 -0
- data/spec/persistable/error_messages_spec.rb +32 -0
- data/spec/persistable/loading.rb +339 -0
- data/spec/persistable/loading_spec.rb +339 -0
- data/spec/persistable/new_methods.rb +70 -0
- data/spec/persistable/new_methods_spec.rb +70 -0
- data/spec/persistable/persistable_helper.rb +194 -0
- data/spec/persistable/relations.rb +470 -0
- data/spec/persistable/relations_spec.rb +470 -0
- data/spec/persistable/saving.rb +137 -0
- data/spec/persistable/saving_spec.rb +137 -0
- data/spec/persistable/setting_storage_location.rb +65 -0
- data/spec/persistable/setting_storage_location_spec.rb +65 -0
- data/spec/persistable/timestamps.rb +76 -0
- data/spec/persistable/timestamps_spec.rb +76 -0
- data/spec/persistable/unsaved_changes.rb +211 -0
- data/spec/persistable/unsaved_changes_spec.rb +211 -0
- data/spec/server_spec.rb +5 -5
- data/spec/utils_spec.rb +60 -0
- data/spec/view_spec.rb +40 -7
- data/website/index.html +22 -7
- data/website/index.txt +13 -5
- metadata +93 -61
- data/bin/couch_ruby_view_requestor +0 -81
- data/lib/couch_object/model.rb +0 -5
- data/lib/couch_object/proc_condition.rb +0 -14
- data/spec/model_spec.rb +0 -5
- data/spec/persistable_spec.rb +0 -91
- data/spec/proc_condition_spec.rb +0 -26
@@ -0,0 +1,209 @@
|
|
1
|
+
module CouchObject
|
2
|
+
module Persistable
|
3
|
+
#####
|
4
|
+
#
|
5
|
+
# Overloaded methods
|
6
|
+
#
|
7
|
+
#####
|
8
|
+
|
9
|
+
#
|
10
|
+
# When saved, clones and dupes are stored as separate documents from
|
11
|
+
# the object it originated from
|
12
|
+
#
|
13
|
+
# Returns:
|
14
|
+
# * A new instance of itself where the ID and revision number
|
15
|
+
# is set to nil
|
16
|
+
# * the new instance shares the same storage location as the object
|
17
|
+
# it originates from.
|
18
|
+
#
|
19
|
+
alias couch_object_origianl_clone clone
|
20
|
+
def clone
|
21
|
+
new_clone = self.couch_object_origianl_clone
|
22
|
+
new_clone.instance_variable_set("@id", nil)
|
23
|
+
new_clone.instance_variable_set("@revision", nil)
|
24
|
+
|
25
|
+
# return the new clone
|
26
|
+
new_clone
|
27
|
+
end
|
28
|
+
def dup
|
29
|
+
clone
|
30
|
+
end
|
31
|
+
|
32
|
+
#
|
33
|
+
# Equality is checked for using the following rules:
|
34
|
+
# * if the object types do not match the result is false
|
35
|
+
# * if the object_id of the class sent as an argument is the same
|
36
|
+
# as the object_id of self, equal returns true.
|
37
|
+
# * if the two objects have a different class type it fails
|
38
|
+
# as a result of the object_id test above which can't be true
|
39
|
+
# * fails if the object_id or revision numbers are different
|
40
|
+
# * it fails if one or both of the objects are new and they don't share
|
41
|
+
# the object_id, because in that case they will be stored as
|
42
|
+
# separate documents in the database
|
43
|
+
# * is true if all instance_variables are the same
|
44
|
+
#
|
45
|
+
# Takes:
|
46
|
+
# * +other_object+ which is any object one wishes to compare self to
|
47
|
+
#
|
48
|
+
# Returns:
|
49
|
+
# * true or false
|
50
|
+
#
|
51
|
+
def ==(other_object)
|
52
|
+
return false unless self.class == other_object.class
|
53
|
+
return true if self.object_id == other_object.object_id
|
54
|
+
return false if self.id != other_object.id || \
|
55
|
+
self.revision != other_object.revision
|
56
|
+
return false if self.new? || other_object.new?
|
57
|
+
|
58
|
+
# All relations should be loaded so that the comparison can be realistic
|
59
|
+
has.each do |what_is_has|
|
60
|
+
self.send(what_is_has)
|
61
|
+
other_object.send(what_is_has) if other_object.
|
62
|
+
respond_to?(what_is_has)
|
63
|
+
end
|
64
|
+
belongs_to.each do |what_it_belongs_to|
|
65
|
+
self.send(what_it_belongs_to)
|
66
|
+
other_object.send(what_it_belongs_to) if other_object.
|
67
|
+
respond_to?(what_it_belongs_to)
|
68
|
+
end
|
69
|
+
|
70
|
+
self.instance_variables.each do |var|
|
71
|
+
return false if eval(var).to_s != \
|
72
|
+
other_object.instance_variable_get(var).to_s
|
73
|
+
end
|
74
|
+
|
75
|
+
# has to be true because else it would already have failed :)
|
76
|
+
true
|
77
|
+
end
|
78
|
+
|
79
|
+
#
|
80
|
+
# Goal:
|
81
|
+
# The goal is to return true for the object which has the newest
|
82
|
+
# representation in the database.
|
83
|
+
#
|
84
|
+
# Requires:
|
85
|
+
# * that both objects have timestamps
|
86
|
+
#
|
87
|
+
# Returns:
|
88
|
+
# * false if they are equal objects.
|
89
|
+
# * true if self has been saved while the other_object has not.
|
90
|
+
# * false if self hasn't been saved but the other_object has
|
91
|
+
# * true if both have been saved and self has been saved more recently.
|
92
|
+
# * false if both have been saved but the other object more recently.
|
93
|
+
#
|
94
|
+
# Takes:
|
95
|
+
# * +other_object+ to compare size with
|
96
|
+
#
|
97
|
+
# Raises:
|
98
|
+
# * CantCompareSize when trying to compare two object that have not
|
99
|
+
# been saved or saved but do not have timestamps
|
100
|
+
#
|
101
|
+
# Returns:
|
102
|
+
# * true or false
|
103
|
+
#
|
104
|
+
def >(other_object)
|
105
|
+
return false if self == other_object
|
106
|
+
unless self.new? && other_object.new?
|
107
|
+
if self.class.couch_object_timestamp_on_update? and \
|
108
|
+
other_object.class.couch_object_timestamp_on_update?
|
109
|
+
return ((self.updated_at || 0).to_i \
|
110
|
+
> (other_object.updated_at || 0).to_i) \
|
111
|
+
? true : false
|
112
|
+
elsif self.class.couch_object_timestamp_on_create? and \
|
113
|
+
other_object.class.couch_object_timestamp_on_create?
|
114
|
+
return ((self.created_at || 0).to_i \
|
115
|
+
> (other_object.created_at || 0).to_i) \
|
116
|
+
? true : false
|
117
|
+
else
|
118
|
+
# Both or one of them does not have a timestamp,
|
119
|
+
# so we can't really compare them
|
120
|
+
raise CouchObject::Errors::CantCompareSize
|
121
|
+
end
|
122
|
+
else
|
123
|
+
raise CouchObject::Errors::CantCompareSize
|
124
|
+
end
|
125
|
+
|
126
|
+
end
|
127
|
+
def <(other_object)
|
128
|
+
other_object > self
|
129
|
+
end
|
130
|
+
|
131
|
+
#
|
132
|
+
# <= and >= Uses the results from the methods ==, < and >
|
133
|
+
# to determine the result
|
134
|
+
#
|
135
|
+
# Takes:
|
136
|
+
# * +other_object+ to compare size with
|
137
|
+
#
|
138
|
+
# Raises:
|
139
|
+
# * CantCompareSize when trying to compare two object that have not
|
140
|
+
# been saved or saved but do not have timestamps and that are not equal
|
141
|
+
#
|
142
|
+
# Returns:
|
143
|
+
# * true or false
|
144
|
+
#
|
145
|
+
def <=(other_object)
|
146
|
+
self == other_object || self < other_object ? true : false
|
147
|
+
end
|
148
|
+
def >=(other_object)
|
149
|
+
other_object <= self
|
150
|
+
end
|
151
|
+
|
152
|
+
#
|
153
|
+
# Returns a prettyfied string version of the object
|
154
|
+
#
|
155
|
+
# def inspect
|
156
|
+
# has_many_relations = []
|
157
|
+
#
|
158
|
+
#
|
159
|
+
# has_many.each do |what_it_has|
|
160
|
+
# related_objects = []
|
161
|
+
# objects_it_has = self.send(what_it_has)
|
162
|
+
# unless objects_it_has.size == 0
|
163
|
+
# objects_it_has.each do |obj|
|
164
|
+
# if obj.new?
|
165
|
+
# related_objects << "<#{obj.class}[unsaved]>"
|
166
|
+
# else
|
167
|
+
# related_objects << "<#{obj.class}[#{obj.id}/#{obj.revision}]>"
|
168
|
+
# end
|
169
|
+
# end
|
170
|
+
# end
|
171
|
+
#
|
172
|
+
# what_it_has_string = " #{what_it_has.to_s.capitalize}"
|
173
|
+
# what_it_has_string += ": (#{related_objects.join(", ")})" \
|
174
|
+
# unless related_objects.size == 0
|
175
|
+
#
|
176
|
+
# has_many_relations << what_it_has_string
|
177
|
+
#
|
178
|
+
# end
|
179
|
+
#
|
180
|
+
# has_many_string = ""
|
181
|
+
# belongs_to_string = ""
|
182
|
+
#
|
183
|
+
# has_many_string = " Has many: #{has_many_relations.join(",")}" unless has_many_relations.size == 0
|
184
|
+
#
|
185
|
+
# if belongs_to
|
186
|
+
# object_it_belongs_to = self.send(belongs_to)
|
187
|
+
# if object_it_belongs_to
|
188
|
+
# if object_it_belongs_to.new?
|
189
|
+
# belongs_to_string = " Belongs to: " + \
|
190
|
+
# "#{belongs_to.to_s.capitalize}" + \
|
191
|
+
# "[unsaved]"
|
192
|
+
# else
|
193
|
+
# belongs_to_string = " Belongs to:" + \
|
194
|
+
# " #{belongs_to.to_s.capitalize}" + \
|
195
|
+
# "[#{object_it_belongs_to.id}/#{object_it_belongs_to.revision}]"
|
196
|
+
# end
|
197
|
+
# end
|
198
|
+
# end
|
199
|
+
#
|
200
|
+
# if new?
|
201
|
+
# "<#{self.class}[unsaved]#{belongs_to_string}#{has_many_string}>"
|
202
|
+
# else
|
203
|
+
# "<#{self.class}[#{self.id}/#{self.revision}]" + \
|
204
|
+
# "#{belongs_to_string}#{has_many_string}>"
|
205
|
+
# end
|
206
|
+
#
|
207
|
+
# end
|
208
|
+
end
|
209
|
+
end
|
data/lib/couch_object/server.rb
CHANGED
data/lib/couch_object/utils.rb
CHANGED
@@ -9,5 +9,49 @@ module CouchObject
|
|
9
9
|
end.join("/")
|
10
10
|
end
|
11
11
|
end
|
12
|
+
|
13
|
+
def self.encode_querystring_parameter(parameter)
|
14
|
+
case parameter.class.to_s
|
15
|
+
when "Array"
|
16
|
+
# [12123,"ASD"] => [%2212123%22,%22ASD%22]
|
17
|
+
"[#{(parameter.map {|p| self.fix_parameter(p) }).join(",")}]"
|
18
|
+
else
|
19
|
+
self.fix_parameter(parameter)
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
def self.decode_strings(input)
|
24
|
+
case input.class.to_s
|
25
|
+
when "String"
|
26
|
+
# HTMLEntities.decode_entities(input).toutf8
|
27
|
+
input.toutf8
|
28
|
+
when "Array"
|
29
|
+
input.map! do |n|
|
30
|
+
decode_strings(n)
|
31
|
+
end
|
32
|
+
when "Hash"
|
33
|
+
input.each_pair do |key, value|
|
34
|
+
input[key] = decode_strings(value)
|
35
|
+
end
|
36
|
+
else
|
37
|
+
input
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
protected
|
42
|
+
def self.fix_parameter(p)
|
43
|
+
case p.class.to_s.downcase
|
44
|
+
when "fixnum", "bignum", "trueclass", "falseclass"
|
45
|
+
"#{p.to_s}"
|
46
|
+
when "nilclass"
|
47
|
+
nil
|
48
|
+
else
|
49
|
+
# Sanitize forward slashes
|
50
|
+
# # / => \/
|
51
|
+
val = p.gsub(/\//, "\\/")
|
52
|
+
"%22#{val}%22"
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
12
56
|
end
|
13
57
|
end
|
data/lib/couch_object/version.rb
CHANGED
data/lib/couch_object/view.rb
CHANGED
@@ -1,23 +1,146 @@
|
|
1
|
+
require "net/http"
|
1
2
|
require "enumerator"
|
2
3
|
|
3
4
|
module CouchObject
|
4
5
|
class View
|
6
|
+
|
7
|
+
#
|
8
|
+
# Takes:
|
9
|
+
# * db as CouchObject::Database object or a string containing the database
|
10
|
+
# uri and database name (http://localhost:5984/mydb)
|
11
|
+
# * name (string). The name of the view
|
12
|
+
# * query (JSON string). The JSON document that should be
|
13
|
+
# added to the database
|
14
|
+
#
|
15
|
+
# Returns:
|
16
|
+
# CouchObject::Reponse object instance
|
17
|
+
#
|
18
|
+
# Raises:
|
19
|
+
# * an exeption if it can't figure out the database
|
20
|
+
#
|
5
21
|
def self.create(db, name, query)
|
6
|
-
|
22
|
+
_db = self.get_db(db)
|
23
|
+
# %2F => /
|
24
|
+
_db.put("_design%2F#{name}", query)
|
7
25
|
end
|
8
|
-
|
26
|
+
|
27
|
+
#
|
28
|
+
# Takes:
|
29
|
+
# * db as CouchObject::Database object or a string containing the database
|
30
|
+
# uri and database name (http://localhost:5984/mydb)
|
31
|
+
# * name (string). The name of the view
|
32
|
+
#
|
33
|
+
# Returns:
|
34
|
+
# new CouchObject::View instance
|
35
|
+
#
|
36
|
+
# Raises:
|
37
|
+
# * an exeption if it can't figure out the database
|
38
|
+
#
|
9
39
|
def initialize(db, name)
|
10
|
-
@db = db
|
40
|
+
@db = self.class.get_db(db)
|
11
41
|
@name = name
|
12
42
|
end
|
13
43
|
attr_accessor :db
|
14
44
|
|
15
45
|
def name
|
16
|
-
"
|
46
|
+
"_view/#{@name.dup}"
|
47
|
+
end
|
48
|
+
|
49
|
+
#
|
50
|
+
# Returns an array of the rows returned by the view
|
51
|
+
#
|
52
|
+
# Takes:
|
53
|
+
# * [+params+] (hash): a hash of URL query arguments supported
|
54
|
+
# by couchDB. If omitted it defaults to not use a key
|
55
|
+
# and to update the view.
|
56
|
+
#
|
57
|
+
# Example:
|
58
|
+
#
|
59
|
+
# view.query({:update => false, :key => "bar"}) => Array
|
60
|
+
#
|
61
|
+
# Returns:
|
62
|
+
# * a array of rows from the view
|
63
|
+
#
|
64
|
+
# Raises:
|
65
|
+
# * CouchObject::Errors::MissingView if the view doesn't exist
|
66
|
+
#
|
67
|
+
def query(params = {})
|
68
|
+
|
69
|
+
response = raw_query(params)
|
70
|
+
|
71
|
+
rows_to_return = []
|
72
|
+
response["rows"].each do |params_for_object|
|
73
|
+
rows_to_return << params_for_object["value"]
|
74
|
+
end
|
75
|
+
|
76
|
+
rows_to_return
|
77
|
+
|
78
|
+
end
|
79
|
+
|
80
|
+
#
|
81
|
+
# Returns the response data from CouchDB for a view query without
|
82
|
+
#
|
83
|
+
# Takes:
|
84
|
+
# * [+params+] (hash): a hash of URL query arguments supported
|
85
|
+
# by couchDB. If omitted it defaults to not use a key
|
86
|
+
# and to update the view.
|
87
|
+
#
|
88
|
+
# Example:
|
89
|
+
#
|
90
|
+
# view.raw_query({:update => false, :key => "bar"}) => data
|
91
|
+
#
|
92
|
+
# Returns:
|
93
|
+
# * the response data for the view
|
94
|
+
#
|
95
|
+
# Raises:
|
96
|
+
# * CouchObject::Errors::MissingView if the view doesn't exist
|
97
|
+
#
|
98
|
+
def raw_query(params = {})
|
99
|
+
|
100
|
+
#Create a querystring with the parameters passed inn
|
101
|
+
querystring = "?"
|
102
|
+
params.each_pair do |key, value|
|
103
|
+
querystring += \
|
104
|
+
"#{key}=#{Utils.encode_querystring_parameter(value)}&"
|
105
|
+
end
|
106
|
+
querystring = querystring[0...-1]
|
107
|
+
|
108
|
+
view_with_parameters = name + querystring
|
109
|
+
|
110
|
+
response = JSON.parse(db.get(view_with_parameters).body)
|
111
|
+
|
112
|
+
raise CouchObject::Errors::MissingView, \
|
113
|
+
"The view '#{name}' doesn't exist on the server" \
|
114
|
+
if response["error"] == "not_found"
|
115
|
+
|
116
|
+
raise CouchObject::Errors::MapProcessError \
|
117
|
+
if response["error"] == "map_process_error"
|
118
|
+
|
119
|
+
raise CouchObject::Errors::CouchDBError, \
|
120
|
+
"CouchDB returned and error and described the problem as #{response['reason']}" \
|
121
|
+
if response["error"]
|
122
|
+
|
123
|
+
return response
|
124
|
+
|
17
125
|
end
|
18
126
|
|
19
127
|
def delete
|
20
128
|
@db.delete("/#{db.name}/#{name}")
|
21
129
|
end
|
22
|
-
|
23
|
-
|
130
|
+
|
131
|
+
protected
|
132
|
+
def self.get_db(db)
|
133
|
+
case db.class.to_s
|
134
|
+
when "CouchObject::Database"
|
135
|
+
db
|
136
|
+
when "String"
|
137
|
+
CouchObject::Database.open(db)
|
138
|
+
else
|
139
|
+
raise "You have to supply a database URI " + \
|
140
|
+
"or a CouchObject::Database object"
|
141
|
+
end
|
142
|
+
end
|
143
|
+
|
144
|
+
end
|
145
|
+
end
|
146
|
+
|
data/script/console
CHANGED
File without changes
|
data/script/destroy
CHANGED
File without changes
|
data/script/generate
CHANGED
File without changes
|
data/script/txt2html
CHANGED
File without changes
|
data/spec/database_spec.rb
CHANGED
@@ -3,7 +3,7 @@ require File.dirname(__FILE__) + '/spec_helper.rb'
|
|
3
3
|
describe CouchObject::Database do
|
4
4
|
before(:each) do
|
5
5
|
@server = mock("Couch server")
|
6
|
-
@uri = "http://localhost:
|
6
|
+
@uri = "http://localhost:5984"
|
7
7
|
@response = mock("Net::HTTP::Response")
|
8
8
|
CouchObject::Server.should_receive(:new).with(@uri).and_return(@server)
|
9
9
|
@response.stub!(:code).and_return(200)
|
@@ -19,7 +19,7 @@ describe CouchObject::Database do
|
|
19
19
|
|
20
20
|
it "should create a database" do
|
21
21
|
@server.should_receive(:put).with("/foo", "").and_return(@response)
|
22
|
-
CouchObject::Database.create
|
22
|
+
CouchObject::Database.create(@uri, "foo")
|
23
23
|
end
|
24
24
|
|
25
25
|
it "should delete a database" do
|
@@ -49,7 +49,7 @@ describe CouchObject::Database do
|
|
49
49
|
end
|
50
50
|
|
51
51
|
it "should lint the database name from slashes with ::open" do
|
52
|
-
db = CouchObject::Database.open("http://localhost:
|
52
|
+
db = CouchObject::Database.open("http://localhost:5984/foo")
|
53
53
|
class << db
|
54
54
|
attr_accessor :dbname
|
55
55
|
end
|
@@ -64,10 +64,16 @@ describe CouchObject::Database do
|
|
64
64
|
|
65
65
|
it "should POST" do
|
66
66
|
db = CouchObject::Database.new(@uri, "foo")
|
67
|
-
@server.should_receive(:post).with("/foo/123", "postdata").and_return(@response)
|
67
|
+
@server.should_receive(:post).with("/foo/123", "postdata", "application/json").and_return(@response)
|
68
68
|
db.post("123", "postdata")
|
69
69
|
end
|
70
70
|
|
71
|
+
it "should POST with supplied ContentType header" do
|
72
|
+
db = CouchObject::Database.new(@uri, "foo")
|
73
|
+
@server.should_receive(:post).with("/foo/123", "postdata", "text/rspec").and_return(@response)
|
74
|
+
db.post("123", "postdata", "text/rspec")
|
75
|
+
end
|
76
|
+
|
71
77
|
it "should PUT" do
|
72
78
|
db = CouchObject::Database.new(@uri, "foo")
|
73
79
|
@server.should_receive(:put).with("/foo/123", "postdata").and_return(@response)
|
@@ -76,12 +82,12 @@ describe CouchObject::Database do
|
|
76
82
|
|
77
83
|
it "should DELETE" do
|
78
84
|
db = CouchObject::Database.new(@uri, "foo")
|
79
|
-
@server.should_receive(:delete).with("/foo/123").and_return(@response)
|
80
|
-
db.delete("123")
|
85
|
+
@server.should_receive(:delete).with("/foo/123?rev=456").and_return(@response)
|
86
|
+
db.delete("123", "456")
|
81
87
|
end
|
82
88
|
|
83
89
|
it "should open a new connection from a full uri spec" do
|
84
|
-
proc{ CouchObject::Database.open("http://localhost:
|
90
|
+
proc{ CouchObject::Database.open("http://localhost:5984/foo") }.should_not raise_error
|
85
91
|
end
|
86
92
|
|
87
93
|
it "should know the database name" do
|
@@ -91,7 +97,7 @@ describe CouchObject::Database do
|
|
91
97
|
|
92
98
|
it "should know the full uri" do
|
93
99
|
db = CouchObject::Database.new(@uri, "foo")
|
94
|
-
db.url.should == "http://localhost:
|
100
|
+
db.url.should == "http://localhost:5984/foo"
|
95
101
|
end
|
96
102
|
|
97
103
|
it "should load a document from id with #[]" do
|
@@ -142,31 +148,17 @@ describe CouchObject::Database do
|
|
142
148
|
it "should store a document" do
|
143
149
|
db = CouchObject::Database.new(@uri, "foo")
|
144
150
|
doc = CouchObject::Document.new({"foo" => "bar"})
|
145
|
-
|
151
|
+
|
152
|
+
FakeRespons = Struct.new(:to_document)
|
153
|
+
FakeDocument = Struct.new(:id, :revision)
|
154
|
+
document = \
|
155
|
+
FakeDocument.new("2113826070","id"=>"594F126A80B45C8AC2298E0393E20192")
|
156
|
+
response = FakeRespons.new(document)
|
157
|
+
|
158
|
+
db.should_receive(:post).with("", JSON.unparse("foo" => "bar")).
|
159
|
+
and_return(response)
|
146
160
|
db.store(doc)
|
147
161
|
end
|
148
162
|
|
149
|
-
it "should return the rows when filtering" do
|
150
|
-
db = CouchObject::Database.new(@uri, "foo")
|
151
|
-
rowdata = { "_rev"=>1,
|
152
|
-
"_id"=>"1",
|
153
|
-
"value"=> {
|
154
|
-
"_id"=>"1",
|
155
|
-
"_rev"=>1,
|
156
|
-
"foo"=>"bar"
|
157
|
-
}
|
158
|
-
}
|
159
|
-
resp = mock("response")
|
160
|
-
resp.stub!(:body).and_return(JSON.unparse("rows" => [rowdata]))
|
161
|
-
resp.stub!(:parse).and_return(resp)
|
162
|
-
resp.stub!(:to_document).and_return(
|
163
|
-
CouchObject::Document.new("rows" => [rowdata])
|
164
|
-
)
|
165
|
-
db.should_receive(:post).with("_temp_view", "proc { |doc|\n (doc[\"foo\"] == \"bar\")\n}").and_return(resp)
|
166
|
-
rows = db.filter{|doc| doc["foo"] == "bar"}
|
167
|
-
rows.size.should == 1
|
168
|
-
rows.first["value"]["foo"].should == "bar"
|
169
|
-
end
|
170
|
-
|
171
163
|
#it "should url encode paths"
|
172
164
|
end
|