ShyCouch 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/Rakefile CHANGED
@@ -31,21 +31,20 @@ Jeweler::RubygemsDotOrgTasks.new
31
31
  require 'rake/testtask'
32
32
  Rake::TestTask.new(:test) do |test|
33
33
  test.libs << 'lib' << 'test'
34
- test.pattern = 'test/**/test_*.rb'
34
+ test.pattern = 'test/test_ShyCouch.rb'
35
35
  test.verbose = true
36
36
  end
37
37
 
38
38
  require 'rcov/rcovtask'
39
39
  Rcov::RcovTask.new do |test|
40
40
  test.libs << 'test'
41
- test.pattern = 'test/**/test_*.rb'
41
+ test.pattern = 'test/test_ShyCouch.rb'
42
42
  test.verbose = true
43
43
  test.rcov_opts << '--exclude "gems/*"'
44
44
  end
45
45
 
46
46
  task :default => :test
47
47
 
48
- # require 'rake/rdoctask'
49
48
  require 'rdoc/task'
50
49
  RDoc::Task.new do |rdoc|
51
50
  version = File.exist?('VERSION') ? File.read('VERSION') : ""
@@ -5,11 +5,11 @@
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = %q{ShyCouch}
8
- s.version = "0.5.0"
8
+ s.version = "0.6.0"
9
9
 
10
10
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
11
  s.authors = [%q{Shy Inc.}, %q{Daniel Bryan}, %q{Cerales}]
12
- s.date = %q{2011-09-18}
12
+ s.date = %q{2011-09-24}
13
13
  s.description = %q{Ruby API for CouchDB, designed to work with the Camping micro-framework.}
14
14
  s.email = %q{danbryan@gmail.com}
15
15
  s.extra_rdoc_files = [
@@ -30,8 +30,6 @@ Gem::Specification.new do |s|
30
30
  "lib/ShyCouch/data.rb",
31
31
  "lib/ShyCouch/fields.rb",
32
32
  "test/helper.rb",
33
- "test/old-test.rb",
34
- "test/old-tests.rb",
35
33
  "test/test_ShyCouch.rb",
36
34
  "test/test_couch_document.rb",
37
35
  "test/test_couchdb_api.rb",
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.5.0
1
+ 0.6.0
@@ -14,7 +14,6 @@ require 'resolv'
14
14
  require 'rest-client'
15
15
  require 'ShyRubyJS'
16
16
  # require everything from the 'ShyCouch' subdirectory
17
- # Dir.new(File.dirname(__FILE__)+'/ShyCouch').each { |f| require 'shycouch/' + f.split('.')[0] unless f == '.' or f == '..' }
18
17
  require 'ShyCouch/data'
19
18
  require 'ShyCouch/fields'
20
19
 
@@ -22,16 +21,18 @@ require 'ShyCouch/fields'
22
21
  module ShyCouch
23
22
  class << self
24
23
  def getDB(settings)
25
- # this is a wrapper for create a CouchDatabase object and testing that it can connect
24
+ # this is a wrapper for creating CouchDatabase object and testing that it can connect
26
25
  database = CouchDatabase.new(settings)
27
26
  puts database.connect unless database.connect["ok"] #TODO - hm
28
- database.create unless database.on_server?
27
+ database.create! unless database.exists?
29
28
  return database
30
29
  end
31
30
  end
32
31
  attr_accessor :database
33
32
 
34
33
  class ShyCouchError < StandardError; end
34
+
35
+ class ShyCouchDesignMissing < ShyCouchError; end
35
36
 
36
37
  class CouchDatabase
37
38
  def initialize(settings)
@@ -39,7 +40,7 @@ module ShyCouch
39
40
  init(settings)
40
41
  end
41
42
 
42
- attr_accessor :server, :name, :host, :port, :design_documents
43
+ attr_accessor :server, :name, :host, :port, :design_documents, :designs
43
44
 
44
45
  def connect
45
46
  @server = CouchServerConnection.new({"host"=>@host, "port"=>@port, "user"=>@user, "password"=>@password, "database" => @name})
@@ -49,24 +50,37 @@ module ShyCouch
49
50
  return {"ok"=>false, "message"=>"Could not connect to the couch database."}
50
51
  end
51
52
  end
52
- def delete_database
53
+ def delete!
53
54
  @server.delete_db(self.name)
54
55
  end
55
56
  def server_responds?; return @server.responds?; end
56
57
 
57
- def on_server?
58
- @server.has_database?(@name)
59
- end
58
+ def design(design)
59
+ if design.kind_of?(ShyCouch::Data::Design)
60
+ return design_by_name(design.name)
61
+ else
62
+ return design_by_name(design)
63
+ end
64
+ end
65
+
66
+ def design_by_name(name)
67
+ @designs.each { |design| return design if design.name == name.to_s }
68
+ return nil
69
+ end
60
70
 
61
- def create
71
+ def exists?
72
+ @server.has_database?(@name)
73
+ end
74
+ def create!
62
75
  @server.create_db(@name)
63
76
  end
64
77
  def get_document_by_id(id)
65
78
  @server.get_document_by_id(@name, id)
66
79
  end
67
- def get_design_document_by_id(id)
68
- doc = @server.get_document_by_id(@name, id)
69
- ShyCouch::Data::Design.new(id).merge! doc
80
+
81
+ def pull_design(designName)
82
+ doc = @server.get_document_by_id(@name, designName)
83
+ return ShyCouch::Data::Design.new(designName).merge! doc
70
84
  end
71
85
  def all_docs
72
86
  get_document_by_id('_all_docs').rows.map { |doc|
@@ -78,27 +92,44 @@ module ShyCouch
78
92
  end
79
93
 
80
94
  def pull_document(document)
81
- @server.pull_document(self.name, document)
95
+ @server.pull_document(self.name, document)
82
96
  end
83
97
 
84
- def push_document(document)
98
+ def push_document!(document)
85
99
  @server.push_document(self.name, document)
86
100
  end
87
101
 
88
- def add_design_document(design)
89
- @design_documents << design
102
+ def query_view(design_name, view_name)
103
+ queryString = "/_design/#{design_name}/_view/#{view_name}"
104
+ ShyCouch::Data::ViewResult.new(get_document_by_id(queryString))
105
+ end
106
+
107
+ def add_design(design)
108
+ throw TypeError unless design.kind_of?(ShyCouch::Data::Design)
109
+ # if the db has already stored the design, update it
110
+ if design_by_name(design.name) != nil
111
+ design_by_name(design.name) == design
112
+ end
113
+ # otherwise, add it
114
+ @designs << design
90
115
  end
91
116
 
92
- def add_design_documents_and_push(*docs)
117
+ def add_designs_and_push!(*docs)
93
118
  docs.each do |doc|
94
- @design_documents << doc
119
+ add_design(doc)
95
120
  end
96
- push_design_documents
121
+ push_designs!
122
+ end
123
+
124
+ def add_design_and_push!(doc)
125
+ add_design(doc)
126
+ push_designs!
97
127
  end
98
128
 
99
- def push_design_documents
100
- @design_documents.each do |design|
101
- design.push(self)
129
+ def push_designs!
130
+ @designs.each do |design|
131
+ # push the document and update it with the rev sent by the response
132
+ design["_rev"] = push_document!(design)["rev"]
102
133
  end
103
134
  end
104
135
 
@@ -112,7 +143,7 @@ module ShyCouch
112
143
  def init(settings, design_documents = [])
113
144
  db_settings = settings["db"]
114
145
  @host, @port, @name, @user, @password = db_settings["host"],db_settings["port"], db_settings["name"],db_settings["user"], db_settings["password"]
115
- @design_documents = design_documents
146
+ @designs = ShyCouch::Data::CouchDocumentCollection.new
116
147
  @server = CouchServerConnection.allocate
117
148
  end
118
149
 
@@ -142,15 +173,11 @@ module ShyCouch
142
173
  rescue RestClient::ResourceNotFound
143
174
  false
144
175
  end
145
-
146
- # def get_database_info(db_name)
147
- # get("/#{db+name}/")
148
- # end
149
176
 
150
177
  def req(kind, uri, data = nil)
151
178
  raise TypeError unless [:get,:delete,:put,:post].include?(kind) # only support these 4 request methods currently
152
179
  res = (@user and @password ? couch_req_with_auth(kind, uri, data) : couch_req_without_auth(kind, uri, data))
153
- JSON.parse(res)
180
+ return JSON.parse(res)
154
181
  end
155
182
  def req_host
156
183
  "http://#{(@user + ':' + @password + '@') if @user and @password}#{@host}:#{@port}"
@@ -172,12 +199,6 @@ module ShyCouch
172
199
  end
173
200
 
174
201
  end
175
-
176
- # this should be done w/ couch key stuff?
177
- # def pull_all_design_docs(db_name)
178
- # pull_all_doc_ids(db_name).map { get_document_by_id(db_name, id) if id[0,7] == "_design" }
179
- # end
180
-
181
202
  #TODO - this is screwed
182
203
  def pull_all_doc_ids(db_name)
183
204
  req(:get,"/#{db_name}/_all_docs")["rows"].map { |doc| doc["id"] }
@@ -188,10 +209,10 @@ module ShyCouch
188
209
  end
189
210
 
190
211
  def get_document_by_id(db_name, id)
191
- document = Data::CouchDocument.new(req(:get,"/#{db_name}/#{id}"))
212
+ document = Data::CouchDocument.new(:data => req(:get,"/#{db_name}/#{id}"))
192
213
  end
193
214
  def pull_document(db_name, document)
194
- document = Data::CouchDocument.new(req(:get,"/#{db_name}/#{document._id}"))
215
+ document = Data::CouchDocument.new(:data => req(:get,"/#{db_name}/#{document._id}"))
195
216
  end
196
217
 
197
218
  def delete_document(db_name, id)
@@ -202,12 +223,15 @@ module ShyCouch
202
223
  # Haven't decided whether PUT/POST should take a CouchDocument or a JSON string.
203
224
 
204
225
  def push_document(db_name, document)
205
- raise TypeError unless document.kind_of?(Data::CouchDocument)
226
+ raise TypeError unless document.kind_of?(ShyCouch::Data::CouchDocument)
206
227
  raise JSON::GeneratorError unless document.valid?
207
228
  if document["_rev"]
208
- req(:put, "/#{db_name}/#{document._id}?rev=#{document._rev}/", document.to_json)
209
- else
210
- req(:post, "/#{db_name}/", document.to_json)
229
+ # puts "/#{db_name}/#{document._id}?rev=#{document._rev}/" #TODO - remove
230
+ return req(:put, "/#{db_name}/#{document._id}?rev=#{document._rev}/", document.to_json)
231
+ elsif document["_id"]
232
+ return req(:put, "/#{db_name}/#{document._id}", document.to_json)
233
+ else
234
+ return req(:post, "/#{db_name}/", document.to_json)
211
235
  end
212
236
  end
213
237
 
@@ -8,11 +8,24 @@ module ShyCouch
8
8
  end
9
9
  @@needs, @@suggests, @@views = [], [], []
10
10
 
11
- def initialize(hash={})
11
+ def initialize(opts={})
12
12
  # Assumes that the "kind" is the class name unless explicitly stated otherwise
13
13
  # TODO - maybe just force it to be the class name no matter what tbh
14
- hash["kind"] = self.class.to_s.split("::").last unless hash["kind"]
15
- merge!(hash)
14
+
15
+ # this is messy.
16
+ # If there's some data given, see whether it has a kind.
17
+ if opts[:data]
18
+ if !opts[:data]["kind"]
19
+ # If there's no kind, give the 'kind' the class name as a value
20
+ opts[:data]["kind"] = self.class.to_s.split("::").last
21
+ end
22
+ else
23
+ # if there's no data, give it data and a kind
24
+ opts[:data] = {"kind" => self.class.to_s.split("::").last}
25
+ end
26
+
27
+ merge!(opts[:data])
28
+ @database = opts[:push_to] if opts[:push_to]
16
29
  raise TypeError unless valid?
17
30
  set_up_views
18
31
  end
@@ -56,16 +69,24 @@ module ShyCouch
56
69
  return self.class.requirements
57
70
  end
58
71
 
59
- def pull(database)
60
- new_doc = database.pull_document(self)
72
+ def pull(db = nil)
73
+ db ||= @database
74
+ new_doc = db.pull_document(self)
75
+ return new_doc
76
+ end
77
+
78
+ def pull!(db = nil)
79
+ db ||= @database
80
+ new_doc = pull(db)
61
81
  if new_doc
62
82
  self.clear
63
83
  self.merge! new_doc
64
84
  end
65
85
  end
66
86
 
67
- def push(database)
68
- res = database.push_document(self)
87
+ def push!(database=nil)
88
+ database ||= @database
89
+ res = database.push_document!(self)
69
90
  self["_id"] = res["id"] unless self["_id"]
70
91
  self["_rev"] = res["rev"]
71
92
  return res
@@ -133,16 +154,65 @@ module ShyCouch
133
154
  return {"map" => @map, "reduce" => @reduce}
134
155
  end
135
156
  end
157
+
158
+ class ViewResult < Array
159
+ attr_accessor :total_rows, :offset
160
+ def initialize(res)
161
+ @total_rows = res["total_rows"]
162
+ @offset = res["offset"]
163
+ concat res["rows"]
164
+ end
165
+ end
166
+
167
+ class CouchDocumentCollection < Array
168
+ def <<(obj)
169
+ raise TypeError unless obj.kind_of?(ShyCouch::Data::CouchDocument)
170
+ super
171
+ end
172
+
173
+ def initialize(opts = {})
174
+ @database = opts[:push_to] if opts[:push_to]
175
+ end
176
+
177
+ def pull_all(db = nil)
178
+ db ||= @database
179
+ collection = CouchDocumentCollection.new
180
+ each do |item|
181
+ collection << db.pull_document(item)
182
+ end
183
+ return collection
184
+ end
185
+
186
+ def pull_all!(db = nil)
187
+ db ||= @database
188
+ each do |item|
189
+ item.pull!(db)
190
+ end
191
+ end
192
+
193
+ def push_all!(db = nil)
194
+ db ||= @database
195
+ each do |item|
196
+ item.push!(db)
197
+ end
198
+ end
199
+
200
+ end
136
201
 
137
202
  class Design < CouchDocument
138
203
  # this is used to manage design documents
139
204
  # In practise, the Controllers should be a list of classes corresponding to design documents
140
205
 
141
- def initialize(name, views=[])
206
+ def initialize(name, opts = {})
142
207
  merge! "_id" => "_design/#{name.to_s}"
143
208
  @parser = ShyRubyJS::ShySexpParser.new
144
- @views = views
145
- merge_views
209
+ views = opts[:views] if opts[:views]
210
+ merge_views(views) if views
211
+ @database = opts[:push_to] if opts[:push_to]
212
+ end
213
+
214
+ def name
215
+ return self["_id"].split("_design/").drop(1).join
146
216
  end
147
217
 
148
218
  def add_view(view)
@@ -151,15 +221,28 @@ module ShyCouch
151
221
  merge_views
152
222
  end
153
223
 
224
+ def query_view(view, db = nil)
225
+ db ||= @database
226
+ raise ShyCouchError, "No CouchDB defined" unless db
227
+ view = view.name if view.kind_of?(ShyCouch::Data::View)
228
+ #TODO - something
229
+ db.query_view(self.name, view)
230
+ end
231
+
154
232
  def view(view_name, &block)
155
233
  add_view(ShyCouch::Data::View.new(view_name, &block))
156
234
  end
235
+ def push!(db = nil)
236
+ db ||= @database
237
+ raise ShyCouchError, "No CouchDB defined" unless db
238
+ db.add_design_and_push!(self)
239
+ end
157
240
 
158
241
  private
159
242
 
160
- def merge_views
243
+ def merge_views(views)
161
244
  h = { "views" => {}}
162
- @views.each do |view|
245
+ views.each do |view|
163
246
  h["views"][view.name] = view.functions
164
247
  end
165
248
  merge! h
@@ -16,6 +16,28 @@ $settings = {
16
16
  },
17
17
  }
18
18
 
19
+ class ShyCouchTestHelper < Test::Unit::TestCase
20
+ # The majority of the tests in this suite need the setup provided in here
21
+ # And it means I don't forget to delete the database in their teardown functions
22
+ def setup
23
+ valid_settings = $settings
24
+ @couchdb = ShyCouch.getDB(valid_settings)
25
+ end
26
+ def teardown
27
+ @couchdb.delete!
28
+ @couchdb = nil
29
+ end
30
+
31
+ def add_some_documents
32
+ 4.times do
33
+ recipe = Recipe.new(:push_to => @couchdb)
34
+ recipe.push!
35
+ end
36
+ end
37
+
38
+ class Recipe < ShyCouch::Data::CouchDocument; end
39
+ end
40
+
19
41
  # test ShyCouch::CouchDBAPI
20
42
  require_relative 'test_couchdb_api'
21
43
 
@@ -9,7 +9,7 @@ class CouchDocumentTests
9
9
  @couchdb = ShyCouch.getDB(valid_settings)
10
10
  end
11
11
  def teardown
12
- @couchdb.delete_database
12
+ @couchdb.delete!
13
13
  @couchdb = nil
14
14
  end
15
15
 
@@ -30,7 +30,7 @@ class CouchDocumentTests
30
30
  def test_create_from_string
31
31
  # Ensure no doc creation with fixnum argument
32
32
  string = "hehe i'm all over here you know"
33
- assert_raises IndexError do
33
+ assert_raises TypeError do
34
34
  doc = ShyCouch::Data::CouchDocument.new(string)
35
35
  end
36
36
  end
@@ -57,26 +57,25 @@ class CouchDocumentTests
57
57
 
58
58
 
59
59
  @valid_documents = [
60
- ShyCouch::Data::CouchDocument.new({"kind"=>"post", "message"=>"BUY TRAMADOL ONLINE!!"}),
61
- ShyCouch::Data::CouchDocument.new({"kind"=>"comment",
60
+ ShyCouch::Data::CouchDocument.new(:data => {"kind"=>"post", "message"=>"BUY TRAMADOL ONLINE!!"}),
61
+ ShyCouch::Data::CouchDocument.new(:data => {"kind"=>"comment",
62
62
  "message"=>"gry gry online gry gry online gry gry online gry gry online gry gry online "}),
63
- ShyCouch::Data::CouchDocument.new({"kind"=>"tag", "name"=>"FREE CANADIAN PRESCRIPTION DRUGS"}),
64
- ShyCouch::Data::CouchDocument.new({"kind"=>"helpers",
63
+ ShyCouch::Data::CouchDocument.new(:data => {"kind"=>"tag", "name"=>"FREE CANADIAN PRESCRIPTION DRUGS"}),
64
+ ShyCouch::Data::CouchDocument.new(:data => {"kind"=>"helpers",
65
65
  "helpers"=>["helper", "bad helper", "terrible helper", "this isn't helping"],
66
66
  "actually_helpful"=>false, "times_helped"=>0}),
67
67
  ]
68
68
  @existing_valid_documents = [
69
- ShyCouch::Data::CouchDocument.new("whatever"=>"yep"),
70
- ShyCouch::Data::CouchDocument.new("is_a_document"=>true, "number_of_docs_this_is"=>1)
69
+ ShyCouch::Data::CouchDocument.new(:data => {"whatever"=>"yep"}),
70
+ ShyCouch::Data::CouchDocument.new(:data => {"is_a_document"=>true, "number_of_docs_this_is"=>1})
71
71
  ].each { |doc|
72
- doc.push($couchdb)
72
+ doc.push!($couchdb)
73
73
  }
74
74
  @invalid_documents = nil # make sure user can't set rev maybe? or is that legal?
75
75
  end
76
76
  def teardown
77
- $couchdb.delete_database
77
+ $couchdb.delete!
78
78
  $couchdb = nil
79
- # delete the database
80
79
  end
81
80
 
82
81
  def test_keys_as_attr_accessors
@@ -91,7 +90,7 @@ class CouchDocumentTests
91
90
  def test_push_new_documents
92
91
  @valid_documents.each { |doc|
93
92
  # put the document on the server, grab the server's response
94
- res = doc.push($couchdb)
93
+ res = doc.push!($couchdb)
95
94
  # check that the server included "ok"=>true in its response
96
95
  assert(res["ok"])
97
96
  # check that the doc now has an id and a rev
@@ -116,7 +115,7 @@ class CouchDocumentTests
116
115
  doc.buttonCount = 5
117
116
  doc.friends = ["alan", "alex", "all me other mates"]
118
117
 
119
- res = doc.push($couchdb)
118
+ res = doc.push!($couchdb)
120
119
  assert(res["ok"])
121
120
 
122
121
  # pull it from the database again
@@ -133,10 +132,110 @@ class CouchDocumentTests
133
132
  @existing_valid_documents.each { |doc|
134
133
  doc._rev = "hurr"
135
134
  assert_raise RestClient::BadRequest do
136
- res = doc.push($couchdb)
135
+ res = doc.push!($couchdb)
137
136
  end
138
137
  }
139
138
  end
140
139
 
141
140
  end
142
- end
141
+ end
142
+
143
+ class CouchDocumentCollectionPushingAndPulling < ShyCouchTestHelper
144
+
145
+ def setup
146
+ super
147
+ @collection = ShyCouch::Data::CouchDocumentCollection.new(:push_to => @couchdb)
148
+ 4.times do
149
+ @collection << Recipe.new
150
+ end
151
+ end
152
+
153
+ def test_push_all_docs
154
+ assert_nothing_raised Exception do
155
+ @collection.push_all!
156
+ end
157
+ end
158
+
159
+ def test_pull_all_docs
160
+ @collection.push_all!
161
+ collection2 = @collection.pull_all
162
+ @collection.each_with_index do |item, i|
163
+ assert_equal(item, collection2[i])
164
+ end
165
+ end
166
+
167
+ def test_pull_all_docs_forcefully
168
+ # tests pulling w/ exclamation yo
169
+ @collection.push_all!
170
+ backupCollection = @collection.clone
171
+ @collection.pull_all!
172
+ @collection.each_with_index do |item, i|
173
+ assert_equal(backupCollection[i], item)
174
+ end
175
+ end
176
+
177
+ def teardown; super; end
178
+
179
+ end
180
+
181
+ # class CouchDocumentCollectionTests < ShyCouchTestHelper
182
+ # # Test for:
183
+ # # * calling a view returns a document collection
184
+ # # * treating it like an array gives access to rows
185
+ # # * the metadata that is returned with a view is accessible as object attributes
186
+ #
187
+ # class Leg < ShyCouch::Data::CouchDocument; end #for testing
188
+ #
189
+ # def setup
190
+ # super
191
+ # @view = ShyCouch::Data::View.new :legs do
192
+ # map do
193
+ # emit(doc.key, doc.name) if(doc.kind == "Leg")
194
+ # end
195
+ # end
196
+ # @design = ShyCouch::Data::Design.new :cool, { :views => [@view], :push_to => $couchdb }
197
+ # @couchdb.add_design_and_push!(@design)
198
+ # @legDocument = Leg.new(:push_to => @couchdb).push!
199
+ # @legDocumentTwo = Leg.new(:push_to => @couchdb).push!
200
+ # end
201
+ #
202
+ # def test_view_returns_collection
203
+ # collection = $couchdb.design(:cool).view(:butts)
204
+ # assert_kind_of(ShyCouch::Data::DocumentCollection, collection)
205
+ # end
206
+ #
207
+ # def test_view_metadata_are_attrs
208
+ # collection = $couchdb.design(:cool).view(:butts)
209
+ # assert(collection.respond_to? :total_rows)
210
+ # assert(collection.respond_to? :offset)
211
+ # end
212
+ #
213
+ # def test_doc_collection_takes_couch_doc
214
+ # collection = ShyCouch::Data::CouchDocumentCollection.new
215
+ # assert_nothing_raised Exception do
216
+ # collection << ShyCouch::Data::CouchDocument.new
217
+ # end
218
+ # end
219
+ #
220
+ # def test_doc_collection_rejects_wrong_type
221
+ # collection = ShyCouch::Data::CouchDocumentCollection.new
222
+ # assert_raises TypeError do
223
+ # collection << 1
224
+ # end
225
+ # assert_raises TypeError do
226
+ # collection << "Nice!"
227
+ # end
228
+ # end
229
+ #
230
+ # def test_document_collection_has_documents
231
+ # collection = $couchdb.design(:cool).view(:butts)
232
+ #
233
+ # assert(collection.has_row_with(:id,legDocument["id"]))
234
+ # assert(collection.has_row_with(:id,legDocument["id"]))
235
+ # end
236
+ #
237
+ # def teardown
238
+ # super
239
+ # end
240
+ #
241
+ # end
@@ -8,7 +8,7 @@ class TestCouchDBAPI < Test::Unit::TestCase
8
8
  end
9
9
 
10
10
  def teardown
11
- $database.delete_database
11
+ $database.delete!
12
12
  $database = nil
13
13
  end
14
14
 
@@ -2,56 +2,29 @@ require 'test/unit'
2
2
  require_relative '../lib/ShyCouch.rb'
3
3
 
4
4
  class DesignDocumentTests
5
- class TestDesignDocument < Test::Unit::TestCase
6
- Design = ShyCouch::Data::Design
7
- CouchDocument = ShyCouch::Data::CouchDocument
8
-
9
- class Recipe < CouchDocument
10
-
11
- end
12
-
5
+ class ShyCouchDesignTestHelper < ShyCouchTestHelper
13
6
  def setup
14
- valid_settings = $settings
15
- @couchdb = ShyCouch.getDB(valid_settings)
7
+ super
8
+ # add some docs to the database
9
+ @documents = add_some_documents
10
+ # make some views
16
11
  @views = setup_views
17
- @design = nil
12
+ # make a design, push it
13
+ @design = setup_design_document
14
+ @design.push!
18
15
  end
19
16
  def teardown
20
- @couchdb.delete_database
21
- @couchdb = nil
22
- end
23
-
24
-
25
-
26
- def test_create_design
27
- assert_nothing_raised {
28
- @design = setup_design_document
29
- }
30
- end
31
-
32
- def test_push_to_db
33
- design = setup_design_document
34
- @couchdb.add_design_documents_and_push(design)
35
- new_doc = @couchdb.get_design_document_by_id(design._id)
36
- assert_equal(design.as_hash, new_doc.as_hash)
17
+ super
37
18
  end
38
-
39
- def test_call_views
40
- design = setup_design_document
41
- @couchdb.add_design_documents_and_push(design)
42
- add_some_documents
43
- # puts design.views["count_recipes"]
44
- end
45
-
46
19
  def setup_views
47
20
  view1 = ShyCouch::Data::View.new :recipes do
48
21
  map do
49
- emit(doc._id, doc.name) if doc.kind == 'Recipe'
22
+ emit(doc.name, null) if doc.kind == "Recipe"
50
23
  end
51
24
  end
52
- view2 = ShyCouch::Data::View.new :count_recipes do
25
+ view2 = ShyCouch::Data::View.new :recipe_count do
53
26
  map do
54
- emit(doc._id) if doc.kind == 'Recipe'
27
+ emit(doc.name, null) if doc.kind == "Recipe"
55
28
  end
56
29
  reduce do
57
30
  return sum(values)
@@ -59,13 +32,114 @@ class DesignDocumentTests
59
32
  end
60
33
  return [view1, view2]
61
34
  end
35
+
62
36
  def setup_design_document
63
- return ShyCouch::Data::Design.new :test_design, @views
37
+ return ShyCouch::Data::Design.new :food, {:views => @views, :push_to => @couchdb }
64
38
  end
39
+
65
40
  def add_some_documents
66
41
  4.times do
67
- Recipe.new.push(@couchdb)
42
+ recipe = Recipe.new(:push_to => @couchdb)
43
+ recipe.push!
68
44
  end
69
45
  end
70
46
  end
47
+
48
+ class TestDesignDocument < ShyCouchDesignTestHelper
49
+ Design = ShyCouch::Data::Design
50
+ CouchDocument = ShyCouch::Data::CouchDocument
51
+
52
+ class Recipe < CouchDocument; end
53
+
54
+ def setup
55
+ super
56
+ end
57
+ def teardown
58
+ super
59
+ end
60
+
61
+ def test_create_design
62
+ assert_nothing_raised {
63
+ @design = setup_design_document
64
+ }
65
+ end
66
+
67
+ def test_create_design_to_db
68
+ new_doc = @couchdb.pull_design(@design._id)
69
+ assert_equal(@design.as_hash, new_doc.as_hash)
70
+ end
71
+ end
72
+
73
+ class TestDesignsInDatabase < ShyCouchDesignTestHelper
74
+ def setup
75
+ super
76
+ end
77
+
78
+ def teardown
79
+ super
80
+ end
81
+
82
+ # three different ways of calling the design
83
+ def test_get_design_1
84
+ result = @couchdb.design(@design.name)
85
+ assert_equal(@design, result)
86
+ end
87
+ def test_get_design_2
88
+ result = @couchdb.design(@design)
89
+ assert_equal(@design, result)
90
+ end
91
+ def test_get_design_3
92
+ result = @couchdb.design(:food)
93
+ assert_equal(@design, result)
94
+ end
95
+
96
+ def test_modify_design_and_push
97
+ @design.views["recipe_count"].delete("map")
98
+ @design.push!
99
+ end
100
+
101
+ end
102
+
103
+ class TestCallViewFromDesign < ShyCouchDesignTestHelper
104
+ def setup
105
+ super
106
+ end
107
+
108
+ def teardown
109
+ super
110
+ end
111
+
112
+ def test_call_view_by_name
113
+ # for the map view:
114
+ result = @couchdb.design(@design).query_view(:recipes)
115
+ # test that we got the right kind of object:
116
+ assert_kind_of(ShyCouch::Data::ViewResult, result)
117
+ # test that the object has the expected number of rows:
118
+ assert_equal(4, result.length)
119
+
120
+ # for the reduce view:
121
+ result = @couchdb.design(@design).query_view(:recipe_count)
122
+ assert_kind_of(ShyCouch::Data::ViewResult, result)
123
+ assert_equal(1, result.length)
124
+ assert_respond_to(result, :total_rows)
125
+ assert_respond_to(result, :offset)
126
+ end
127
+
128
+ def test_call_view_with_view_object
129
+ # for the map view:
130
+ result = @couchdb.design(@design).query_view(@views[0])
131
+ # test that we got the right kind of object:
132
+ assert_kind_of(ShyCouch::Data::ViewResult, result)
133
+ # test that the object has the expected number of rows:
134
+ assert_equal(4, result.length)
135
+ # and that it responds to offset and total rows as method calls:
136
+ assert_respond_to(result, :total_rows)
137
+ assert_respond_to(result, :offset)
138
+
139
+ # for the reduce view:
140
+ # TODO
141
+ end
142
+
143
+ end
144
+
71
145
  end
@@ -15,13 +15,8 @@ class CouchViewTests < Test::Unit::TestCase
15
15
  end
16
16
  def teardown; end
17
17
 
18
- class Leg < ShyCouch::Data::CouchDocument
19
-
20
- end
21
18
 
22
- def test_query_all
23
-
24
- end
19
+
25
20
 
26
21
  # def test_define_map_view
27
22
  # view :five_star_butts do
@@ -50,4 +45,26 @@ class CouchViewTests < Test::Unit::TestCase
50
45
  # assert_equal(expected_reduce, @couch_views[0].reduce)
51
46
  # end
52
47
 
48
+ end
49
+
50
+ class CouchDefaultViewTests < ShyCouchTestHelper
51
+ # define a class that should have an 'all' method to get all instances of that object
52
+ class Leg < ShyCouch::Data::CouchDocument; end
53
+ def setup
54
+ super
55
+ # add some instances of the object
56
+ @test_docs = []
57
+ @test_docs << Leg.new(:push_to => @couchdb, :data => {"length"=>30}).push!
58
+ @test_docs << Leg.new(:push_to => @couchdb, :data => {"length"=>18, "broken"=>true}).push!
59
+ end
60
+ def teardown
61
+ super
62
+ end
63
+ #
64
+ # def test_query_all
65
+ # @all_legs = Leg.all
66
+ # assert_equal(@test_docs.length, @all_legs.length)
67
+ # assert_kind_of(ShyCouch::CouchDocumentCollection, @all_legs)
68
+ # # also test that the doc values worked, and that the response has the docs in it, etc.
69
+ # end
53
70
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ShyCouch
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.5.0
4
+ version: 0.6.0
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -11,11 +11,11 @@ authors:
11
11
  autorequire:
12
12
  bindir: bin
13
13
  cert_chain: []
14
- date: 2011-09-18 00:00:00.000000000Z
14
+ date: 2011-09-24 00:00:00.000000000Z
15
15
  dependencies:
16
16
  - !ruby/object:Gem::Dependency
17
17
  name: ShyRubyJS
18
- requirement: &70144500883400 !ruby/object:Gem::Requirement
18
+ requirement: &70284357957800 !ruby/object:Gem::Requirement
19
19
  none: false
20
20
  requirements:
21
21
  - - ! '>='
@@ -23,10 +23,10 @@ dependencies:
23
23
  version: '0'
24
24
  type: :runtime
25
25
  prerelease: false
26
- version_requirements: *70144500883400
26
+ version_requirements: *70284357957800
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: bundler
29
- requirement: &70144500899300 !ruby/object:Gem::Requirement
29
+ requirement: &70284357957320 !ruby/object:Gem::Requirement
30
30
  none: false
31
31
  requirements:
32
32
  - - ~>
@@ -34,10 +34,10 @@ dependencies:
34
34
  version: 1.0.0
35
35
  type: :development
36
36
  prerelease: false
37
- version_requirements: *70144500899300
37
+ version_requirements: *70284357957320
38
38
  - !ruby/object:Gem::Dependency
39
39
  name: jeweler
40
- requirement: &70144500898820 !ruby/object:Gem::Requirement
40
+ requirement: &70284357956840 !ruby/object:Gem::Requirement
41
41
  none: false
42
42
  requirements:
43
43
  - - ~>
@@ -45,10 +45,10 @@ dependencies:
45
45
  version: 1.6.4
46
46
  type: :development
47
47
  prerelease: false
48
- version_requirements: *70144500898820
48
+ version_requirements: *70284357956840
49
49
  - !ruby/object:Gem::Dependency
50
50
  name: rcov
51
- requirement: &70144500898340 !ruby/object:Gem::Requirement
51
+ requirement: &70284357956360 !ruby/object:Gem::Requirement
52
52
  none: false
53
53
  requirements:
54
54
  - - ! '>='
@@ -56,10 +56,10 @@ dependencies:
56
56
  version: '0'
57
57
  type: :development
58
58
  prerelease: false
59
- version_requirements: *70144500898340
59
+ version_requirements: *70284357956360
60
60
  - !ruby/object:Gem::Dependency
61
61
  name: sourcify
62
- requirement: &70144500897860 !ruby/object:Gem::Requirement
62
+ requirement: &70284357955880 !ruby/object:Gem::Requirement
63
63
  none: false
64
64
  requirements:
65
65
  - - ~>
@@ -67,10 +67,10 @@ dependencies:
67
67
  version: 0.5.0
68
68
  type: :development
69
69
  prerelease: false
70
- version_requirements: *70144500897860
70
+ version_requirements: *70284357955880
71
71
  - !ruby/object:Gem::Dependency
72
72
  name: ShyRubyJS
73
- requirement: &70144500897380 !ruby/object:Gem::Requirement
73
+ requirement: &70284357955400 !ruby/object:Gem::Requirement
74
74
  none: false
75
75
  requirements:
76
76
  - - ! '>='
@@ -78,10 +78,10 @@ dependencies:
78
78
  version: '0'
79
79
  type: :development
80
80
  prerelease: false
81
- version_requirements: *70144500897380
81
+ version_requirements: *70284357955400
82
82
  - !ruby/object:Gem::Dependency
83
83
  name: ShyRubyJS
84
- requirement: &70144500896900 !ruby/object:Gem::Requirement
84
+ requirement: &70284357954920 !ruby/object:Gem::Requirement
85
85
  none: false
86
86
  requirements:
87
87
  - - ! '>='
@@ -89,10 +89,10 @@ dependencies:
89
89
  version: '0'
90
90
  type: :runtime
91
91
  prerelease: false
92
- version_requirements: *70144500896900
92
+ version_requirements: *70284357954920
93
93
  - !ruby/object:Gem::Dependency
94
94
  name: rest-client
95
- requirement: &70144500896420 !ruby/object:Gem::Requirement
95
+ requirement: &70284357954440 !ruby/object:Gem::Requirement
96
96
  none: false
97
97
  requirements:
98
98
  - - ! '>='
@@ -100,10 +100,10 @@ dependencies:
100
100
  version: 1.6.7
101
101
  type: :runtime
102
102
  prerelease: false
103
- version_requirements: *70144500896420
103
+ version_requirements: *70284357954440
104
104
  - !ruby/object:Gem::Dependency
105
105
  name: sourcify
106
- requirement: &70144500895940 !ruby/object:Gem::Requirement
106
+ requirement: &70284357953960 !ruby/object:Gem::Requirement
107
107
  none: false
108
108
  requirements:
109
109
  - - ! '>='
@@ -111,7 +111,7 @@ dependencies:
111
111
  version: '0'
112
112
  type: :runtime
113
113
  prerelease: false
114
- version_requirements: *70144500895940
114
+ version_requirements: *70284357953960
115
115
  description: Ruby API for CouchDB, designed to work with the Camping micro-framework.
116
116
  email: danbryan@gmail.com
117
117
  executables: []
@@ -133,8 +133,6 @@ files:
133
133
  - lib/ShyCouch/data.rb
134
134
  - lib/ShyCouch/fields.rb
135
135
  - test/helper.rb
136
- - test/old-test.rb
137
- - test/old-tests.rb
138
136
  - test/test_ShyCouch.rb
139
137
  - test/test_couch_document.rb
140
138
  - test/test_couchdb_api.rb
@@ -157,7 +155,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
157
155
  version: '0'
158
156
  segments:
159
157
  - 0
160
- hash: 2267181098830076376
158
+ hash: -2651663880212191407
161
159
  required_rubygems_version: !ruby/object:Gem::Requirement
162
160
  none: false
163
161
  requirements:
@@ -1,10 +0,0 @@
1
- require '~/dev/shycouch/shycouch'
2
- require '~/dev/shycouch/shycouchtests'
3
- require 'irb'
4
-
5
- ShyCouchTests::test_up
6
- ShyCouchTests::test_down
7
- message = "Test methods: "
8
- message += ShyCouchTests::singleton_methods.map { |m| "ShyCouchTests::#{m}"}.join(', ')
9
- puts message
10
- IRB.start
@@ -1,89 +0,0 @@
1
- require '~/dev/shycouch/shycouch'
2
- module ShyCouchTests
3
- def self.test_up
4
- begin
5
- # set everything up
6
- $t_database, $t_id, $t_document = ShyCouch::CouchDatabase.allocate, "", ShyCouch::Data::CouchDocument.new
7
-
8
- #set up the database
9
- setup_database
10
- setup_document
11
- test_model
12
- test_doc_kinds
13
- # check that everything at least exists
14
- result = if $t_database and $t_database.server and $t_id and $t_document #and $test_doc_kinds.length == 1
15
- {"ok"=>true,"message"=>"Test environment appears to work","database"=>"$t_database",
16
- "server connection"=>"$t_database.server","test doc id"=>"$t_id", "test document"=>"$t_doc",
17
- "test doc model"=>"$t_model"}
18
- else
19
- {"ok"=>false,"message"=>"Test environment appears not to be working","database"=>$t_database,
20
- "server connection"=>$t_database.server,"test doc id"=>$t_id,"test document"=>$t_doc}
21
- end
22
- rescue Errno::ECONNREFUSED
23
- result = {"ok"=>false, "message"=>"""Server Connection refused.
24
- Is CouchDB running at http://#{$t_database.host}:#{$t_database.port} ?"""}
25
- end
26
- result.each do |k, v| puts "#{k}: #{v}"; end
27
- result["ok"]
28
- end
29
-
30
- def self.test_down
31
- $t_database.server.delete_db('test')
32
- $t_database = nil
33
- $t_id = nil
34
- $t_doc = nil
35
- result = {"ok"=>true, "message"=>"Test environment has been brought down."}
36
- result.each do|k, v| puts "#{k}: #{v}"; end
37
- end
38
-
39
- class TestModel < ShyCouch::Data::CouchDocument
40
- def initialize hash
41
- requirements = {
42
- "me"=>String,
43
- "you"=>Array
44
- }
45
- super hash, requirements
46
- end
47
- end
48
-
49
- private
50
-
51
- def self.setup_database
52
- settings = {
53
- "db"=> {
54
- "host" => "localhost",
55
- "port" => 5984,
56
- "name" => "test",
57
- "user" => "cerales",
58
- "password" => "password"
59
- },
60
- }
61
- $t_database = ShyCouch::Create.go(settings)
62
- raise Errno::ECONNREFUSED unless $t_database.connect["ok"]
63
- $t_database.create_on_server unless $t_database.exists_on_server?
64
- end
65
-
66
- def self.setup_document
67
- if $t_database.all_docs.length == 0
68
- emptyDoc = ShyCouch::Data::CouchDocument.new
69
- #$t_id = $t_database.server.push_document($t_database, emptyDoc)["id"]
70
- $t_id = $t_database.push_document(emptyDoc)["id"]
71
- else
72
- $t_id = $t_database.all_docs[0]["id"]
73
- end
74
- end
75
-
76
- def self.test_doc_kinds
77
- doc = ShyCouch::Data::CouchDocument.new.merge!("kind"=>"test")
78
- doc2 = ShyCouch::Data::CouchDocument.new.merge!("kind"=>"nope")
79
- doc3 = ShyCouch::Data::CouchDocument.new.merge!("kind"=>"not me!")
80
- $t_database.push_document(doc)
81
- $t_database.push_document(doc2)
82
- $t_database.push_document(doc3)
83
- $t_doc_kind = $t_database.all_docs_with("kind", "not me!")
84
- end
85
-
86
- def self.test_model
87
- $t_document.merge!($t_database.get_document($t_id))
88
- end
89
- end