tmptation 1.3 → 1.4
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/README.md +5 -5
- data/lib/tmptation.rb +30 -10
- data/test/tmptation_test.rb +214 -206
- metadata +3 -3
data/README.md
CHANGED
@@ -13,24 +13,24 @@ Examples
|
|
13
13
|
|
14
14
|
# TmpFile is a subclass of Tempfile, with a few additions
|
15
15
|
|
16
|
-
file = TmpFile.new('name', 'contents')
|
16
|
+
file = Tmptation::TmpFile.new('name', 'contents')
|
17
17
|
|
18
18
|
file.path.exist? #=> true
|
19
19
|
file.closed? #=> false
|
20
20
|
file.read #=> "contents"
|
21
21
|
|
22
|
-
TmpFile.delete_all
|
22
|
+
Tmptation::TmpFile.delete_all
|
23
23
|
|
24
24
|
file.path.exist? #=> false
|
25
25
|
file.closed? #=> true
|
26
26
|
|
27
27
|
|
28
|
-
# TmpDir
|
28
|
+
# TmpDir behaves like Pathname, with a few additions
|
29
29
|
|
30
|
-
path = TmpDir.new
|
30
|
+
path = Tmptation::TmpDir.new
|
31
31
|
path.exist? #=> true
|
32
32
|
|
33
|
-
TmpDir.delete_all
|
33
|
+
Tmptation::TmpDir.delete_all
|
34
34
|
path.exist? #=> false
|
35
35
|
|
36
36
|
Mixins
|
data/lib/tmptation.rb
CHANGED
@@ -2,9 +2,10 @@ require 'pathname'
|
|
2
2
|
require 'tempfile'
|
3
3
|
require 'tmpdir'
|
4
4
|
require 'fileutils'
|
5
|
+
require 'forwardable'
|
5
6
|
|
6
7
|
module Tmptation
|
7
|
-
VERSION = 1.
|
8
|
+
VERSION = 1.4
|
8
9
|
|
9
10
|
# Adds a #safe_delete method that will delete the object's associated path
|
10
11
|
# (either #path or #to_s, if it exists) only if it lives within the system's
|
@@ -139,8 +140,8 @@ module Tmptation
|
|
139
140
|
end
|
140
141
|
end
|
141
142
|
|
142
|
-
#
|
143
|
-
# instances.
|
143
|
+
# Temporary directory object which behaves like core lib's Pathname, and
|
144
|
+
# allows safely deleting all of its instances.
|
144
145
|
#
|
145
146
|
# @example
|
146
147
|
#
|
@@ -150,7 +151,8 @@ module Tmptation
|
|
150
151
|
# TmpDir.delete_all
|
151
152
|
# path.exist? #=> false
|
152
153
|
#
|
153
|
-
class TmpDir
|
154
|
+
class TmpDir
|
155
|
+
extend Forwardable
|
154
156
|
include SafeDeletable
|
155
157
|
include InstanceTracking
|
156
158
|
|
@@ -164,16 +166,34 @@ module Tmptation
|
|
164
166
|
alias -@ delete_all
|
165
167
|
end
|
166
168
|
|
169
|
+
# temporary directory's path as a Pathname
|
170
|
+
#
|
171
|
+
# @return path<Pathname>
|
172
|
+
#
|
173
|
+
attr_reader :path
|
174
|
+
|
167
175
|
# @param prefix<String> optional
|
168
176
|
# prefix of directory name
|
169
177
|
#
|
170
178
|
def initialize(prefix='TmpDir-')
|
171
|
-
|
172
|
-
|
173
|
-
|
174
|
-
|
175
|
-
|
176
|
-
|
179
|
+
super()
|
180
|
+
@path = Pathname(Dir.mktmpdir(prefix)).expand_path
|
181
|
+
end
|
182
|
+
|
183
|
+
def_delegator :@path, :to_s
|
184
|
+
|
185
|
+
# Delegate Pathname methods to #path
|
186
|
+
#
|
187
|
+
# Allows TmpDir to behave like Pathname without having to use inheritence
|
188
|
+
# (which causes all sorts of issues).
|
189
|
+
#
|
190
|
+
def method_missing(name, *args) #:nodoc:
|
191
|
+
if path.respond_to?(name)
|
192
|
+
self.class.def_delegator :@path, name #method inlining
|
193
|
+
send(name, *args)
|
194
|
+
else
|
195
|
+
super
|
196
|
+
end
|
177
197
|
end
|
178
198
|
end
|
179
199
|
end
|
data/test/tmptation_test.rb
CHANGED
@@ -17,285 +17,293 @@ describe Tmptation do
|
|
17
17
|
it "should have a version" do
|
18
18
|
assert_kind_of Float, Tmptation::VERSION
|
19
19
|
end
|
20
|
-
end
|
21
20
|
|
22
|
-
describe
|
21
|
+
describe SafeDeletable do
|
23
22
|
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
assert dir.exist?
|
30
|
-
assert_match /^#{Regexp.quote(Dir.tmpdir)}/, dir.to_s
|
23
|
+
it "should delete a tmp directory" do
|
24
|
+
begin
|
25
|
+
dir = Pathname(Dir.mktmpdir('SafeDeletable-')).expand_path
|
26
|
+
dir.extend(SafeDeletable)
|
31
27
|
|
32
|
-
|
28
|
+
assert dir.exist?
|
29
|
+
assert_match /^#{Regexp.quote(Dir.tmpdir)}/, dir.to_s
|
33
30
|
|
34
|
-
|
35
|
-
|
36
|
-
|
31
|
+
dir.safe_delete
|
32
|
+
|
33
|
+
refute dir.exist?
|
34
|
+
ensure
|
35
|
+
dir.rmdir if dir.directory?
|
36
|
+
end
|
37
37
|
end
|
38
|
-
end
|
39
38
|
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
39
|
+
it "should refuse to delete a non-tmp directory" do
|
40
|
+
begin
|
41
|
+
dir = Pathname(Dir.mktmpdir('SafeDeletable-')).expand_path
|
42
|
+
dir.extend(SafeDeletable)
|
44
43
|
|
45
|
-
|
46
|
-
|
44
|
+
stub(dir).to_s { '/not/a/tmp/dir' }
|
45
|
+
refute_match /^#{Regexp.quote(Dir.tmpdir)}/, dir.to_s
|
47
46
|
|
48
|
-
|
49
|
-
|
50
|
-
|
47
|
+
assert_raises(SafeDeletable::UnsafeDelete) { dir.safe_delete }
|
48
|
+
ensure
|
49
|
+
dir.rmdir if dir.directory?
|
50
|
+
end
|
51
51
|
end
|
52
|
-
end
|
53
52
|
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
53
|
+
it "should hanled relative paths" do
|
54
|
+
begin
|
55
|
+
dir = Pathname(Dir.mktmpdir('SafeDeletable-')).relative_path_from(Pathname(Dir.pwd))
|
56
|
+
dir.extend(SafeDeletable)
|
58
57
|
|
59
|
-
|
60
|
-
|
58
|
+
assert_match /^#{Regexp.quote(Dir.tmpdir)}/, dir.expand_path.to_s
|
59
|
+
assert dir.relative?
|
61
60
|
|
62
|
-
|
61
|
+
dir.safe_delete
|
63
62
|
|
64
|
-
|
65
|
-
|
66
|
-
|
63
|
+
refute dir.exist?
|
64
|
+
ensure
|
65
|
+
dir.rmdir if dir.directory?
|
66
|
+
end
|
67
67
|
end
|
68
|
-
end
|
69
68
|
|
70
|
-
|
71
|
-
|
72
|
-
|
69
|
+
it "should handle nonexistent entries" do
|
70
|
+
dir = Pathname(Dir.tmpdir).join("nonexistentdir-#{Time.now.to_f}")
|
71
|
+
dir.extend(SafeDeletable)
|
73
72
|
|
74
|
-
|
75
|
-
|
76
|
-
|
73
|
+
refute dir.exist?
|
74
|
+
dir.safe_delete #refute raises
|
75
|
+
end
|
77
76
|
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
77
|
+
it "should use an object's #path if it exists" do
|
78
|
+
begin
|
79
|
+
file = Tempfile.new('safe_deletable')
|
80
|
+
file.extend(SafeDeletable)
|
82
81
|
|
83
|
-
|
84
|
-
|
82
|
+
assert File.exist?(file.path)
|
83
|
+
assert_match /^#{Regexp.quote(Dir.tmpdir)}/, file.path.to_s
|
85
84
|
|
86
|
-
|
85
|
+
file.safe_delete
|
87
86
|
|
88
|
-
|
89
|
-
|
90
|
-
|
87
|
+
refute File.exist?(file.path)
|
88
|
+
ensure
|
89
|
+
file.delete if File.exist?(file)
|
90
|
+
end
|
91
91
|
end
|
92
92
|
end
|
93
|
-
end
|
94
93
|
|
95
|
-
describe
|
94
|
+
describe InstanceTracking do
|
96
95
|
|
97
|
-
|
98
|
-
|
99
|
-
|
96
|
+
before do
|
97
|
+
TmpFile.instance_variable_set(:@instances, nil)
|
98
|
+
end
|
100
99
|
|
101
|
-
|
102
|
-
|
103
|
-
|
100
|
+
it "should keep track of class instances" do
|
101
|
+
klass = Class.new
|
102
|
+
klass.class_eval { include InstanceTracking }
|
104
103
|
|
105
|
-
|
104
|
+
assert_empty klass.instances
|
106
105
|
|
107
|
-
|
108
|
-
|
106
|
+
foo, bar = klass.new, klass.new
|
107
|
+
assert_equal [foo,bar], klass.instances
|
108
|
+
end
|
109
109
|
end
|
110
|
-
end
|
111
110
|
|
112
|
-
describe
|
111
|
+
describe TmpFile do
|
113
112
|
|
114
|
-
|
115
|
-
|
116
|
-
|
113
|
+
before do
|
114
|
+
TmpFile.instance_variable_set(:@instances, nil)
|
115
|
+
end
|
117
116
|
|
118
|
-
|
119
|
-
|
120
|
-
|
117
|
+
it "should implement SafeDeletable" do
|
118
|
+
assert_includes TmpFile.included_modules, SafeDeletable
|
119
|
+
end
|
121
120
|
|
122
|
-
|
123
|
-
|
124
|
-
|
121
|
+
it "should implement InstanceTracking" do
|
122
|
+
assert_includes TmpFile.included_modules, InstanceTracking
|
123
|
+
end
|
125
124
|
|
126
|
-
|
127
|
-
|
128
|
-
|
125
|
+
it "should create a new temporary file on init" do
|
126
|
+
begin
|
127
|
+
foo = TmpFile.new
|
129
128
|
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
129
|
+
assert File.exist?(foo.path)
|
130
|
+
assert_match /^#{Regexp.quote(Dir.tmpdir)}/, foo.path.to_s
|
131
|
+
ensure
|
132
|
+
foo.delete if foo.path.exist?
|
133
|
+
end
|
134
134
|
end
|
135
|
-
end
|
136
135
|
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
136
|
+
it "should provide a path as Pathname" do
|
137
|
+
begin
|
138
|
+
foo = TmpFile.new
|
139
|
+
assert_kind_of Pathname, foo.path
|
140
|
+
ensure
|
141
|
+
foo.delete if foo.path.exist?
|
142
|
+
end
|
143
143
|
end
|
144
|
-
end
|
145
144
|
|
146
|
-
|
147
|
-
|
148
|
-
|
145
|
+
it "should allow setting a name and body on init" do
|
146
|
+
begin
|
147
|
+
foo = TmpFile.new('name', 'body')
|
149
148
|
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
|
149
|
+
assert_match /^name/, foo.path.basename.to_s
|
150
|
+
assert_equal 'body', foo.read
|
151
|
+
ensure
|
152
|
+
foo.delete if foo.path.exist?
|
153
|
+
end
|
154
154
|
end
|
155
|
-
end
|
156
155
|
|
157
|
-
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
|
167
|
-
|
168
|
-
|
169
|
-
|
170
|
-
|
156
|
+
it "should delete all instances" do
|
157
|
+
begin
|
158
|
+
foo, bar = TmpFile.new, TmpFile.new
|
159
|
+
|
160
|
+
assert foo.path.exist?
|
161
|
+
assert bar.path.exist?
|
162
|
+
|
163
|
+
TmpFile.delete_all
|
164
|
+
|
165
|
+
refute foo.path.exist?
|
166
|
+
refute bar.path.exist?
|
167
|
+
ensure
|
168
|
+
foo.delete if foo.path.exist?
|
169
|
+
bar.delete if bar.path.exist?
|
170
|
+
end
|
171
171
|
end
|
172
|
-
end
|
173
172
|
|
174
|
-
|
175
|
-
|
176
|
-
|
173
|
+
it "should use #safe_delete" do
|
174
|
+
begin
|
175
|
+
foo = TmpFile.new
|
177
176
|
|
178
|
-
|
179
|
-
|
177
|
+
mock(foo).safe_delete
|
178
|
+
TmpFile.delete_all
|
180
179
|
|
181
|
-
|
182
|
-
|
183
|
-
|
180
|
+
RR.verify
|
181
|
+
ensure
|
182
|
+
foo.delete if foo.path.exist?
|
183
|
+
end
|
184
184
|
end
|
185
|
-
end
|
186
185
|
|
187
|
-
|
188
|
-
|
189
|
-
|
190
|
-
|
186
|
+
it "should close files when deleting all instances" do
|
187
|
+
begin
|
188
|
+
foo = TmpFile.new
|
189
|
+
refute foo.closed?
|
191
190
|
|
192
|
-
|
193
|
-
|
194
|
-
|
195
|
-
|
191
|
+
TmpFile.delete_all
|
192
|
+
assert foo.closed?
|
193
|
+
ensure
|
194
|
+
foo.delete if foo.path.exist?
|
195
|
+
end
|
196
196
|
end
|
197
|
-
end
|
198
197
|
|
199
|
-
|
200
|
-
|
201
|
-
|
202
|
-
|
198
|
+
it "should clear the instance references" do
|
199
|
+
begin
|
200
|
+
foo = TmpFile.new
|
201
|
+
assert_equal [foo], TmpFile.instances
|
203
202
|
|
204
|
-
|
205
|
-
|
206
|
-
|
207
|
-
|
203
|
+
TmpFile.delete_all
|
204
|
+
assert_empty TmpFile.instances
|
205
|
+
ensure
|
206
|
+
foo.delete if foo.path.exist?
|
207
|
+
end
|
208
208
|
end
|
209
209
|
end
|
210
|
-
end
|
211
210
|
|
212
|
-
describe
|
211
|
+
describe TmpDir do
|
213
212
|
|
214
|
-
|
215
|
-
|
216
|
-
|
213
|
+
before do
|
214
|
+
TmpDir.instance_variable_set(:@instances, nil)
|
215
|
+
end
|
217
216
|
|
218
|
-
|
219
|
-
|
220
|
-
|
217
|
+
it "should implement SafeDeletable" do
|
218
|
+
assert_includes TmpDir.included_modules, SafeDeletable
|
219
|
+
end
|
221
220
|
|
222
|
-
|
223
|
-
|
224
|
-
|
221
|
+
it "should implement InstanceTracking" do
|
222
|
+
assert_includes TmpFile.included_modules, InstanceTracking
|
223
|
+
end
|
225
224
|
|
226
|
-
|
227
|
-
|
228
|
-
|
225
|
+
it "should provide a path as Pathname" do
|
226
|
+
begin
|
227
|
+
foo = TmpDir.new
|
228
|
+
assert_kind_of Pathname, foo.path
|
229
|
+
ensure
|
230
|
+
foo.path.rmdir if foo.path.exist?
|
231
|
+
end
|
232
|
+
end
|
229
233
|
|
230
|
-
|
231
|
-
|
232
|
-
|
233
|
-
|
234
|
+
it "should allow setting a prefix on init" do
|
235
|
+
begin
|
236
|
+
foo = TmpDir.new('prefix-')
|
237
|
+
assert_match /^prefix/, foo.to_s.split('/').last
|
238
|
+
ensure
|
239
|
+
foo.path.rmdir if foo.path.exist?
|
240
|
+
end
|
234
241
|
end
|
235
|
-
end
|
236
242
|
|
237
|
-
|
238
|
-
|
239
|
-
|
240
|
-
|
241
|
-
|
242
|
-
|
243
|
+
it "should behave like a Pathname" do
|
244
|
+
begin
|
245
|
+
foo = TmpDir.new('prefix-')
|
246
|
+
|
247
|
+
assert_equal Dir.tmpdir, foo.dirname.to_s
|
248
|
+
assert_match /^\//, foo.expand_path
|
249
|
+
assert_match /^\.\./, foo.relative_path_from(Pathname(Dir.pwd))
|
250
|
+
assert_match /^prefix-/, foo.basename
|
251
|
+
ensure
|
252
|
+
foo.path.rmdir if foo.path.exist?
|
253
|
+
end
|
243
254
|
end
|
244
|
-
end
|
245
255
|
|
246
|
-
|
247
|
-
|
248
|
-
|
249
|
-
|
250
|
-
|
251
|
-
|
252
|
-
|
253
|
-
|
254
|
-
|
255
|
-
refute foo.exist?
|
256
|
-
refute bar.exist?
|
257
|
-
ensure
|
258
|
-
foo.rmdir if foo.exist?
|
259
|
-
bar.rmdir if foo.exist?
|
256
|
+
it "should create a temporary directory on init" do
|
257
|
+
begin
|
258
|
+
foo = TmpDir.new
|
259
|
+
|
260
|
+
assert foo.exist?
|
261
|
+
assert_match /^#{Regexp.quote(Dir.tmpdir)}/, foo.to_s
|
262
|
+
ensure
|
263
|
+
foo.rmdir if foo.exist?
|
264
|
+
end
|
260
265
|
end
|
261
|
-
end
|
262
266
|
|
263
|
-
|
264
|
-
|
265
|
-
|
267
|
+
it "should delete all instances" do
|
268
|
+
begin
|
269
|
+
foo, bar = TmpDir.new, TmpDir.new
|
270
|
+
|
271
|
+
assert foo.exist?
|
272
|
+
assert bar.exist?
|
266
273
|
|
267
|
-
|
268
|
-
TmpDir.delete_all
|
274
|
+
TmpDir.delete_all
|
269
275
|
|
270
|
-
|
271
|
-
|
272
|
-
|
276
|
+
refute foo.exist?
|
277
|
+
refute bar.exist?
|
278
|
+
ensure
|
279
|
+
foo.rmdir if foo.exist?
|
280
|
+
bar.rmdir if foo.exist?
|
281
|
+
end
|
273
282
|
end
|
274
|
-
end
|
275
283
|
|
276
|
-
|
277
|
-
|
278
|
-
|
279
|
-
assert_equal [foo], TmpDir.instances
|
284
|
+
it "should use #safe_delete" do
|
285
|
+
begin
|
286
|
+
foo = TmpDir.new
|
280
287
|
|
281
|
-
|
282
|
-
|
283
|
-
|
284
|
-
|
288
|
+
mock(foo).safe_delete
|
289
|
+
TmpDir.delete_all
|
290
|
+
|
291
|
+
RR.verify
|
292
|
+
ensure
|
293
|
+
foo.rmdir if foo.exist?
|
294
|
+
end
|
285
295
|
end
|
286
|
-
end
|
287
296
|
|
288
|
-
|
289
|
-
|
290
|
-
|
297
|
+
it "should clear the instance references" do
|
298
|
+
begin
|
299
|
+
foo = TmpDir.new
|
300
|
+
assert_equal [foo], TmpDir.instances
|
291
301
|
|
292
|
-
|
293
|
-
|
294
|
-
|
295
|
-
|
296
|
-
|
297
|
-
foo.rmdir if foo.exist?
|
302
|
+
TmpDir.delete_all
|
303
|
+
assert_empty TmpDir.instances
|
304
|
+
ensure
|
305
|
+
foo.rmdir if foo.exist?
|
306
|
+
end
|
298
307
|
end
|
299
308
|
end
|
300
309
|
end
|
301
|
-
|
metadata
CHANGED
@@ -4,8 +4,8 @@ version: !ruby/object:Gem::Version
|
|
4
4
|
prerelease: false
|
5
5
|
segments:
|
6
6
|
- 1
|
7
|
-
-
|
8
|
-
version: "1.
|
7
|
+
- 4
|
8
|
+
version: "1.4"
|
9
9
|
platform: ruby
|
10
10
|
authors:
|
11
11
|
- Martin Aumont
|
@@ -13,7 +13,7 @@ autorequire:
|
|
13
13
|
bindir: bin
|
14
14
|
cert_chain: []
|
15
15
|
|
16
|
-
date: 2010-11-
|
16
|
+
date: 2010-11-07 01:00:00 -07:00
|
17
17
|
default_executable:
|
18
18
|
dependencies:
|
19
19
|
- !ruby/object:Gem::Dependency
|