joint 0.3.2 → 0.4
Sign up to get free protection for your applications and to get access to all the features.
- data/LICENSE +20 -0
- data/lib/joint.rb +29 -4
- data/lib/joint/version.rb +1 -1
- data/test/test_joint.rb +62 -4
- metadata +31 -27
- data/Rakefile +0 -38
data/LICENSE
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright (c) 2010 John Nunemaker
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
4
|
+
a copy of this software and associated documentation files (the
|
5
|
+
"Software"), to deal in the Software without restriction, including
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
9
|
+
the following conditions:
|
10
|
+
|
11
|
+
The above copyright notice and this permission notice shall be
|
12
|
+
included in all copies or substantial portions of the Software.
|
13
|
+
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
17
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
18
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
19
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/lib/joint.rb
CHANGED
@@ -11,7 +11,10 @@ module Joint
|
|
11
11
|
end
|
12
12
|
|
13
13
|
module ClassMethods
|
14
|
-
def attachment(name)
|
14
|
+
def attachment(name, options = {})
|
15
|
+
options.symbolize_keys!
|
16
|
+
name = name.to_sym
|
17
|
+
|
15
18
|
self.attachment_names << name
|
16
19
|
|
17
20
|
after_save :save_attachments
|
@@ -23,24 +26,28 @@ module Joint
|
|
23
26
|
key "#{name}_size".to_sym, Integer
|
24
27
|
key "#{name}_type".to_sym, String
|
25
28
|
|
29
|
+
validates_presence_of(name) if options[:required]
|
30
|
+
|
26
31
|
class_eval <<-EOC
|
27
32
|
def #{name}
|
28
33
|
@#{name} ||= AttachmentProxy.new(self, :#{name})
|
29
34
|
end
|
30
35
|
|
31
36
|
def #{name}?
|
32
|
-
self.send(:#{name}_id?)
|
37
|
+
!nil_attachments.include?(:#{name}) && self.send(:#{name}_id?)
|
33
38
|
end
|
34
39
|
|
35
40
|
def #{name}=(file)
|
36
41
|
if file.nil?
|
37
42
|
nil_attachments << :#{name}
|
43
|
+
assigned_attachments.delete(:#{name})
|
38
44
|
else
|
39
|
-
self["#{name}_id"] = BSON::
|
45
|
+
self["#{name}_id"] = BSON::ObjectId.new if self["#{name}_id"].nil?
|
40
46
|
self["#{name}_size"] = File.size(file)
|
41
47
|
self["#{name}_type"] = Wand.wave(file.path)
|
42
48
|
self["#{name}_name"] = Joint.file_name(file)
|
43
49
|
assigned_attachments[:#{name}] = file
|
50
|
+
nil_attachments.delete(:#{name})
|
44
51
|
end
|
45
52
|
end
|
46
53
|
EOC
|
@@ -77,7 +84,21 @@ module Joint
|
|
77
84
|
end
|
78
85
|
|
79
86
|
def destroy_nil_attachments
|
80
|
-
|
87
|
+
# currently MM does not send sets to instance as well
|
88
|
+
nil_attachments.each do |name|
|
89
|
+
grid.delete(send(name).id)
|
90
|
+
send(:"#{name}_id=", nil)
|
91
|
+
send(:"#{name}_size=", nil)
|
92
|
+
send(:"#{name}_type=", nil)
|
93
|
+
send(:"#{name}_name=", nil)
|
94
|
+
set({
|
95
|
+
:"#{name}_id" => nil,
|
96
|
+
:"#{name}_size" => nil,
|
97
|
+
:"#{name}_type" => nil,
|
98
|
+
:"#{name}_name" => nil,
|
99
|
+
})
|
100
|
+
end
|
101
|
+
|
81
102
|
nil_attachments.clear
|
82
103
|
end
|
83
104
|
|
@@ -107,6 +128,10 @@ module Joint
|
|
107
128
|
@instance.send("#{@name}_type")
|
108
129
|
end
|
109
130
|
|
131
|
+
def nil?
|
132
|
+
!@instance.send("#{@name}?")
|
133
|
+
end
|
134
|
+
|
110
135
|
def grid_io
|
111
136
|
@grid_io ||= @instance.grid.get(id)
|
112
137
|
end
|
data/lib/joint/version.rb
CHANGED
data/test/test_joint.rb
CHANGED
@@ -112,8 +112,8 @@ class JointTest < Test::Unit::TestCase
|
|
112
112
|
subject.image_id.should_not be_nil
|
113
113
|
subject.file_id.should_not be_nil
|
114
114
|
|
115
|
-
subject.image_id.should be_instance_of(BSON::
|
116
|
-
subject.file_id.should be_instance_of(BSON::
|
115
|
+
subject.image_id.should be_instance_of(BSON::ObjectId)
|
116
|
+
subject.file_id.should be_instance_of(BSON::ObjectId)
|
117
117
|
end
|
118
118
|
|
119
119
|
should "allow accessing keys through attachment proxy" do
|
@@ -126,8 +126,8 @@ class JointTest < Test::Unit::TestCase
|
|
126
126
|
subject.image.id.should_not be_nil
|
127
127
|
subject.file.id.should_not be_nil
|
128
128
|
|
129
|
-
subject.image.id.should be_instance_of(BSON::
|
130
|
-
subject.file.id.should be_instance_of(BSON::
|
129
|
+
subject.image.id.should be_instance_of(BSON::ObjectId)
|
130
|
+
subject.file.id.should be_instance_of(BSON::ObjectId)
|
131
131
|
end
|
132
132
|
|
133
133
|
should "proxy unknown methods to GridIO object" do
|
@@ -152,6 +152,11 @@ class JointTest < Test::Unit::TestCase
|
|
152
152
|
subject.file?.should be(true)
|
153
153
|
end
|
154
154
|
|
155
|
+
should "respond with false when asked if the attachment is nil?" do
|
156
|
+
subject.image.nil?.should be(false)
|
157
|
+
subject.file.nil?.should be(false)
|
158
|
+
end
|
159
|
+
|
155
160
|
should "clear assigned attachments so they don't get uploaded twice" do
|
156
161
|
Mongo::Grid.any_instance.expects(:put).never
|
157
162
|
subject.save
|
@@ -231,6 +236,16 @@ class JointTest < Test::Unit::TestCase
|
|
231
236
|
assert_grid_difference(-1) { subject.save }
|
232
237
|
end
|
233
238
|
|
239
|
+
should "know that the attachment has been nullified" do
|
240
|
+
subject.image = nil
|
241
|
+
subject.image?.should be(false)
|
242
|
+
end
|
243
|
+
|
244
|
+
should "respond with true when asked if the attachment is nil?" do
|
245
|
+
subject.image = nil
|
246
|
+
subject.image.nil?.should be(true)
|
247
|
+
end
|
248
|
+
|
234
249
|
should "clear nil attachments after save and not attempt to delete again" do
|
235
250
|
Mongo::Grid.any_instance.expects(:delete).once
|
236
251
|
subject.image = nil
|
@@ -238,6 +253,21 @@ class JointTest < Test::Unit::TestCase
|
|
238
253
|
Mongo::Grid.any_instance.expects(:delete).never
|
239
254
|
subject.save
|
240
255
|
end
|
256
|
+
|
257
|
+
should "clear id, name, type, size" do
|
258
|
+
subject.image = nil
|
259
|
+
subject.save
|
260
|
+
assert_nil subject.image_id
|
261
|
+
assert_nil subject.image_name
|
262
|
+
assert_nil subject.image_type
|
263
|
+
assert_nil subject.image_size
|
264
|
+
subject.reload
|
265
|
+
assert_nil subject.image_id
|
266
|
+
assert_nil subject.image_name
|
267
|
+
assert_nil subject.image_type
|
268
|
+
assert_nil subject.image_size
|
269
|
+
end
|
270
|
+
|
241
271
|
end
|
242
272
|
|
243
273
|
context "Retrieving attachment that does not exist" do
|
@@ -251,6 +281,10 @@ class JointTest < Test::Unit::TestCase
|
|
251
281
|
subject.image?.should be(false)
|
252
282
|
end
|
253
283
|
|
284
|
+
should "respond with true when asked if the attachment is nil?" do
|
285
|
+
subject.image.nil?.should be(true)
|
286
|
+
end
|
287
|
+
|
254
288
|
should "raise Mongo::GridFileNotFound" do
|
255
289
|
assert_raises(Mongo::GridFileNotFound) { subject.image.read }
|
256
290
|
end
|
@@ -281,4 +315,28 @@ class JointTest < Test::Unit::TestCase
|
|
281
315
|
assert_equal 'testing.txt', doc.image_name
|
282
316
|
end
|
283
317
|
end
|
318
|
+
|
319
|
+
context "Validating attachment presence" do
|
320
|
+
setup do
|
321
|
+
@model_class = Class.new do
|
322
|
+
include MongoMapper::Document
|
323
|
+
plugin Joint
|
324
|
+
attachment :file, :required => true
|
325
|
+
end
|
326
|
+
end
|
327
|
+
|
328
|
+
should "work" do
|
329
|
+
model = @model_class.new
|
330
|
+
model.should_not be_valid
|
331
|
+
|
332
|
+
model.file = @file
|
333
|
+
model.should be_valid
|
334
|
+
|
335
|
+
model.file = nil
|
336
|
+
model.should_not be_valid
|
337
|
+
|
338
|
+
model.file = @image
|
339
|
+
model.should be_valid
|
340
|
+
end
|
341
|
+
end
|
284
342
|
end
|
metadata
CHANGED
@@ -1,12 +1,12 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: joint
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
+
hash: 3
|
4
5
|
prerelease: false
|
5
6
|
segments:
|
6
7
|
- 0
|
7
|
-
-
|
8
|
-
|
9
|
-
version: 0.3.2
|
8
|
+
- 4
|
9
|
+
version: "0.4"
|
10
10
|
platform: ruby
|
11
11
|
authors:
|
12
12
|
- John Nunemaker
|
@@ -14,16 +14,18 @@ autorequire:
|
|
14
14
|
bindir: bin
|
15
15
|
cert_chain: []
|
16
16
|
|
17
|
-
date: 2010-
|
17
|
+
date: 2010-09-07 00:00:00 -04:00
|
18
18
|
default_executable:
|
19
19
|
dependencies:
|
20
20
|
- !ruby/object:Gem::Dependency
|
21
21
|
name: wand
|
22
22
|
prerelease: false
|
23
23
|
requirement: &id001 !ruby/object:Gem::Requirement
|
24
|
+
none: false
|
24
25
|
requirements:
|
25
26
|
- - ">="
|
26
27
|
- !ruby/object:Gem::Version
|
28
|
+
hash: 21
|
27
29
|
segments:
|
28
30
|
- 0
|
29
31
|
- 2
|
@@ -35,9 +37,11 @@ dependencies:
|
|
35
37
|
name: mime-types
|
36
38
|
prerelease: false
|
37
39
|
requirement: &id002 !ruby/object:Gem::Requirement
|
40
|
+
none: false
|
38
41
|
requirements:
|
39
42
|
- - ">="
|
40
43
|
- !ruby/object:Gem::Version
|
44
|
+
hash: 3
|
41
45
|
segments:
|
42
46
|
- 0
|
43
47
|
version: "0"
|
@@ -47,9 +51,11 @@ dependencies:
|
|
47
51
|
name: mongo_mapper
|
48
52
|
prerelease: false
|
49
53
|
requirement: &id003 !ruby/object:Gem::Requirement
|
54
|
+
none: false
|
50
55
|
requirements:
|
51
56
|
- - ">="
|
52
57
|
- !ruby/object:Gem::Version
|
58
|
+
hash: 11
|
53
59
|
segments:
|
54
60
|
- 0
|
55
61
|
- 7
|
@@ -58,66 +64,58 @@ dependencies:
|
|
58
64
|
type: :runtime
|
59
65
|
version_requirements: *id003
|
60
66
|
- !ruby/object:Gem::Dependency
|
61
|
-
name:
|
67
|
+
name: shoulda
|
62
68
|
prerelease: false
|
63
69
|
requirement: &id004 !ruby/object:Gem::Requirement
|
70
|
+
none: false
|
64
71
|
requirements:
|
65
72
|
- - ">="
|
66
73
|
- !ruby/object:Gem::Version
|
74
|
+
hash: 3
|
67
75
|
segments:
|
68
76
|
- 0
|
69
77
|
version: "0"
|
70
78
|
type: :development
|
71
79
|
version_requirements: *id004
|
72
80
|
- !ruby/object:Gem::Dependency
|
73
|
-
name:
|
81
|
+
name: mocha
|
74
82
|
prerelease: false
|
75
83
|
requirement: &id005 !ruby/object:Gem::Requirement
|
84
|
+
none: false
|
76
85
|
requirements:
|
77
86
|
- - ">="
|
78
87
|
- !ruby/object:Gem::Version
|
88
|
+
hash: 3
|
79
89
|
segments:
|
80
90
|
- 0
|
81
91
|
version: "0"
|
82
92
|
type: :development
|
83
93
|
version_requirements: *id005
|
84
94
|
- !ruby/object:Gem::Dependency
|
85
|
-
name:
|
95
|
+
name: jnunemaker-matchy
|
86
96
|
prerelease: false
|
87
97
|
requirement: &id006 !ruby/object:Gem::Requirement
|
98
|
+
none: false
|
88
99
|
requirements:
|
89
100
|
- - ">="
|
90
101
|
- !ruby/object:Gem::Version
|
102
|
+
hash: 3
|
91
103
|
segments:
|
92
104
|
- 0
|
93
105
|
version: "0"
|
94
106
|
type: :development
|
95
107
|
version_requirements: *id006
|
96
|
-
- !ruby/object:Gem::Dependency
|
97
|
-
name: jnunemaker-matchy
|
98
|
-
prerelease: false
|
99
|
-
requirement: &id007 !ruby/object:Gem::Requirement
|
100
|
-
requirements:
|
101
|
-
- - ">="
|
102
|
-
- !ruby/object:Gem::Version
|
103
|
-
segments:
|
104
|
-
- 0
|
105
|
-
version: "0"
|
106
|
-
type: :development
|
107
|
-
version_requirements: *id007
|
108
108
|
description: MongoMapper and GridFS joined in file upload love.
|
109
109
|
email: nunemaker@gmail.com
|
110
110
|
executables: []
|
111
111
|
|
112
112
|
extensions: []
|
113
113
|
|
114
|
-
extra_rdoc_files:
|
115
|
-
|
114
|
+
extra_rdoc_files: []
|
115
|
+
|
116
116
|
files:
|
117
|
-
- README.rdoc
|
118
|
-
- Rakefile
|
119
|
-
- lib/joint.rb
|
120
117
|
- lib/joint/version.rb
|
118
|
+
- lib/joint.rb
|
121
119
|
- test/fixtures/harmony.png
|
122
120
|
- test/fixtures/mr_t.jpg
|
123
121
|
- test/fixtures/test1.txt
|
@@ -125,33 +123,39 @@ files:
|
|
125
123
|
- test/fixtures/unixref.pdf
|
126
124
|
- test/helper.rb
|
127
125
|
- test/test_joint.rb
|
126
|
+
- LICENSE
|
127
|
+
- README.rdoc
|
128
128
|
has_rdoc: true
|
129
129
|
homepage: http://github.com/jnunemaker/joint
|
130
130
|
licenses: []
|
131
131
|
|
132
132
|
post_install_message:
|
133
|
-
rdoc_options:
|
134
|
-
|
133
|
+
rdoc_options: []
|
134
|
+
|
135
135
|
require_paths:
|
136
136
|
- lib
|
137
137
|
required_ruby_version: !ruby/object:Gem::Requirement
|
138
|
+
none: false
|
138
139
|
requirements:
|
139
140
|
- - ">="
|
140
141
|
- !ruby/object:Gem::Version
|
142
|
+
hash: 3
|
141
143
|
segments:
|
142
144
|
- 0
|
143
145
|
version: "0"
|
144
146
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
147
|
+
none: false
|
145
148
|
requirements:
|
146
149
|
- - ">="
|
147
150
|
- !ruby/object:Gem::Version
|
151
|
+
hash: 3
|
148
152
|
segments:
|
149
153
|
- 0
|
150
154
|
version: "0"
|
151
155
|
requirements: []
|
152
156
|
|
153
157
|
rubyforge_project:
|
154
|
-
rubygems_version: 1.3.
|
158
|
+
rubygems_version: 1.3.7
|
155
159
|
signing_key:
|
156
160
|
specification_version: 3
|
157
161
|
summary: MongoMapper and GridFS joined in file upload love.
|
data/Rakefile
DELETED
@@ -1,38 +0,0 @@
|
|
1
|
-
require 'rubygems'
|
2
|
-
require 'rake'
|
3
|
-
require 'jeweler'
|
4
|
-
require 'rake/testtask'
|
5
|
-
|
6
|
-
require File.join(File.dirname(__FILE__), 'lib', 'joint', 'version')
|
7
|
-
|
8
|
-
Jeweler::Tasks.new do |gem|
|
9
|
-
gem.name = "joint"
|
10
|
-
gem.summary = %Q{MongoMapper and GridFS joined in file upload love.}
|
11
|
-
gem.description = %Q{MongoMapper and GridFS joined in file upload love.}
|
12
|
-
gem.email = "nunemaker@gmail.com"
|
13
|
-
gem.homepage = "http://github.com/jnunemaker/joint"
|
14
|
-
gem.authors = ["John Nunemaker"]
|
15
|
-
gem.version = Joint::Version
|
16
|
-
gem.files = FileList['lib/**/*.rb', 'bin/*', '[A-Z]*', 'test/**/*'].to_a
|
17
|
-
gem.test_files = FileList['test/**/*'].to_a
|
18
|
-
|
19
|
-
gem.add_dependency 'wand', '>= 0.2.1'
|
20
|
-
gem.add_dependency 'mime-types'
|
21
|
-
gem.add_dependency 'mongo_mapper', '>= 0.7.4'
|
22
|
-
|
23
|
-
gem.add_development_dependency 'jeweler'
|
24
|
-
gem.add_development_dependency 'shoulda'
|
25
|
-
gem.add_development_dependency 'mocha'
|
26
|
-
gem.add_development_dependency 'jnunemaker-matchy'
|
27
|
-
end
|
28
|
-
Jeweler::GemcutterTasks.new
|
29
|
-
|
30
|
-
Rake::TestTask.new(:test) do |test|
|
31
|
-
test.libs << 'lib' << 'test'
|
32
|
-
test.ruby_opts << '-rubygems'
|
33
|
-
test.pattern = 'test/**/test_*.rb'
|
34
|
-
test.verbose = true
|
35
|
-
end
|
36
|
-
|
37
|
-
task :test => :check_dependencies
|
38
|
-
task :default => :test
|