mattetti-couchrest 0.14.2 → 0.15

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