ShyCouch 0.5.0 → 0.6.0

Sign up to get free protection for your applications and to get access to all the features.
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