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 +4 -2
- data/lib/joint.rb +19 -17
- data/lib/joint/version.rb +1 -1
- data/test/fixtures/harmony.png +0 -0
- data/test/fixtures/test1.txt +1 -0
- data/test/fixtures/test2.txt +1 -0
- data/test/helper.rb +13 -1
- data/test/test_joint.rb +121 -76
- metadata +48 -4
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 '
|
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
|
|
data/lib/joint.rb
CHANGED
@@ -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"]
|
37
|
-
self["#{name}_size"]
|
38
|
-
self["#{name}_type"]
|
39
|
-
self["#{name}_name"]
|
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.
|
63
|
-
|
64
|
-
if
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
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(
|
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.
|
81
|
+
self.class.attachment_names.map { |name| grid.delete(send(name).id) }
|
80
82
|
end
|
81
83
|
end
|
82
84
|
|
data/lib/joint/version.rb
CHANGED
Binary file
|
@@ -0,0 +1 @@
|
|
1
|
+
test1
|
@@ -0,0 +1 @@
|
|
1
|
+
test2
|
data/test/helper.rb
CHANGED
@@ -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
|
data/test/test_joint.rb
CHANGED
@@ -6,105 +6,151 @@ class Asset
|
|
6
6
|
|
7
7
|
key :title, String
|
8
8
|
attachment :image
|
9
|
-
attachment :
|
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
|
-
|
15
|
-
|
16
|
-
|
17
|
-
@
|
18
|
-
@
|
19
|
-
@
|
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
|
-
|
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, :
|
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, :
|
52
|
+
[:image, :file].each do |attachment|
|
37
53
|
[:id, :name, :type, :size].each do |key|
|
38
|
-
Asset.keys.include
|
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, :
|
47
|
-
|
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
|
-
|
52
|
-
|
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
|
-
|
57
|
-
|
73
|
+
subject.image_size.should == 13661
|
74
|
+
subject.file_size.should == 68926
|
58
75
|
|
59
|
-
|
60
|
-
|
76
|
+
subject.image_type.should == "image/jpeg"
|
77
|
+
subject.file_type.should == "application/pdf"
|
61
78
|
|
62
|
-
|
63
|
-
|
79
|
+
subject.image_id.should_not be_nil
|
80
|
+
subject.file_id.should_not be_nil
|
64
81
|
|
65
|
-
|
66
|
-
|
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
|
-
|
71
|
-
|
87
|
+
subject.image.size.should == 13661
|
88
|
+
subject.file.size.should == 68926
|
72
89
|
|
73
|
-
|
74
|
-
|
90
|
+
subject.image.type.should == "image/jpeg"
|
91
|
+
subject.file.type.should == "application/pdf"
|
75
92
|
|
76
|
-
|
77
|
-
|
93
|
+
subject.image.id.should_not be_nil
|
94
|
+
subject.file.id.should_not be_nil
|
78
95
|
|
79
|
-
|
80
|
-
|
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
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
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
|
-
|
92
|
-
|
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
|
-
|
97
|
-
|
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
|
-
|
102
|
-
|
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
|
-
|
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
|
-
|
167
|
+
subject.image.read.should == @image.read
|
120
168
|
end
|
121
169
|
|
122
170
|
should "update document attributes" do
|
123
|
-
|
171
|
+
subject.title.should == 'Updated'
|
124
172
|
end
|
125
173
|
end
|
126
174
|
|
127
|
-
context "Assigning file
|
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
|
-
|
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
|
-
|
146
|
-
|
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
|
-
|
156
|
-
|
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
|
-
|
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
|
-
|
218
|
+
subject.image?.should be(false)
|
169
219
|
end
|
170
220
|
|
171
221
|
should "raise Mongo::GridError" do
|
172
|
-
assert_raises(Mongo::GridError) {
|
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
|
-
|
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
|
-
|
195
|
-
|
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
|
-
-
|
8
|
-
version: "0.
|
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-
|
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:
|
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
|