mattetti-couchrest 0.14.2 → 0.15

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/README.md CHANGED
@@ -59,13 +59,7 @@ Creating and Querying Views:
59
59
 
60
60
  ## CouchRest::Model
61
61
 
62
- CouchRest::Model is a module designed along the lines of DataMapper::Resource.
63
- By subclassing, suddenly you get all sorts of powerful sugar, so that working
64
- with CouchDB in your Rails or Merb app is no harder than working with the
65
- standard SQL alternatives. See the CouchRest::Model documentation for an
66
- example article class that illustrates usage.
67
-
68
- CouchRest::Model will be removed from this package.
62
+ CouchRest::Model has been deprecated and replaced by CouchRest::ExtendedDocument
69
63
 
70
64
 
71
65
  ## CouchRest::ExtendedDocument
@@ -1,31 +1,38 @@
1
- require 'rubygems'
2
- require 'couchrest'
1
+ require File.join(File.dirname(__FILE__), '..', '..', 'lib', 'couchrest')
3
2
 
4
3
  def show obj
5
4
  puts obj.inspect
6
5
  puts
7
6
  end
8
7
 
9
- CouchRest::Model.default_database = CouchRest.database!('couchrest-model-example')
8
+ SERVER = CouchRest.new
9
+ SERVER.default_database = 'couchrest-extendeddoc-example'
10
10
 
11
- class Author < CouchRest::Model
12
- key_accessor :name
11
+ class Author < CouchRest::ExtendedDocument
12
+ use_database SERVER.default_database
13
+ property :name
14
+
13
15
  def drink_scotch
14
16
  puts "... glug type glug ... I'm #{name} ... type glug glug ..."
15
17
  end
16
18
  end
17
19
 
18
- class Post < CouchRest::Model
19
- key_accessor :title, :body, :author
20
-
21
- cast :author, :as => 'Author'
20
+ class Post < CouchRest::ExtendedDocument
21
+ use_database SERVER.default_database
22
+
23
+ property :title
24
+ property :body
25
+ property :author, :cast_as => 'Author'
22
26
 
23
27
  timestamps!
24
28
  end
25
29
 
26
- class Comment < CouchRest::Model
27
- cast :commenter, :as => 'Author'
28
-
30
+ class Comment < CouchRest::ExtendedDocument
31
+ use_database SERVER.default_database
32
+
33
+ property :commenter, :cast_as => 'Author'
34
+ timestamps!
35
+
29
36
  def post= post
30
37
  self["post_id"] = post.id
31
38
  end
@@ -33,7 +40,6 @@ class Comment < CouchRest::Model
33
40
  Post.get(self['post_id']) if self['post_id']
34
41
  end
35
42
 
36
- timestamps!
37
43
  end
38
44
 
39
45
  puts "Act I: CRUD"
@@ -279,7 +279,7 @@ module CouchRest
279
279
 
280
280
  private
281
281
 
282
- def uri_for_attachment doc, name
282
+ def uri_for_attachment(doc, name)
283
283
  if doc.is_a?(String)
284
284
  puts "CouchRest::Database#fetch_attachment will eventually require a doc as the first argument, not a doc.id"
285
285
  docid = doc
@@ -31,6 +31,7 @@ module CouchRest
31
31
 
32
32
  def initialize(keys={})
33
33
  apply_defaults # defined in CouchRest::Mixins::Properties
34
+ keys ||= {}
34
35
  super
35
36
  cast_keys # defined in CouchRest::Mixins::Properties
36
37
  unless self['_id'] && self['_rev']
@@ -100,7 +101,7 @@ module CouchRest
100
101
  # missing. In case of error, no attributes are changed.
101
102
  def update_attributes_without_saving(hash)
102
103
  hash.each do |k, v|
103
- raise NoMethodError, "#{k}= method not available, use key_accessor or key_writer :#{k}" unless self.respond_to?("#{k}=")
104
+ raise NoMethodError, "#{k}= method not available, use property :#{k}" unless self.respond_to?("#{k}=")
104
105
  end
105
106
  hash.each do |k, v|
106
107
  self.send("#{k}=",v)
@@ -18,6 +18,8 @@ module CouchRest
18
18
  def parse_type(type)
19
19
  if type.nil?
20
20
  @type = 'String'
21
+ elsif type.is_a?(Array) && type.empty?
22
+ @type = 'Array'
21
23
  else
22
24
  @type = type.is_a?(Array) ? [type.first.to_s] : type.to_s
23
25
  end
data/lib/couchrest.rb CHANGED
@@ -27,7 +27,7 @@ require 'couchrest/monkeypatches'
27
27
 
28
28
  # = CouchDB, close to the metal
29
29
  module CouchRest
30
- VERSION = '0.14.2'
30
+ VERSION = '0.15'
31
31
 
32
32
  autoload :Server, 'couchrest/core/server'
33
33
  autoload :Database, 'couchrest/core/database'
@@ -704,7 +704,7 @@ describe CouchRest::Database do
704
704
  describe "creating a database" do
705
705
  before(:each) do
706
706
  @db = @cr.database('couchrest-test-db_to_create')
707
- @db.delete!
707
+ @db.delete! if @cr.databases.include?('couchrest-test-db_to_create')
708
708
  end
709
709
 
710
710
  it "should just work fine" do
@@ -0,0 +1,129 @@
1
+ require File.dirname(__FILE__) + '/../../spec_helper'
2
+
3
+ describe "ExtendedDocument attachments" do
4
+
5
+ describe "#has_attachment?" do
6
+ before(:each) do
7
+ @obj = Basic.new
8
+ @obj.save.should == true
9
+ @file = File.open(FIXTURE_PATH + '/attachments/test.html')
10
+ @attachment_name = 'my_attachment'
11
+ @obj.create_attachment(:file => @file, :name => @attachment_name)
12
+ end
13
+
14
+ it 'should return false if there is no attachment' do
15
+ @obj.has_attachment?('bogus').should be_false
16
+ end
17
+
18
+ it 'should return true if there is an attachment' do
19
+ @obj.has_attachment?(@attachment_name).should be_true
20
+ end
21
+
22
+ it 'should return true if an object with an attachment is reloaded' do
23
+ @obj.save.should be_true
24
+ reloaded_obj = Basic.get(@obj.id)
25
+ reloaded_obj.has_attachment?(@attachment_name).should be_true
26
+ end
27
+
28
+ it 'should return false if an attachment has been removed' do
29
+ @obj.delete_attachment(@attachment_name)
30
+ @obj.has_attachment?(@attachment_name).should be_false
31
+ end
32
+ end
33
+
34
+ describe "creating an attachment" do
35
+ before(:each) do
36
+ @obj = Basic.new
37
+ @obj.save.should == true
38
+ @file_ext = File.open(FIXTURE_PATH + '/attachments/test.html')
39
+ @file_no_ext = File.open(FIXTURE_PATH + '/attachments/README')
40
+ @attachment_name = 'my_attachment'
41
+ @content_type = 'media/mp3'
42
+ end
43
+
44
+ it "should create an attachment from file with an extension" do
45
+ @obj.create_attachment(:file => @file_ext, :name => @attachment_name)
46
+ @obj.save.should == true
47
+ reloaded_obj = Basic.get(@obj.id)
48
+ reloaded_obj['_attachments'][@attachment_name].should_not be_nil
49
+ end
50
+
51
+ it "should create an attachment from file without an extension" do
52
+ @obj.create_attachment(:file => @file_no_ext, :name => @attachment_name)
53
+ @obj.save.should == true
54
+ reloaded_obj = Basic.get(@obj.id)
55
+ reloaded_obj['_attachments'][@attachment_name].should_not be_nil
56
+ end
57
+
58
+ it 'should raise ArgumentError if :file is missing' do
59
+ lambda{ @obj.create_attachment(:name => @attachment_name) }.should raise_error
60
+ end
61
+
62
+ it 'should raise ArgumentError if :name is missing' do
63
+ lambda{ @obj.create_attachment(:file => @file_ext) }.should raise_error
64
+ end
65
+
66
+ it 'should set the content-type if passed' do
67
+ @obj.create_attachment(:file => @file_ext, :name => @attachment_name, :content_type => @content_type)
68
+ @obj['_attachments'][@attachment_name]['content-type'].should == @content_type
69
+ end
70
+ end
71
+
72
+ describe 'reading, updating, and deleting an attachment' do
73
+ before(:each) do
74
+ @obj = Basic.new
75
+ @file = File.open(FIXTURE_PATH + '/attachments/test.html')
76
+ @attachment_name = 'my_attachment'
77
+ @obj.create_attachment(:file => @file, :name => @attachment_name)
78
+ @obj.save.should == true
79
+ @file.rewind
80
+ @content_type = 'media/mp3'
81
+ end
82
+
83
+ it 'should read an attachment that exists' do
84
+ @obj.read_attachment(@attachment_name).should == @file.read
85
+ end
86
+
87
+ it 'should update an attachment that exists' do
88
+ file = File.open(FIXTURE_PATH + '/attachments/README')
89
+ @file.should_not == file
90
+ @obj.update_attachment(:file => file, :name => @attachment_name)
91
+ @obj.save
92
+ reloaded_obj = Basic.get(@obj.id)
93
+ file.rewind
94
+ reloaded_obj.read_attachment(@attachment_name).should_not == @file.read
95
+ reloaded_obj.read_attachment(@attachment_name).should == file.read
96
+ end
97
+
98
+ it 'should se the content-type if passed' do
99
+ file = File.open(FIXTURE_PATH + '/attachments/README')
100
+ @file.should_not == file
101
+ @obj.update_attachment(:file => file, :name => @attachment_name, :content_type => @content_type)
102
+ @obj['_attachments'][@attachment_name]['content-type'].should == @content_type
103
+ end
104
+
105
+ it 'should delete an attachment that exists' do
106
+ @obj.delete_attachment(@attachment_name)
107
+ @obj.save
108
+ lambda{Basic.get(@obj.id).read_attachment(@attachment_name)}.should raise_error
109
+ end
110
+ end
111
+
112
+ describe "#attachment_url" do
113
+ before(:each) do
114
+ @obj = Basic.new
115
+ @file = File.open(FIXTURE_PATH + '/attachments/test.html')
116
+ @attachment_name = 'my_attachment'
117
+ @obj.create_attachment(:file => @file, :name => @attachment_name)
118
+ @obj.save.should == true
119
+ end
120
+
121
+ it 'should return nil if attachment does not exist' do
122
+ @obj.attachment_url('bogus').should be_nil
123
+ end
124
+
125
+ it 'should return the attachment URL as specified by CouchDB HttpDocumentApi' do
126
+ @obj.attachment_url(@attachment_name).should == "#{Basic.database}/#{@obj.id}/#{@attachment_name}"
127
+ end
128
+ end
129
+ end