joint 0.5.1 → 0.5.2
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/Gemfile +1 -1
- data/Gemfile.lock +2 -2
- data/lib/joint.rb +20 -132
- data/lib/joint/attachment_proxy.rb +35 -0
- data/lib/joint/class_methods.rb +49 -0
- data/lib/joint/instance_methods.rb +54 -0
- data/lib/joint/io.rb +14 -0
- data/lib/joint/version.rb +1 -1
- data/specs.watchr +2 -15
- data/test/helper.rb +40 -0
- data/test/joint/test_io.rb +28 -0
- data/test/test_joint.rb +58 -40
- metadata +10 -4
data/Gemfile
CHANGED
data/Gemfile.lock
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
joint (0.5)
|
4
|
+
joint (0.5.1)
|
5
5
|
mime-types
|
6
6
|
mongo_mapper (~> 0.8.6)
|
7
7
|
wand (~> 0.3)
|
@@ -37,7 +37,7 @@ PLATFORMS
|
|
37
37
|
|
38
38
|
DEPENDENCIES
|
39
39
|
bson_ext (~> 1.1)
|
40
|
-
i18n
|
40
|
+
i18n (= 0.4.2)
|
41
41
|
jnunemaker-matchy
|
42
42
|
joint!
|
43
43
|
mime-types
|
data/lib/joint.rb
CHANGED
@@ -3,150 +3,38 @@ require 'mime/types'
|
|
3
3
|
require 'wand'
|
4
4
|
|
5
5
|
module Joint
|
6
|
-
autoload :Version, 'joint/version'
|
7
|
-
|
8
6
|
def self.configure(model)
|
9
7
|
model.class_inheritable_accessor :attachment_names
|
10
8
|
model.attachment_names = Set.new
|
11
9
|
model.send(:include, model.attachment_accessor_module)
|
12
10
|
end
|
13
11
|
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
def attachment(name, options = {})
|
20
|
-
options.symbolize_keys!
|
21
|
-
name = name.to_sym
|
22
|
-
|
23
|
-
self.attachment_names << name
|
24
|
-
|
25
|
-
after_save :save_attachments
|
26
|
-
after_save :destroy_nil_attachments
|
27
|
-
before_destroy :destroy_all_attachments
|
28
|
-
|
29
|
-
key :"#{name}_id", ObjectId
|
30
|
-
key :"#{name}_name", String
|
31
|
-
key :"#{name}_size", Integer
|
32
|
-
key :"#{name}_type", String
|
33
|
-
|
34
|
-
validates_presence_of(name) if options[:required]
|
35
|
-
|
36
|
-
attachment_accessor_module.module_eval <<-EOC
|
37
|
-
def #{name}
|
38
|
-
@#{name} ||= AttachmentProxy.new(self, :#{name})
|
39
|
-
end
|
40
|
-
|
41
|
-
def #{name}?
|
42
|
-
!nil_attachments.include?(:#{name}) && send(:#{name}_id?)
|
43
|
-
end
|
44
|
-
|
45
|
-
def #{name}=(file)
|
46
|
-
if file.nil?
|
47
|
-
nil_attachments << :#{name}
|
48
|
-
assigned_attachments.delete(:#{name})
|
49
|
-
else
|
50
|
-
send("#{name}_id=", BSON::ObjectId.new) if send("#{name}_id").nil?
|
51
|
-
send("#{name}_size=", File.size(file))
|
52
|
-
send("#{name}_type=", Wand.wave(file.path, :original_filename => Joint.file_name(file)))
|
53
|
-
send("#{name}_name=", Joint.file_name(file))
|
54
|
-
assigned_attachments[:#{name}] = file
|
55
|
-
nil_attachments.delete(:#{name})
|
56
|
-
end
|
57
|
-
end
|
58
|
-
EOC
|
12
|
+
def self.name(file)
|
13
|
+
if file.respond_to?(:original_filename)
|
14
|
+
file.original_filename
|
15
|
+
else
|
16
|
+
File.basename(file.path)
|
59
17
|
end
|
60
18
|
end
|
61
19
|
|
62
|
-
|
63
|
-
|
64
|
-
|
20
|
+
def self.size(file)
|
21
|
+
if file.respond_to?(:size)
|
22
|
+
file.size
|
23
|
+
else
|
24
|
+
File.size(file)
|
65
25
|
end
|
66
|
-
|
67
|
-
private
|
68
|
-
def assigned_attachments
|
69
|
-
@assigned_attachments ||= {}
|
70
|
-
end
|
71
|
-
|
72
|
-
def nil_attachments
|
73
|
-
@nil_attachments ||= Set.new
|
74
|
-
end
|
75
|
-
|
76
|
-
# IO must respond to read and rewind
|
77
|
-
def save_attachments
|
78
|
-
assigned_attachments.each_pair do |name, io|
|
79
|
-
next unless io.respond_to?(:read)
|
80
|
-
io.rewind if io.respond_to?(:rewind)
|
81
|
-
grid.delete(send(name).id)
|
82
|
-
grid.put(io.read, {
|
83
|
-
:_id => send(name).id,
|
84
|
-
:filename => send(name).name,
|
85
|
-
:content_type => send(name).type,
|
86
|
-
})
|
87
|
-
end
|
88
|
-
assigned_attachments.clear
|
89
|
-
end
|
90
|
-
|
91
|
-
def destroy_nil_attachments
|
92
|
-
# currently MM does not send sets to instance as well
|
93
|
-
nil_attachments.each do |name|
|
94
|
-
grid.delete(send(name).id)
|
95
|
-
send(:"#{name}_id=", nil)
|
96
|
-
send(:"#{name}_size=", nil)
|
97
|
-
send(:"#{name}_type=", nil)
|
98
|
-
send(:"#{name}_name=", nil)
|
99
|
-
set({
|
100
|
-
:"#{name}_id" => nil,
|
101
|
-
:"#{name}_size" => nil,
|
102
|
-
:"#{name}_type" => nil,
|
103
|
-
:"#{name}_name" => nil,
|
104
|
-
})
|
105
|
-
end
|
106
|
-
|
107
|
-
nil_attachments.clear
|
108
|
-
end
|
109
|
-
|
110
|
-
def destroy_all_attachments
|
111
|
-
self.class.attachment_names.map { |name| grid.delete(send(name).id) }
|
112
|
-
end
|
113
26
|
end
|
114
27
|
|
115
|
-
|
116
|
-
|
117
|
-
|
28
|
+
def self.type(file)
|
29
|
+
if file.respond_to?(:content_type)
|
30
|
+
file.content_type
|
31
|
+
else
|
32
|
+
Wand.wave(file.path, :original_filename => Joint.name(file))
|
118
33
|
end
|
119
|
-
|
120
|
-
def id
|
121
|
-
@instance.send("#{@name}_id")
|
122
|
-
end
|
123
|
-
|
124
|
-
def name
|
125
|
-
@instance.send("#{@name}_name")
|
126
|
-
end
|
127
|
-
|
128
|
-
def size
|
129
|
-
@instance.send("#{@name}_size")
|
130
|
-
end
|
131
|
-
|
132
|
-
def type
|
133
|
-
@instance.send("#{@name}_type")
|
134
|
-
end
|
135
|
-
|
136
|
-
def nil?
|
137
|
-
!@instance.send("#{@name}?")
|
138
|
-
end
|
139
|
-
|
140
|
-
def grid_io
|
141
|
-
@grid_io ||= @instance.grid.get(id)
|
142
|
-
end
|
143
|
-
|
144
|
-
def method_missing(method, *args, &block)
|
145
|
-
grid_io.send(method, *args, &block)
|
146
|
-
end
|
147
|
-
end
|
148
|
-
|
149
|
-
def self.file_name(file)
|
150
|
-
file.respond_to?(:original_filename) ? file.original_filename : File.basename(file.path)
|
151
34
|
end
|
152
35
|
end
|
36
|
+
|
37
|
+
require 'joint/class_methods'
|
38
|
+
require 'joint/instance_methods'
|
39
|
+
require 'joint/attachment_proxy'
|
40
|
+
require 'joint/io'
|
@@ -0,0 +1,35 @@
|
|
1
|
+
module Joint
|
2
|
+
class AttachmentProxy
|
3
|
+
def initialize(instance, name)
|
4
|
+
@instance, @name = instance, name
|
5
|
+
end
|
6
|
+
|
7
|
+
def id
|
8
|
+
@instance.send("#{@name}_id")
|
9
|
+
end
|
10
|
+
|
11
|
+
def name
|
12
|
+
@instance.send("#{@name}_name")
|
13
|
+
end
|
14
|
+
|
15
|
+
def size
|
16
|
+
@instance.send("#{@name}_size")
|
17
|
+
end
|
18
|
+
|
19
|
+
def type
|
20
|
+
@instance.send("#{@name}_type")
|
21
|
+
end
|
22
|
+
|
23
|
+
def nil?
|
24
|
+
!@instance.send("#{@name}?")
|
25
|
+
end
|
26
|
+
|
27
|
+
def grid_io
|
28
|
+
@grid_io ||= @instance.grid.get(id)
|
29
|
+
end
|
30
|
+
|
31
|
+
def method_missing(method, *args, &block)
|
32
|
+
grid_io.send(method, *args, &block)
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
@@ -0,0 +1,49 @@
|
|
1
|
+
module Joint
|
2
|
+
module ClassMethods
|
3
|
+
def attachment_accessor_module
|
4
|
+
@attachment_accessor_module ||= Module.new
|
5
|
+
end
|
6
|
+
|
7
|
+
def attachment(name, options = {})
|
8
|
+
options.symbolize_keys!
|
9
|
+
name = name.to_sym
|
10
|
+
|
11
|
+
self.attachment_names << name
|
12
|
+
|
13
|
+
after_save :save_attachments
|
14
|
+
after_save :destroy_nil_attachments
|
15
|
+
before_destroy :destroy_all_attachments
|
16
|
+
|
17
|
+
key :"#{name}_id", ObjectId
|
18
|
+
key :"#{name}_name", String
|
19
|
+
key :"#{name}_size", Integer
|
20
|
+
key :"#{name}_type", String
|
21
|
+
|
22
|
+
validates_presence_of(name) if options[:required]
|
23
|
+
|
24
|
+
attachment_accessor_module.module_eval <<-EOC
|
25
|
+
def #{name}
|
26
|
+
@#{name} ||= AttachmentProxy.new(self, :#{name})
|
27
|
+
end
|
28
|
+
|
29
|
+
def #{name}?
|
30
|
+
!nil_attachments.include?(:#{name}) && send(:#{name}_id?)
|
31
|
+
end
|
32
|
+
|
33
|
+
def #{name}=(file)
|
34
|
+
if file.nil?
|
35
|
+
nil_attachments << :#{name}
|
36
|
+
assigned_attachments.delete(:#{name})
|
37
|
+
else
|
38
|
+
send("#{name}_id=", BSON::ObjectId.new) if send("#{name}_id").nil?
|
39
|
+
send("#{name}_name=", Joint.name(file))
|
40
|
+
send("#{name}_size=", Joint.size(file))
|
41
|
+
send("#{name}_type=", Joint.type(file))
|
42
|
+
assigned_attachments[:#{name}] = file
|
43
|
+
nil_attachments.delete(:#{name})
|
44
|
+
end
|
45
|
+
end
|
46
|
+
EOC
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
@@ -0,0 +1,54 @@
|
|
1
|
+
module Joint
|
2
|
+
module InstanceMethods
|
3
|
+
def grid
|
4
|
+
@grid ||= Mongo::Grid.new(database)
|
5
|
+
end
|
6
|
+
|
7
|
+
private
|
8
|
+
def assigned_attachments
|
9
|
+
@assigned_attachments ||= {}
|
10
|
+
end
|
11
|
+
|
12
|
+
def nil_attachments
|
13
|
+
@nil_attachments ||= Set.new
|
14
|
+
end
|
15
|
+
|
16
|
+
# IO must respond to read and rewind
|
17
|
+
def save_attachments
|
18
|
+
assigned_attachments.each_pair do |name, io|
|
19
|
+
next unless io.respond_to?(:read)
|
20
|
+
io.rewind if io.respond_to?(:rewind)
|
21
|
+
grid.delete(send(name).id)
|
22
|
+
grid.put(io.read, {
|
23
|
+
:_id => send(name).id,
|
24
|
+
:filename => send(name).name,
|
25
|
+
:content_type => send(name).type,
|
26
|
+
})
|
27
|
+
end
|
28
|
+
assigned_attachments.clear
|
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)
|
35
|
+
send(:"#{name}_id=", nil)
|
36
|
+
send(:"#{name}_size=", nil)
|
37
|
+
send(:"#{name}_type=", nil)
|
38
|
+
send(:"#{name}_name=", nil)
|
39
|
+
set({
|
40
|
+
:"#{name}_id" => nil,
|
41
|
+
:"#{name}_size" => nil,
|
42
|
+
:"#{name}_type" => nil,
|
43
|
+
:"#{name}_name" => nil,
|
44
|
+
})
|
45
|
+
end
|
46
|
+
|
47
|
+
nil_attachments.clear
|
48
|
+
end
|
49
|
+
|
50
|
+
def destroy_all_attachments
|
51
|
+
self.class.attachment_names.map { |name| grid.delete(send(name).id) }
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
data/lib/joint/io.rb
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
module Joint
|
2
|
+
class IO
|
3
|
+
attr_accessor :name, :content, :content_type, :size
|
4
|
+
|
5
|
+
def initialize(attrs={})
|
6
|
+
attrs.each { |key, value| send("#{key}=", value) }
|
7
|
+
@content_type ||= 'plain/text'
|
8
|
+
@size ||= @content.size unless @content.nil?
|
9
|
+
end
|
10
|
+
|
11
|
+
alias path name
|
12
|
+
alias read content
|
13
|
+
end
|
14
|
+
end
|
data/lib/joint/version.rb
CHANGED
data/specs.watchr
CHANGED
@@ -1,16 +1,3 @@
|
|
1
|
-
def growl(title, msg, img)
|
2
|
-
%x{growlnotify -m #{ msg.inspect} -t #{title.inspect} --image ~/.watchr/#{img}.png}
|
3
|
-
end
|
4
|
-
|
5
|
-
def form_growl_message(str)
|
6
|
-
results = str.split("\n").last
|
7
|
-
if results =~ /[1-9]\s(failure|error)s?/
|
8
|
-
growl "Test Results", "#{results}", "fail"
|
9
|
-
elsif results != ""
|
10
|
-
growl "Test Results", "#{results}", "pass"
|
11
|
-
end
|
12
|
-
end
|
13
|
-
|
14
1
|
def run(cmd)
|
15
2
|
puts(cmd)
|
16
3
|
output = ""
|
@@ -21,7 +8,7 @@ def run(cmd)
|
|
21
8
|
$stdout.flush
|
22
9
|
end
|
23
10
|
end
|
24
|
-
|
11
|
+
output
|
25
12
|
end
|
26
13
|
|
27
14
|
def run_test_file(file)
|
@@ -37,7 +24,7 @@ def related_test_files(path)
|
|
37
24
|
end
|
38
25
|
|
39
26
|
watch('test/test_helper\.rb') { system('clear'); run_all_tests }
|
40
|
-
watch('test
|
27
|
+
watch('test/.*test_.*\.rb') { |m| system('clear'); run_test_file(m[0]) }
|
41
28
|
watch('lib/.*') { |m| related_test_files(m[0]).each { |file| run_test_file(file) } }
|
42
29
|
|
43
30
|
# Ctrl-\
|
data/test/helper.rb
CHANGED
@@ -37,4 +37,44 @@ class Test::Unit::TestCase
|
|
37
37
|
def assert_no_grid_difference(&block)
|
38
38
|
assert_grid_difference(0, &block)
|
39
39
|
end
|
40
|
+
end
|
41
|
+
|
42
|
+
class Asset
|
43
|
+
include MongoMapper::Document
|
44
|
+
plugin Joint
|
45
|
+
|
46
|
+
key :title, String
|
47
|
+
attachment :image
|
48
|
+
attachment :file
|
49
|
+
end
|
50
|
+
|
51
|
+
class BaseModel
|
52
|
+
include MongoMapper::Document
|
53
|
+
plugin Joint
|
54
|
+
attachment :file
|
55
|
+
end
|
56
|
+
|
57
|
+
class Image < BaseModel; attachment :image end
|
58
|
+
class Video < BaseModel; attachment :video end
|
59
|
+
|
60
|
+
module JointTestHelpers
|
61
|
+
def all_files
|
62
|
+
[@file, @image, @image2, @test1, @test2]
|
63
|
+
end
|
64
|
+
|
65
|
+
def rewind_files
|
66
|
+
all_files.each { |file| file.rewind }
|
67
|
+
end
|
68
|
+
|
69
|
+
def open_file(name)
|
70
|
+
File.open(File.join(File.dirname(__FILE__), 'fixtures', name), 'r')
|
71
|
+
end
|
72
|
+
|
73
|
+
def grid
|
74
|
+
@grid ||= Mongo::Grid.new(MongoMapper.database)
|
75
|
+
end
|
76
|
+
|
77
|
+
def key_names
|
78
|
+
[:id, :name, :type, :size]
|
79
|
+
end
|
40
80
|
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
require 'helper'
|
2
|
+
|
3
|
+
class IOTest < Test::Unit::TestCase
|
4
|
+
context "#initialize" do
|
5
|
+
should "set attributes from hash" do
|
6
|
+
Joint::IO.new(:name => 'foo').name.should == 'foo'
|
7
|
+
end
|
8
|
+
end
|
9
|
+
|
10
|
+
should "default content_type to plain text" do
|
11
|
+
Joint::IO.new.content_type.should == 'plain/text'
|
12
|
+
end
|
13
|
+
|
14
|
+
should "default size to content size" do
|
15
|
+
content = 'This is my content'
|
16
|
+
Joint::IO.new(:content => content).size.should == content.size
|
17
|
+
end
|
18
|
+
|
19
|
+
should "alias path to name" do
|
20
|
+
Joint::IO.new(:name => 'foo').path.should == 'foo'
|
21
|
+
end
|
22
|
+
|
23
|
+
context "#read" do
|
24
|
+
should "return content" do
|
25
|
+
Joint::IO.new(:content => 'Testing').read.should == 'Testing'
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
data/test/test_joint.rb
CHANGED
@@ -1,45 +1,5 @@
|
|
1
1
|
require 'helper'
|
2
2
|
|
3
|
-
class Asset
|
4
|
-
include MongoMapper::Document
|
5
|
-
plugin Joint
|
6
|
-
|
7
|
-
key :title, String
|
8
|
-
attachment :image
|
9
|
-
attachment :file
|
10
|
-
end
|
11
|
-
|
12
|
-
class BaseModel
|
13
|
-
include MongoMapper::Document
|
14
|
-
plugin Joint
|
15
|
-
attachment :file
|
16
|
-
end
|
17
|
-
|
18
|
-
class Image < BaseModel; attachment :image end
|
19
|
-
class Video < BaseModel; attachment :video end
|
20
|
-
|
21
|
-
module JointTestHelpers
|
22
|
-
def all_files
|
23
|
-
[@file, @image, @image2, @test1, @test2]
|
24
|
-
end
|
25
|
-
|
26
|
-
def rewind_files
|
27
|
-
all_files.each { |file| file.rewind }
|
28
|
-
end
|
29
|
-
|
30
|
-
def open_file(name)
|
31
|
-
File.open(File.join(File.dirname(__FILE__), 'fixtures', name), 'r')
|
32
|
-
end
|
33
|
-
|
34
|
-
def grid
|
35
|
-
@grid ||= Mongo::Grid.new(MongoMapper.database)
|
36
|
-
end
|
37
|
-
|
38
|
-
def key_names
|
39
|
-
[:id, :name, :type, :size]
|
40
|
-
end
|
41
|
-
end
|
42
|
-
|
43
3
|
class JointTest < Test::Unit::TestCase
|
44
4
|
include JointTestHelpers
|
45
5
|
|
@@ -56,6 +16,45 @@ class JointTest < Test::Unit::TestCase
|
|
56
16
|
all_files.each { |file| file.close }
|
57
17
|
end
|
58
18
|
|
19
|
+
context ".name" do
|
20
|
+
should "return original_filename" do
|
21
|
+
def @image.original_filename
|
22
|
+
'frank.jpg'
|
23
|
+
end
|
24
|
+
Joint.name(@image).should == 'frank.jpg'
|
25
|
+
end
|
26
|
+
|
27
|
+
should "fall back to File.basename" do
|
28
|
+
Joint.name(@image).should == 'mr_t.jpg'
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
context ".size" do
|
33
|
+
should "return size" do
|
34
|
+
def @image.size
|
35
|
+
25
|
36
|
+
end
|
37
|
+
Joint.size(@image).should == 25
|
38
|
+
end
|
39
|
+
|
40
|
+
should "fall back to File.size" do
|
41
|
+
Joint.size(@image).should == 13661
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
context ".type" do
|
46
|
+
should "return type" do
|
47
|
+
def @image.content_type
|
48
|
+
'plain/text'
|
49
|
+
end
|
50
|
+
Joint.type(@image).should == 'plain/text'
|
51
|
+
end
|
52
|
+
|
53
|
+
should "fall back to Wand" do
|
54
|
+
Joint.type(@image).should == 'image/jpeg'
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
59
58
|
context "Using Joint plugin" do
|
60
59
|
should "add each attachment to attachment_names" do
|
61
60
|
Asset.attachment_names.should == Set.new([:image, :file])
|
@@ -343,4 +342,23 @@ class JointTest < Test::Unit::TestCase
|
|
343
342
|
model.should be_valid
|
344
343
|
end
|
345
344
|
end
|
345
|
+
|
346
|
+
context "Assigning joint io instance" do
|
347
|
+
setup do
|
348
|
+
io = Joint::IO.new({
|
349
|
+
:name => 'foo.txt',
|
350
|
+
:content_type => 'plain/text',
|
351
|
+
:content => 'This is my stuff',
|
352
|
+
:size => 19,
|
353
|
+
})
|
354
|
+
@asset = Asset.create(:file => io)
|
355
|
+
end
|
356
|
+
|
357
|
+
should "work" do
|
358
|
+
@asset.file_name.should == 'foo.txt'
|
359
|
+
@asset.file_size.should == 19
|
360
|
+
@asset.file_type.should == 'plain/text'
|
361
|
+
@asset.file.read.should == 'This is my stuff'
|
362
|
+
end
|
363
|
+
end
|
346
364
|
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:
|
4
|
+
hash: 15
|
5
5
|
prerelease: false
|
6
6
|
segments:
|
7
7
|
- 0
|
8
8
|
- 5
|
9
|
-
-
|
10
|
-
version: 0.5.
|
9
|
+
- 2
|
10
|
+
version: 0.5.2
|
11
11
|
platform: ruby
|
12
12
|
authors:
|
13
13
|
- John Nunemaker
|
@@ -15,7 +15,7 @@ autorequire:
|
|
15
15
|
bindir: bin
|
16
16
|
cert_chain: []
|
17
17
|
|
18
|
-
date: 2010-12-
|
18
|
+
date: 2010-12-30 00:00:00 -05:00
|
19
19
|
default_executable:
|
20
20
|
dependencies:
|
21
21
|
- !ruby/object:Gem::Dependency
|
@@ -122,6 +122,10 @@ files:
|
|
122
122
|
- Rakefile
|
123
123
|
- joint.gemspec
|
124
124
|
- lib/joint.rb
|
125
|
+
- lib/joint/attachment_proxy.rb
|
126
|
+
- lib/joint/class_methods.rb
|
127
|
+
- lib/joint/instance_methods.rb
|
128
|
+
- lib/joint/io.rb
|
125
129
|
- lib/joint/version.rb
|
126
130
|
- specs.watchr
|
127
131
|
- test/fixtures/harmony.png
|
@@ -130,6 +134,7 @@ files:
|
|
130
134
|
- test/fixtures/test2.txt
|
131
135
|
- test/fixtures/unixref.pdf
|
132
136
|
- test/helper.rb
|
137
|
+
- test/joint/test_io.rb
|
133
138
|
- test/test_joint.rb
|
134
139
|
has_rdoc: true
|
135
140
|
homepage: http://github.com/jnunemaker/joint
|
@@ -172,4 +177,5 @@ test_files:
|
|
172
177
|
- test/fixtures/test2.txt
|
173
178
|
- test/fixtures/unixref.pdf
|
174
179
|
- test/helper.rb
|
180
|
+
- test/joint/test_io.rb
|
175
181
|
- test/test_joint.rb
|