joint 0.2 → 0.3

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
@@ -1,6 +1,5 @@
1
1
  require 'rubygems'
2
2
  require 'rake'
3
- require 'yard'
4
3
  require 'jeweler'
5
4
  require 'rake/testtask'
6
5
 
@@ -21,7 +20,10 @@ Jeweler::Tasks.new do |gem|
21
20
  gem.add_dependency 'mime-types'
22
21
 
23
22
  gem.add_development_dependency 'jeweler'
24
- gem.add_development_dependency 'mongo_mapper'
23
+ gem.add_development_dependency 'shoulda'
24
+ gem.add_development_dependency 'mocha'
25
+ gem.add_development_dependency 'jnunemaker-matchy'
26
+ gem.add_development_dependency 'mongo_mapper', '>= 0.7.2'
25
27
  end
26
28
  Jeweler::GemcutterTasks.new
27
29
 
@@ -8,7 +8,7 @@ module Joint
8
8
  module ClassMethods
9
9
  def attachment(name)
10
10
  self.class.class_inheritable_accessor :attachment_names unless self.class.respond_to?(:attachment_names)
11
- self.class.attachment_names ||= []
11
+ self.class.attachment_names ||= Set.new
12
12
  self.class.attachment_names << name
13
13
 
14
14
  after_save :save_attachments
@@ -33,10 +33,10 @@ module Joint
33
33
  if file.nil?
34
34
  nil_attachments << :#{name}
35
35
  else
36
- self["#{name}_id"] = Mongo::ObjectID.new
37
- self["#{name}_size"] = File.size(file)
38
- self["#{name}_type"] = Wand.wave(file.path)
39
- self["#{name}_name"] = Joint.file_name(file)
36
+ self["#{name}_id"] = Mongo::ObjectID.new if self["#{name}_id"].nil?
37
+ self["#{name}_size"] = File.size(file)
38
+ self["#{name}_type"] = Wand.wave(file.path)
39
+ self["#{name}_name"] = Joint.file_name(file)
40
40
  assigned_attachments[:#{name}] = file
41
41
  end
42
42
  end
@@ -58,25 +58,27 @@ module Joint
58
58
  @nil_attachments ||= Set.new
59
59
  end
60
60
 
61
+ # IO must respond to read and rewind
61
62
  def save_attachments
62
- assigned_attachments.each do |attachment|
63
- name, file = attachment
64
- if file.respond_to?(:read)
65
- file.rewind if file.respond_to?(:rewind)
66
- grid.put(file.read, self["#{name}_name"], {
67
- :_id => self["#{name}_id"],
68
- :content_type => self["#{name}_type"],
69
- })
70
- end
71
- end.tap(&:clear)
63
+ assigned_attachments.each_pair do |name, io|
64
+ next unless io.respond_to?(:read)
65
+ io.rewind if io.respond_to?(:rewind)
66
+ grid.delete(send(name).id)
67
+ grid.put(io.read, send(name).name, {
68
+ :_id => send(name).id,
69
+ :content_type => send(name).type,
70
+ })
71
+ end
72
+ assigned_attachments.clear
72
73
  end
73
74
 
74
75
  def destroy_nil_attachments
75
- nil_attachments.each { |name| grid.delete(self["#{name}_id"]) }.tap(&:clear)
76
+ nil_attachments.each { |name| grid.delete(send(name).id) }
77
+ nil_attachments.clear
76
78
  end
77
79
 
78
80
  def destroy_all_attachments
79
- self.class.attachment_names.each { |name| grid.delete(self["#{name}_id"]) }
81
+ self.class.attachment_names.map { |name| grid.delete(send(name).id) }
80
82
  end
81
83
  end
82
84
 
@@ -1,3 +1,3 @@
1
1
  module Joint
2
- Version = '0.2'
2
+ Version = '0.3'
3
3
  end
Binary file
@@ -0,0 +1 @@
1
+ test1
@@ -0,0 +1 @@
1
+ test2
@@ -1,15 +1,19 @@
1
1
  require 'tempfile'
2
2
  require 'pp'
3
- require 'mongo_mapper'
4
3
  require 'shoulda'
5
4
  require 'matchy'
6
5
  require 'mocha'
6
+ require 'mongo_mapper'
7
7
 
8
8
  require File.expand_path(File.dirname(__FILE__) + '/../lib/joint')
9
9
 
10
10
  MongoMapper.database = "testing"
11
11
 
12
12
  class Test::Unit::TestCase
13
+ def setup
14
+ MongoMapper.database.collections.each(&:remove)
15
+ end
16
+
13
17
  def assert_difference(expression, difference = 1, message = nil, &block)
14
18
  b = block.send(:binding)
15
19
  exps = Array.wrap(expression)
@@ -25,4 +29,12 @@ class Test::Unit::TestCase
25
29
  def assert_no_difference(expression, message = nil, &block)
26
30
  assert_difference(expression, 0, message, &block)
27
31
  end
32
+
33
+ def assert_grid_difference(difference=1, &block)
34
+ assert_difference("MongoMapper.database['fs.files'].find().count", difference, &block)
35
+ end
36
+
37
+ def assert_no_grid_difference(&block)
38
+ assert_grid_difference(0, &block)
39
+ end
28
40
  end
@@ -6,105 +6,151 @@ class Asset
6
6
 
7
7
  key :title, String
8
8
  attachment :image
9
- attachment :pdf
9
+ attachment :file
10
+ end
11
+
12
+ module JointTestHelpers
13
+ def all_files
14
+ [@file, @image, @image2, @test1, @test2]
15
+ end
16
+
17
+ def rewind_files
18
+ all_files.each { |file| file.rewind }
19
+ end
20
+
21
+ def open_file(name)
22
+ File.open(File.join(File.dirname(__FILE__), 'fixtures', name), 'r')
23
+ end
24
+
25
+ def grid
26
+ @grid ||= Mongo::Grid.new(MongoMapper.database)
27
+ end
10
28
  end
11
29
 
12
30
  class JointTest < Test::Unit::TestCase
31
+ include JointTestHelpers
32
+
13
33
  def setup
14
- MongoMapper.database.collections.each(&:remove)
15
-
16
- dir = File.dirname(__FILE__) + '/fixtures'
17
- @pdf = File.open("#{dir}/unixref.pdf", 'r')
18
- @image = File.open("#{dir}/mr_t.jpg", 'r')
19
- @pdf_contents = File.read("#{dir}/unixref.pdf")
20
- @image_contents = File.read("#{dir}/mr_t.jpg")
21
- @grid = Mongo::Grid.new(MongoMapper.database)
22
- @gridfs_collection = MongoMapper.database['fs.files']
34
+ super
35
+ @file = open_file('unixref.pdf')
36
+ @image = open_file('mr_t.jpg')
37
+ @image2 = open_file('harmony.png')
38
+ @test1 = open_file('test1.txt')
39
+ @test2 = open_file('test2.txt')
23
40
  end
24
41
 
25
42
  def teardown
26
- @pdf.close
27
- @image.close
43
+ all_files.each { |file| file.close }
28
44
  end
29
45
 
30
46
  context "Using Joint plugin" do
31
47
  should "add each attachment to attachment_names" do
32
- Asset.attachment_names.should == [:image, :pdf]
48
+ Asset.attachment_names.should == Set.new([:image, :file])
33
49
  end
34
50
 
35
51
  should "add keys for each attachment" do
36
- [:image, :pdf].each do |attachment|
52
+ [:image, :file].each do |attachment|
37
53
  [:id, :name, :type, :size].each do |key|
38
- Asset.keys.include?("#{attachment}_#{key}")
54
+ Asset.keys.should include("#{attachment}_#{key}")
39
55
  end
40
56
  end
41
57
  end
42
58
  end
43
59
 
44
- context "Assigning attachments to document" do
60
+ context "Assigning new attachments to document" do
45
61
  setup do
46
- @doc = Asset.create(:image => @image, :pdf => @pdf)
47
- @doc.reload
62
+ @doc = Asset.create(:image => @image, :file => @file)
63
+ rewind_files
48
64
  end
65
+ subject { @doc }
49
66
 
50
67
  should "assign GridFS content_type" do
51
- @grid.get(@doc.image_id).content_type.should == 'image/jpeg'
52
- @grid.get(@doc.pdf_id).content_type.should == 'application/pdf'
68
+ grid.get(subject.image_id).content_type.should == 'image/jpeg'
69
+ grid.get(subject.file_id).content_type.should == 'application/pdf'
53
70
  end
54
71
 
55
72
  should "assign joint keys" do
56
- @doc.image_size.should == 13661
57
- @doc.pdf_size.should == 68926
73
+ subject.image_size.should == 13661
74
+ subject.file_size.should == 68926
58
75
 
59
- @doc.image_type.should == "image/jpeg"
60
- @doc.pdf_type.should == "application/pdf"
76
+ subject.image_type.should == "image/jpeg"
77
+ subject.file_type.should == "application/pdf"
61
78
 
62
- @doc.image_id.should_not be_nil
63
- @doc.pdf_id.should_not be_nil
79
+ subject.image_id.should_not be_nil
80
+ subject.file_id.should_not be_nil
64
81
 
65
- @doc.image_id.should be_instance_of(Mongo::ObjectID)
66
- @doc.pdf_id.should be_instance_of(Mongo::ObjectID)
82
+ subject.image_id.should be_instance_of(Mongo::ObjectID)
83
+ subject.file_id.should be_instance_of(Mongo::ObjectID)
67
84
  end
68
85
 
69
86
  should "allow accessing keys through attachment proxy" do
70
- @doc.image.size.should == 13661
71
- @doc.pdf.size.should == 68926
87
+ subject.image.size.should == 13661
88
+ subject.file.size.should == 68926
72
89
 
73
- @doc.image.type.should == "image/jpeg"
74
- @doc.pdf.type.should == "application/pdf"
90
+ subject.image.type.should == "image/jpeg"
91
+ subject.file.type.should == "application/pdf"
75
92
 
76
- @doc.image.id.should_not be_nil
77
- @doc.pdf.id.should_not be_nil
93
+ subject.image.id.should_not be_nil
94
+ subject.file.id.should_not be_nil
78
95
 
79
- @doc.image.id.should be_instance_of(Mongo::ObjectID)
80
- @doc.pdf.id.should be_instance_of(Mongo::ObjectID)
96
+ subject.image.id.should be_instance_of(Mongo::ObjectID)
97
+ subject.file.id.should be_instance_of(Mongo::ObjectID)
81
98
  end
82
99
 
83
100
  should "proxy unknown methods to GridIO object" do
84
- @doc.image.files_id.should == @doc.image_id
85
- @doc.image.content_type.should == 'image/jpeg'
86
- @doc.image.filename.should == 'mr_t.jpg'
87
- @doc.image.file_length.should == 13661
101
+ subject.image.files_id.should == subject.image_id
102
+ subject.image.content_type.should == 'image/jpeg'
103
+ subject.image.filename.should == 'mr_t.jpg'
104
+ subject.image.file_length.should == 13661
88
105
  end
89
106
 
90
107
  should "assign file name from path if original file name not available" do
91
- @doc.image_name.should == 'mr_t.jpg'
92
- @doc.pdf_name.should == 'unixref.pdf'
108
+ subject.image_name.should == 'mr_t.jpg'
109
+ subject.file_name.should == 'unixref.pdf'
93
110
  end
94
111
 
95
112
  should "save attachment contents correctly" do
96
- @doc.pdf.read.should == @pdf_contents
97
- @doc.image.read.should == @image_contents
113
+ subject.file.read.should == @file.read
114
+ subject.image.read.should == @image.read
98
115
  end
99
116
 
100
117
  should "know that attachment exists" do
101
- @doc.image?.should be(true)
102
- @doc.pdf?.should be(true)
118
+ subject.image?.should be(true)
119
+ subject.file?.should be(true)
103
120
  end
104
121
 
105
122
  should "clear assigned attachments so they don't get uploaded twice" do
106
123
  Mongo::Grid.any_instance.expects(:put).never
107
- @doc.save
124
+ subject.save
125
+ end
126
+ end
127
+
128
+ context "Updating existing attachment" do
129
+ setup do
130
+ @doc = Asset.create(:file => @test1)
131
+ assert_no_grid_difference do
132
+ @doc.file = @test2
133
+ @doc.save!
134
+ end
135
+ rewind_files
136
+ end
137
+ subject { @doc }
138
+
139
+ should "not change attachment id" do
140
+ subject.file_id_changed?.should be(false)
141
+ end
142
+
143
+ should "update keys" do
144
+ subject.file_name.should == 'test2.txt'
145
+ subject.file_type.should == "text/plain"
146
+ subject.file_size.should == 5
147
+ end
148
+
149
+ should "update GridFS" do
150
+ grid.get(subject.file_id).filename.should == 'test2.txt'
151
+ grid.get(subject.file_id).content_type.should == 'text/plain'
152
+ grid.get(subject.file_id).file_length.should == 5
153
+ grid.get(subject.file_id).read.should == @test2.read
108
154
  end
109
155
  end
110
156
 
@@ -113,75 +159,79 @@ class JointTest < Test::Unit::TestCase
113
159
  @doc = Asset.create(:image => @image)
114
160
  @doc.update_attributes(:title => 'Updated')
115
161
  @doc.reload
162
+ rewind_files
116
163
  end
164
+ subject { @doc }
117
165
 
118
166
  should "not affect attachment" do
119
- @doc.image.read.should == @image_contents
167
+ subject.image.read.should == @image.read
120
168
  end
121
169
 
122
170
  should "update document attributes" do
123
- @doc.title.should == 'Updated'
171
+ subject.title.should == 'Updated'
124
172
  end
125
173
  end
126
174
 
127
- context "Assigning file with where file pointer is not at beginning" do
175
+ context "Assigning file where file pointer is not at beginning" do
128
176
  setup do
129
177
  @image.read
130
178
  @doc = Asset.create(:image => @image)
131
179
  @doc.reload
180
+ rewind_files
132
181
  end
182
+ subject { @doc }
133
183
 
134
184
  should "rewind and correctly store contents" do
135
- @doc.image.read.should == @image_contents
185
+ subject.image.read.should == @image.read
136
186
  end
137
187
  end
138
188
 
139
189
  context "Setting attachment to nil" do
140
190
  setup do
141
191
  @doc = Asset.create(:image => @image)
192
+ rewind_files
142
193
  end
194
+ subject { @doc }
143
195
 
144
196
  should "delete attachment after save" do
145
- assert_no_difference '@gridfs_collection.find().count' do
146
- @doc.image = nil
147
- end
148
-
149
- assert_difference '@gridfs_collection.find().count', -1 do
150
- @doc.save
151
- end
197
+ assert_no_grid_difference { subject.image = nil }
198
+ assert_grid_difference(-1) { subject.save }
152
199
  end
153
-
200
+
154
201
  should "clear nil attachments after save and not attempt to delete again" do
155
- @doc.image = nil
156
- @doc.save
202
+ Mongo::Grid.any_instance.expects(:delete).once
203
+ subject.image = nil
204
+ subject.save
157
205
  Mongo::Grid.any_instance.expects(:delete).never
158
- @doc.save
206
+ subject.save
159
207
  end
160
208
  end
161
209
 
162
210
  context "Retrieving attachment that does not exist" do
163
211
  setup do
164
212
  @doc = Asset.create
213
+ rewind_files
165
214
  end
215
+ subject { @doc }
166
216
 
167
217
  should "know that the attachment is not present" do
168
- @doc.image?.should be(false)
218
+ subject.image?.should be(false)
169
219
  end
170
220
 
171
221
  should "raise Mongo::GridError" do
172
- assert_raises(Mongo::GridError) { @doc.image.read }
222
+ assert_raises(Mongo::GridError) { subject.image.read }
173
223
  end
174
224
  end
175
225
 
176
226
  context "Destroying a document" do
177
227
  setup do
178
228
  @doc = Asset.create(:image => @image)
229
+ rewind_files
179
230
  end
231
+ subject { @doc }
180
232
 
181
233
  should "remove files from grid fs as well" do
182
- assert_difference "@gridfs_collection.find().count", -1 do
183
- @doc.destroy
184
- end
234
+ assert_grid_difference(-1) { subject.destroy }
185
235
  end
186
236
  end
187
237
 
@@ -191,16 +241,11 @@ class JointTest < Test::Unit::TestCase
191
241
  end
192
242
 
193
243
  should "use original_filename if available" do
194
- begin
195
- file = Tempfile.new('testing.txt')
196
- def file.original_filename
197
- 'testing.txt'
198
- end
199
- doc = Asset.create(:image => file)
200
- assert_equal 'testing.txt', doc.image_name
201
- ensure
202
- file.close
244
+ def @image.original_filename
245
+ 'testing.txt'
203
246
  end
247
+ doc = Asset.create(:image => @image)
248
+ assert_equal 'testing.txt', doc.image_name
204
249
  end
205
250
  end
206
251
  end
metadata CHANGED
@@ -4,8 +4,8 @@ version: !ruby/object:Gem::Version
4
4
  prerelease: false
5
5
  segments:
6
6
  - 0
7
- - 2
8
- version: "0.2"
7
+ - 3
8
+ version: "0.3"
9
9
  platform: ruby
10
10
  authors:
11
11
  - John Nunemaker
@@ -13,7 +13,7 @@ autorequire:
13
13
  bindir: bin
14
14
  cert_chain: []
15
15
 
16
- date: 2010-03-29 00:00:00 -04:00
16
+ date: 2010-04-05 00:00:00 -04:00
17
17
  default_executable:
18
18
  dependencies:
19
19
  - !ruby/object:Gem::Dependency
@@ -55,7 +55,7 @@ dependencies:
55
55
  type: :development
56
56
  version_requirements: *id003
57
57
  - !ruby/object:Gem::Dependency
58
- name: mongo_mapper
58
+ name: shoulda
59
59
  prerelease: false
60
60
  requirement: &id004 !ruby/object:Gem::Requirement
61
61
  requirements:
@@ -66,6 +66,44 @@ dependencies:
66
66
  version: "0"
67
67
  type: :development
68
68
  version_requirements: *id004
69
+ - !ruby/object:Gem::Dependency
70
+ name: mocha
71
+ prerelease: false
72
+ requirement: &id005 !ruby/object:Gem::Requirement
73
+ requirements:
74
+ - - ">="
75
+ - !ruby/object:Gem::Version
76
+ segments:
77
+ - 0
78
+ version: "0"
79
+ type: :development
80
+ version_requirements: *id005
81
+ - !ruby/object:Gem::Dependency
82
+ name: jnunemaker-matchy
83
+ prerelease: false
84
+ requirement: &id006 !ruby/object:Gem::Requirement
85
+ requirements:
86
+ - - ">="
87
+ - !ruby/object:Gem::Version
88
+ segments:
89
+ - 0
90
+ version: "0"
91
+ type: :development
92
+ version_requirements: *id006
93
+ - !ruby/object:Gem::Dependency
94
+ name: mongo_mapper
95
+ prerelease: false
96
+ requirement: &id007 !ruby/object:Gem::Requirement
97
+ requirements:
98
+ - - ">="
99
+ - !ruby/object:Gem::Version
100
+ segments:
101
+ - 0
102
+ - 7
103
+ - 2
104
+ version: 0.7.2
105
+ type: :development
106
+ version_requirements: *id007
69
107
  description: MongoMapper and GridFS joined in file upload love.
70
108
  email: nunemaker@gmail.com
71
109
  executables: []
@@ -79,7 +117,10 @@ files:
79
117
  - Rakefile
80
118
  - lib/joint.rb
81
119
  - lib/joint/version.rb
120
+ - test/fixtures/harmony.png
82
121
  - test/fixtures/mr_t.jpg
122
+ - test/fixtures/test1.txt
123
+ - test/fixtures/test2.txt
83
124
  - test/fixtures/unixref.pdf
84
125
  - test/helper.rb
85
126
  - test/test_joint.rb
@@ -114,7 +155,10 @@ signing_key:
114
155
  specification_version: 3
115
156
  summary: MongoMapper and GridFS joined in file upload love.
116
157
  test_files:
158
+ - test/fixtures/harmony.png
117
159
  - test/fixtures/mr_t.jpg
160
+ - test/fixtures/test1.txt
161
+ - test/fixtures/test2.txt
118
162
  - test/fixtures/unixref.pdf
119
163
  - test/helper.rb
120
164
  - test/test_joint.rb