joint 0.6.0 → 0.6.1

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/.gitignore CHANGED
@@ -5,3 +5,4 @@ doc/*
5
5
  pkg/*
6
6
  .bundle
7
7
  *.swp
8
+ Gemfile.lock
data/Gemfile CHANGED
@@ -2,6 +2,7 @@ source :rubygems
2
2
 
3
3
  gemspec
4
4
 
5
+ gem 'rake'
5
6
  gem 'bson_ext', :require => false
6
7
  gem 'shoulda'
7
8
  gem 'mocha'
@@ -12,7 +12,7 @@ Gem::Specification.new do |s|
12
12
 
13
13
  s.add_dependency 'wand', '~> 0.4'
14
14
  s.add_dependency 'mime-types'
15
- s.add_dependency 'mongo_mapper', '~> 0.9.0'
15
+ s.add_dependency 'mongo_mapper', '~> 0.9'
16
16
 
17
17
  s.files = `git ls-files`.split("\n")
18
18
  s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
@@ -11,6 +11,7 @@ module Joint
11
11
  self.attachment_names = attachment_names.dup.add(name)
12
12
 
13
13
  after_save :save_attachments
14
+ before_save :nullify_nil_attachments_attributes
14
15
  after_save :destroy_nil_attachments
15
16
  before_destroy :destroy_all_attachments
16
17
 
@@ -27,12 +28,12 @@ module Joint
27
28
  end
28
29
 
29
30
  def #{name}?
30
- !nil_attachments.include?(:#{name}) && send(:#{name}_id?)
31
+ !nil_attachments.has_key?(:#{name}) && send(:#{name}_id?)
31
32
  end
32
33
 
33
34
  def #{name}=(file)
34
35
  if file.nil?
35
- nil_attachments << :#{name}
36
+ nil_attachments[:#{name}] = send("#{name}_id")
36
37
  assigned_attachments.delete(:#{name})
37
38
  else
38
39
  send("#{name}_id=", BSON::ObjectId.new) if send("#{name}_id").nil?
@@ -10,7 +10,7 @@ module Joint
10
10
  end
11
11
 
12
12
  def nil_attachments
13
- @nil_attachments ||= Set.new
13
+ @nil_attachments ||= {}
14
14
  end
15
15
 
16
16
  # IO must respond to read and rewind
@@ -27,21 +27,19 @@ module Joint
27
27
  end
28
28
  assigned_attachments.clear
29
29
  end
30
-
31
- def destroy_nil_attachments
32
- # currently MM does not send sets to instance as well
33
- nil_attachments.each do |name|
34
- grid.delete(send(name).id)
30
+
31
+ def nullify_nil_attachments_attributes
32
+ nil_attachments.each_key do |name|
35
33
  send(:"#{name}_id=", nil)
36
34
  send(:"#{name}_size=", nil)
37
35
  send(:"#{name}_type=", nil)
38
36
  send(:"#{name}_name=", nil)
39
- set({
40
- :"#{name}_id" => nil,
41
- :"#{name}_size" => nil,
42
- :"#{name}_type" => nil,
43
- :"#{name}_name" => nil,
44
- })
37
+ end
38
+ end
39
+
40
+ def destroy_nil_attachments
41
+ nil_attachments.each_value do |id|
42
+ grid.delete(id)
45
43
  end
46
44
 
47
45
  nil_attachments.clear
@@ -1,3 +1,3 @@
1
1
  module Joint
2
- Version = '0.6.0'
2
+ Version = '0.6.1'
3
3
  end
@@ -25,7 +25,8 @@ class Test::Unit::TestCase
25
25
  exps.each_with_index do |e, i|
26
26
  error = "#{e.inspect} didn't change by #{difference}"
27
27
  error = "#{message}.\n#{error}" if message
28
- assert_equal(before[i] + difference, eval(e, b), error)
28
+ after = eval(e, b)
29
+ assert_equal(before[i] + difference, after, error)
29
30
  end
30
31
  end
31
32
 
@@ -46,6 +47,16 @@ class Asset
46
47
  include MongoMapper::Document
47
48
  plugin Joint
48
49
 
50
+ key :title, String
51
+ attachment :image
52
+ attachment :file
53
+ has_many :embedded_assets
54
+ end
55
+
56
+ class EmbeddedAsset
57
+ include MongoMapper::EmbeddedDocument
58
+ plugin Joint
59
+
49
60
  key :title, String
50
61
  attachment :image
51
62
  attachment :file
@@ -56,17 +56,21 @@ class JointTest < Test::Unit::TestCase
56
56
  context "Using Joint plugin" do
57
57
  should "add each attachment to attachment_names" do
58
58
  Asset.attachment_names.should == Set.new([:image, :file])
59
+ EmbeddedAsset.attachment_names.should == Set.new([:image, :file])
59
60
  end
60
61
 
61
62
  should "add keys for each attachment" do
62
63
  key_names.each do |key|
63
64
  Asset.keys.should include("image_#{key}")
64
65
  Asset.keys.should include("file_#{key}")
66
+ EmbeddedAsset.keys.should include("image_#{key}")
67
+ EmbeddedAsset.keys.should include("file_#{key}")
65
68
  end
66
69
  end
67
70
 
68
71
  should "add memoized accessors module" do
69
72
  Asset.attachment_accessor_module.should be_instance_of(Module)
73
+ EmbeddedAsset.attachment_accessor_module.should be_instance_of(Module)
70
74
  end
71
75
 
72
76
  context "with inheritance" do
@@ -153,9 +157,79 @@ class JointTest < Test::Unit::TestCase
153
157
  subject.file?.should be(true)
154
158
  end
155
159
 
156
- should "respond with false when asked if the attachment is nil?" do
157
- subject.image.nil?.should be(false)
158
- subject.file.nil?.should be(false)
160
+ should "respond with false when asked if the attachment is blank?" do
161
+ subject.image.blank?.should be(false)
162
+ subject.file.blank?.should be(false)
163
+ end
164
+
165
+ should "clear assigned attachments so they don't get uploaded twice" do
166
+ Mongo::Grid.any_instance.expects(:put).never
167
+ subject.save
168
+ end
169
+ end
170
+
171
+ context "Assigning new attachments to embedded document" do
172
+ setup do
173
+ @asset = Asset.new
174
+ @doc = @asset.embedded_assets.build(:image => @image, :file => @file)
175
+ @asset.save!
176
+ rewind_files
177
+ end
178
+ subject { @doc }
179
+
180
+ should "assign GridFS content_type" do
181
+ grid.get(subject.image_id).content_type.should == 'image/jpeg'
182
+ grid.get(subject.file_id).content_type.should == 'application/pdf'
183
+ end
184
+
185
+ should "assign joint keys" do
186
+ subject.image_size.should == 13661
187
+ subject.file_size.should == 68926
188
+
189
+ subject.image_type.should == "image/jpeg"
190
+ subject.file_type.should == "application/pdf"
191
+
192
+ subject.image_id.should_not be_nil
193
+ subject.file_id.should_not be_nil
194
+
195
+ subject.image_id.should be_instance_of(BSON::ObjectId)
196
+ subject.file_id.should be_instance_of(BSON::ObjectId)
197
+ end
198
+
199
+ should "allow accessing keys through attachment proxy" do
200
+ subject.image.size.should == 13661
201
+ subject.file.size.should == 68926
202
+
203
+ subject.image.type.should == "image/jpeg"
204
+ subject.file.type.should == "application/pdf"
205
+
206
+ subject.image.id.should_not be_nil
207
+ subject.file.id.should_not be_nil
208
+
209
+ subject.image.id.should be_instance_of(BSON::ObjectId)
210
+ subject.file.id.should be_instance_of(BSON::ObjectId)
211
+ end
212
+
213
+ should "proxy unknown methods to GridIO object" do
214
+ subject.image.files_id.should == subject.image_id
215
+ subject.image.content_type.should == 'image/jpeg'
216
+ subject.image.filename.should == 'mr_t.jpg'
217
+ subject.image.file_length.should == 13661
218
+ end
219
+
220
+ should "assign file name from path if original file name not available" do
221
+ subject.image_name.should == 'mr_t.jpg'
222
+ subject.file_name.should == 'unixref.pdf'
223
+ end
224
+
225
+ should "save attachment contents correctly" do
226
+ subject.file.read.should == @file.read
227
+ subject.image.read.should == @image.read
228
+ end
229
+
230
+ should "know that attachment exists" do
231
+ subject.image?.should be(true)
232
+ subject.file?.should be(true)
159
233
  end
160
234
 
161
235
  should "respond with false when asked if the attachment is blank?" do
@@ -198,6 +272,33 @@ class JointTest < Test::Unit::TestCase
198
272
  end
199
273
  end
200
274
 
275
+ context "Updating existing attachment in embedded document" do
276
+ setup do
277
+ @asset = Asset.new
278
+ @doc = @asset.embedded_assets.build(:file => @test1)
279
+ @asset.save!
280
+ assert_no_grid_difference do
281
+ @doc.file = @test2
282
+ @doc.save!
283
+ end
284
+ rewind_files
285
+ end
286
+ subject { @doc }
287
+
288
+ should "update keys" do
289
+ subject.file_name.should == 'test2.txt'
290
+ subject.file_type.should == "text/plain"
291
+ subject.file_size.should == 5
292
+ end
293
+
294
+ should "update GridFS" do
295
+ grid.get(subject.file_id).filename.should == 'test2.txt'
296
+ grid.get(subject.file_id).content_type.should == 'text/plain'
297
+ grid.get(subject.file_id).file_length.should == 5
298
+ grid.get(subject.file_id).read.should == @test2.read
299
+ end
300
+ end
301
+
201
302
  context "Updating document but not attachments" do
202
303
  setup do
203
304
  @doc = Asset.create(:image => @image)
@@ -216,6 +317,26 @@ class JointTest < Test::Unit::TestCase
216
317
  end
217
318
  end
218
319
 
320
+ context "Updating embedded document but not attachments" do
321
+ setup do
322
+ @asset = Asset.new
323
+ @doc = @asset.embedded_assets.build(:image => @image)
324
+ @doc.update_attributes(:title => 'Updated')
325
+ @asset.reload
326
+ @doc = @asset.embedded_assets.first
327
+ rewind_files
328
+ end
329
+ subject { @doc }
330
+
331
+ should "not affect attachment" do
332
+ subject.image.read.should == @image.read
333
+ end
334
+
335
+ should "update document attributes" do
336
+ subject.title.should == 'Updated'
337
+ end
338
+ end
339
+
219
340
  context "Assigning file where file pointer is not at beginning" do
220
341
  setup do
221
342
  @image.read
@@ -278,7 +399,58 @@ class JointTest < Test::Unit::TestCase
278
399
  assert_nil subject.image_type
279
400
  assert_nil subject.image_size
280
401
  end
402
+ end
403
+
404
+ context "Setting attachment to nil on embedded document" do
405
+ setup do
406
+ @asset = Asset.new
407
+ @doc = @asset.embedded_assets.build(:image => @image)
408
+ @asset.save!
409
+ rewind_files
410
+ end
411
+ subject { @doc }
412
+
413
+ should "delete attachment after save" do
414
+ assert_no_grid_difference { subject.image = nil }
415
+ assert_grid_difference(-1) { subject.save }
416
+ end
281
417
 
418
+ should "know that the attachment has been nullified" do
419
+ subject.image = nil
420
+ subject.image?.should be(false)
421
+ end
422
+
423
+ should "respond with true when asked if the attachment is nil?" do
424
+ subject.image = nil
425
+ subject.image.nil?.should be(true)
426
+ end
427
+
428
+ should "respond with true when asked if the attachment is blank?" do
429
+ subject.image = nil
430
+ subject.image.blank?.should be(true)
431
+ end
432
+
433
+ should "clear nil attachments after save and not attempt to delete again" do
434
+ Mongo::Grid.any_instance.expects(:delete).once
435
+ subject.image = nil
436
+ subject.save
437
+ Mongo::Grid.any_instance.expects(:delete).never
438
+ subject.save
439
+ end
440
+
441
+ should "clear id, name, type, size" do
442
+ subject.image = nil
443
+ subject.save
444
+ assert_nil subject.image_id
445
+ assert_nil subject.image_name
446
+ assert_nil subject.image_type
447
+ assert_nil subject.image_size
448
+ s = subject._root_document.reload.embedded_assets.first
449
+ assert_nil s.image_id
450
+ assert_nil s.image_name
451
+ assert_nil s.image_type
452
+ assert_nil s.image_size
453
+ end
282
454
  end
283
455
 
284
456
  context "Retrieving attachment that does not exist" do
@@ -313,6 +485,22 @@ class JointTest < Test::Unit::TestCase
313
485
  end
314
486
  end
315
487
 
488
+ context "Destroying an embedded document's _root_document" do
489
+ setup do
490
+ @asset = Asset.new
491
+ @doc = @asset.embedded_assets.build(:image => @image)
492
+ @doc.save!
493
+ rewind_files
494
+ end
495
+ subject { @doc }
496
+
497
+ should "remove files from grid fs as well" do
498
+ assert_grid_difference(-1) { subject._root_document.destroy }
499
+ end
500
+ end
501
+
502
+ # What about when an embedded document is removed?
503
+
316
504
  context "Assigning file name" do
317
505
  should "default to path" do
318
506
  Asset.create(:image => @image).image.name.should == 'mr_t.jpg'
@@ -358,15 +546,14 @@ class JointTest < Test::Unit::TestCase
358
546
  io = Joint::IO.new({
359
547
  :name => 'foo.txt',
360
548
  :type => 'plain/text',
361
- :content => 'This is my stuff',
362
- :size => 19,
549
+ :content => 'This is my stuff'
363
550
  })
364
551
  @asset = Asset.create(:file => io)
365
552
  end
366
553
 
367
554
  should "work" do
368
555
  @asset.file_name.should == 'foo.txt'
369
- @asset.file_size.should == 19
556
+ @asset.file_size.should == 16
370
557
  @asset.file_type.should == 'plain/text'
371
558
  @asset.file.read.should == 'This is my stuff'
372
559
  end
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: joint
3
3
  version: !ruby/object:Gem::Version
4
- hash: 7
4
+ hash: 5
5
5
  prerelease:
6
6
  segments:
7
7
  - 0
8
8
  - 6
9
- - 0
10
- version: 0.6.0
9
+ - 1
10
+ version: 0.6.1
11
11
  platform: ruby
12
12
  authors:
13
13
  - John Nunemaker
@@ -15,12 +15,14 @@ autorequire:
15
15
  bindir: bin
16
16
  cert_chain: []
17
17
 
18
- date: 2011-09-14 00:00:00 Z
18
+ date: 2011-12-14 00:00:00 -05:00
19
+ default_executable:
19
20
  dependencies:
20
21
  - !ruby/object:Gem::Dependency
22
+ type: :runtime
21
23
  name: wand
22
24
  prerelease: false
23
- requirement: &id001 !ruby/object:Gem::Requirement
25
+ version_requirements: &id001 !ruby/object:Gem::Requirement
24
26
  none: false
25
27
  requirements:
26
28
  - - ~>
@@ -30,12 +32,12 @@ dependencies:
30
32
  - 0
31
33
  - 4
32
34
  version: "0.4"
33
- type: :runtime
34
- version_requirements: *id001
35
+ requirement: *id001
35
36
  - !ruby/object:Gem::Dependency
37
+ type: :runtime
36
38
  name: mime-types
37
39
  prerelease: false
38
- requirement: &id002 !ruby/object:Gem::Requirement
40
+ version_requirements: &id002 !ruby/object:Gem::Requirement
39
41
  none: false
40
42
  requirements:
41
43
  - - ">="
@@ -44,24 +46,22 @@ dependencies:
44
46
  segments:
45
47
  - 0
46
48
  version: "0"
47
- type: :runtime
48
- version_requirements: *id002
49
+ requirement: *id002
49
50
  - !ruby/object:Gem::Dependency
51
+ type: :runtime
50
52
  name: mongo_mapper
51
53
  prerelease: false
52
- requirement: &id003 !ruby/object:Gem::Requirement
54
+ version_requirements: &id003 !ruby/object:Gem::Requirement
53
55
  none: false
54
56
  requirements:
55
57
  - - ~>
56
58
  - !ruby/object:Gem::Version
57
- hash: 59
59
+ hash: 25
58
60
  segments:
59
61
  - 0
60
62
  - 9
61
- - 0
62
- version: 0.9.0
63
- type: :runtime
64
- version_requirements: *id003
63
+ version: "0.9"
64
+ requirement: *id003
65
65
  description: MongoMapper and GridFS joined in file upload love.
66
66
  email: nunemaker@gmail.com
67
67
  executables: []
@@ -73,7 +73,6 @@ extra_rdoc_files: []
73
73
  files:
74
74
  - .gitignore
75
75
  - Gemfile
76
- - Gemfile.lock
77
76
  - LICENSE
78
77
  - README.rdoc
79
78
  - Rakefile
@@ -95,6 +94,7 @@ files:
95
94
  - test/helper.rb
96
95
  - test/joint/test_io.rb
97
96
  - test/test_joint.rb
97
+ has_rdoc: true
98
98
  homepage: http://github.com/jnunemaker/joint
99
99
  licenses: []
100
100
 
@@ -124,7 +124,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
124
124
  requirements: []
125
125
 
126
126
  rubyforge_project:
127
- rubygems_version: 1.8.9
127
+ rubygems_version: 1.6.1
128
128
  signing_key:
129
129
  specification_version: 3
130
130
  summary: MongoMapper and GridFS joined in file upload love.
@@ -1,52 +0,0 @@
1
- PATH
2
- remote: .
3
- specs:
4
- joint (0.6.0)
5
- mime-types
6
- mongo_mapper (~> 0.9.0)
7
- wand (~> 0.4)
8
-
9
- GEM
10
- remote: http://rubygems.org/
11
- specs:
12
- activemodel (3.1.0)
13
- activesupport (= 3.1.0)
14
- bcrypt-ruby (~> 3.0.0)
15
- builder (~> 3.0.0)
16
- i18n (~> 0.6)
17
- activesupport (3.1.0)
18
- multi_json (~> 1.0)
19
- bcrypt-ruby (3.0.1)
20
- bson (1.3.1)
21
- bson_ext (1.3.1)
22
- builder (3.0.0)
23
- i18n (0.6.0)
24
- jnunemaker-matchy (0.4.0)
25
- mime-types (1.16)
26
- mocha (0.9.10)
27
- rake
28
- mongo (1.3.1)
29
- bson (>= 1.3.1)
30
- mongo_mapper (0.9.2)
31
- activemodel (~> 3.0)
32
- activesupport (~> 3.0)
33
- plucky (~> 0.3.8)
34
- multi_json (1.0.2)
35
- plucky (0.3.8)
36
- mongo (~> 1.3)
37
- rake (0.8.7)
38
- safe_shell (1.0.0)
39
- shoulda (2.11.3)
40
- wand (0.4)
41
- mime-types
42
- safe_shell (~> 1.0.0)
43
-
44
- PLATFORMS
45
- ruby
46
-
47
- DEPENDENCIES
48
- bson_ext
49
- jnunemaker-matchy
50
- joint!
51
- mocha
52
- shoulda