multi_zip 0.1.3

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,487 @@
1
+ shared_examples 'zip backend' do |backend_name|
2
+ let(:filename) { archive_fixture_filename }
3
+ subject { MultiZip.new(filename, :backend => backend_name) }
4
+
5
+ before do
6
+ apply_constants(backend_name)
7
+ # subject.backend = backend_name
8
+ end
9
+ after { stash_constants(backend_name) }
10
+
11
+ describe '#read_member' do
12
+ context "backend: #{backend_name}" do
13
+ context 'member found' do
14
+ archive_member_files.each do |member_file|
15
+ it "returns '#{member_file}' as a string" do
16
+ expect(
17
+ subject.read_member(member_file).bytesize
18
+ ).to eq(
19
+ archive_member_size(member_file)
20
+ )
21
+ end
22
+ end
23
+ end
24
+
25
+ context 'member not found' do
26
+ it_behaves_like 'raises MemberNotFoundError', :read_member, 'doesnt_exist'
27
+ end
28
+
29
+ context 'member is a directory' do
30
+ it_behaves_like 'raises MemberNotFoundError', :read_member, archive_member_directories.first
31
+ end
32
+
33
+ context 'archive not found' do
34
+ it_behaves_like 'raises ArchiveNotFoundError', :read_member, archive_member_files.first
35
+ end
36
+
37
+ context 'archive is not a file' do
38
+ it 'raises ArchiveNotFoundError'
39
+ end
40
+
41
+ context 'archive cannot be accessed due to permissions' do
42
+ it 'raises ArchiveNotAccessibleError'
43
+ end
44
+
45
+ context 'invalid or unreadable archive' do
46
+ it_behaves_like 'raises InvalidArchiveError', :read_member, archive_member_files.first
47
+ end
48
+ end
49
+ end
50
+
51
+ describe '#read_members' do
52
+ context "backend: #{backend_name}" do
53
+ context 'all members found' do
54
+ it 'returns the member content as an array a string in order of args' do
55
+ extracted_files = subject.read_members(archive_member_files)
56
+
57
+ archive_member_files.each_with_index do |member, i|
58
+ expect(extracted_files[i].bytesize).to eq(archive_member_size(member))
59
+ end
60
+ end
61
+ end
62
+
63
+ context 'one of the members is a directory' do
64
+ it_behaves_like 'raises MemberNotFoundError', :read_members,
65
+ [ archive_member_files.first, archive_member_directories.first ]
66
+ end
67
+
68
+ context 'one of the members is not found' do
69
+ it_behaves_like 'raises MemberNotFoundError', :read_members,
70
+ [ archive_member_files.first, 'doesnt_exist' ]
71
+ end
72
+
73
+ context 'archive not found' do
74
+ it_behaves_like 'raises ArchiveNotFoundError', :read_members, archive_member_files
75
+ end
76
+
77
+ context 'archive is not a file' do
78
+ it 'raises ArchiveNotFoundError'
79
+ end
80
+
81
+ context 'archive cannot be accessed due to permissions' do
82
+ it 'raises ArchiveNotAccessibleError'
83
+ end
84
+
85
+ context 'invalid or unreadable archive' do
86
+ it_behaves_like 'raises InvalidArchiveError', :read_members,
87
+ [ archive_member_files.first, archive_member_directories.first ]
88
+ end
89
+ end
90
+ end
91
+
92
+ describe '#extract_member' do
93
+ context "backend: #{backend_name}" do
94
+ let(:tempfile) { Tempfile.new('multi_zip_test') }
95
+
96
+ context 'member found' do
97
+ let!(:extraction_return) { subject.extract_member(archive_member_files.first, tempfile.path) }
98
+ after { tempfile.delete }
99
+ it 'writes the file to the local filesystem' do
100
+ expect(tempfile.size).to eq(archive_member_size(archive_member_files.first))
101
+ end
102
+
103
+ it 'returns the file system path written to' do
104
+ expect(extraction_return).to eq(tempfile.path)
105
+ end
106
+ end
107
+
108
+ context 'member is a directory' do
109
+ it 'raises MemberNotFoundError' do
110
+ expect(
111
+ lambda { subject.extract_member(archive_member_directories.first, tempfile.path) }
112
+ ).to raise_error(MultiZip::MemberNotFoundError)
113
+ end
114
+ end
115
+
116
+ context 'member not found' do
117
+ it 'raises MemberNotFoundError' do
118
+ expect(
119
+ lambda { subject.extract_member('doesnt_exist', tempfile.path) }
120
+ ).to raise_error(MultiZip::MemberNotFoundError)
121
+ end
122
+ end
123
+
124
+ context 'archive not found' do
125
+ it_behaves_like 'raises ArchiveNotFoundError', :extract_member, archive_member_files.first, 'destination'
126
+ end
127
+
128
+ context 'archive is not a file' do
129
+ it 'raises ArchiveNotFoundError'
130
+ end
131
+
132
+ context 'archive cannot be accessed due to permissions' do
133
+ it 'raises ArchiveNotAccessibleError'
134
+ end
135
+
136
+ context 'invalid or unreadable archive' do
137
+ let(:filename) { invalid_archive_fixture_filename }
138
+ it 'raises ArchiveInvalidError' do
139
+ expect(
140
+ lambda { subject.extract_member(archive_member_files.first, tempfile.path) }
141
+ ).to raise_error(MultiZip::InvalidArchiveError)
142
+ end
143
+ end
144
+ end
145
+ end
146
+
147
+ describe '#list_members' do
148
+ context "backend: #{backend_name}" do
149
+ context 'file contains members' do
150
+ it 'returns array member file names' do
151
+ expect(subject.list_members).to eq(archive_member_names)
152
+ end
153
+
154
+ context 'prefix provided' do
155
+ context 'files with that prefix exist' do
156
+ it 'returns only files with that prefix' do
157
+ expect(subject.list_members('dir_1/')).to eq(
158
+ [ 'dir_1/', 'dir_1/file_3.txt' ]
159
+ )
160
+ end
161
+ end
162
+
163
+ context 'no files with that prefix exist' do
164
+ it 'returns empty array' do
165
+ expect(subject.list_members('doesnt_exist/')).to eq( [ ] )
166
+ end
167
+ end
168
+ end
169
+ end
170
+
171
+ context 'contains no members, is empty archive' do
172
+ it 'returns empty array'
173
+ end
174
+
175
+ context 'archive not found' do
176
+ it_behaves_like 'raises ArchiveNotFoundError', :list_members
177
+ end
178
+
179
+ context 'archive is not a file' do
180
+ it 'raises ArchiveNotFoundError'
181
+ end
182
+
183
+ context 'archive cannot be accessed due to permissions' do
184
+ it 'raises ArchiveNotAccessibleError'
185
+ end
186
+
187
+ context 'invalid or unreadable archive' do
188
+ it_behaves_like 'raises InvalidArchiveError', :list_members
189
+ end
190
+ end
191
+ end
192
+
193
+ describe '#member_exists?' do
194
+ context "backend: #{backend_name}" do
195
+ context 'member is a file' do
196
+ it 'returns true if member exists' do
197
+ expect(subject.member_exists?(archive_member_files.first)).to be_truthy
198
+ end
199
+ end
200
+
201
+ context 'member is a directory' do
202
+ it 'returns true if member exists' do
203
+ expect(subject.member_exists?(archive_member_directories.first)).to be_truthy
204
+ end
205
+ end
206
+
207
+ it 'returns false if member does not exist' do
208
+ expect(subject.member_exists?('does_not_exist')).to be_falsey
209
+ end
210
+
211
+ context 'archive not found' do
212
+ it_behaves_like 'raises ArchiveNotFoundError', :member_exists?, archive_member_files.first
213
+ end
214
+
215
+ context 'archive is not a file' do
216
+ it 'raises ArchiveNotFoundError'
217
+ end
218
+
219
+ context 'archive cannot be accessed due to permissions' do
220
+ it 'raises ArchiveNotAccessibleError'
221
+ end
222
+
223
+ context 'invalid or unreadable archive' do
224
+ it_behaves_like 'raises InvalidArchiveError', :member_exists?, archive_member_files.first
225
+ end
226
+ end
227
+ end
228
+
229
+ describe '#write_member' do
230
+ context "backend: #{backend_name}" do
231
+ after { FileUtils.rm(filename) if File.exists?(filename) }
232
+
233
+ let(:filename) { "/tmp/multizip_test.zip" }
234
+ let(:member_file_name) { 'test_member_file' }
235
+ let(:member_file_contents) { 'file contents here' }
236
+
237
+ context 'archive did not exist' do
238
+ before { expect(File.exists?(filename)).to be_falsey }
239
+
240
+ let!(:result) do
241
+ subject.write_member(member_file_name, member_file_contents)
242
+ end
243
+
244
+ it 'archive is created' do
245
+ expect(File.exists?(filename)).to be_truthy
246
+ end
247
+
248
+ context 'member added successfully' do
249
+ it 'returns true' do
250
+ expect(result).to be_truthy
251
+ end
252
+ it 'adds the member to the file' do
253
+ expect(
254
+ subject.read_member(member_file_name)
255
+ ).to eq(
256
+ member_file_contents
257
+ )
258
+ end
259
+ end
260
+
261
+ context 'member not successfully added' do
262
+ it 'raises MemberNotAddedError'
263
+ it 'does not add member to the archive/archive is empty'
264
+ end
265
+ end
266
+
267
+ context 'archive already exists' do
268
+ before do
269
+ FileUtils.cp(archive_fixture_filename, filename)
270
+ expect(File.exists?(filename)).to be_truthy
271
+ end
272
+
273
+ let!(:preexisting_members) { subject.list_members }
274
+
275
+ let!(:result) do
276
+ subject.write_member(member_file_name, member_file_contents)
277
+ end
278
+
279
+ context 'member added successfully' do
280
+ it 'returns true' do
281
+ expect(result).to be_truthy
282
+ end
283
+
284
+ context 'member with that name already exists' do
285
+ let(:member_file_name) { 'mimetype' }
286
+ it 'returns true' do
287
+ expect(result).to be_truthy
288
+ end
289
+ it 'it overwrites the member file name with new data' do
290
+ expect(
291
+ subject.read_member(member_file_name)
292
+ ).to eq(
293
+ member_file_contents
294
+ )
295
+ end
296
+ end
297
+
298
+ it 'adds the member to the file' do
299
+ expect(
300
+ subject.read_member(member_file_name)
301
+ ).to eq(
302
+ member_file_contents
303
+ )
304
+ end
305
+
306
+ it 'does not remove preexisting members' do
307
+ expect(
308
+ subject.list_members - preexisting_members
309
+ ).to eq(
310
+ [ member_file_name ]
311
+ )
312
+ end
313
+ end
314
+
315
+ context 'member not successfully added' do
316
+ it 'raises MemberNotAddedError'
317
+ it 'does not add member to the archive'
318
+ it 'does not remove preexisting members from the archive'
319
+ end
320
+ end
321
+
322
+ context 'archive is not a file' do
323
+ it 'raises ArchiveNotFoundError'
324
+ end
325
+
326
+ context 'archive cannot be accessed due to permissions' do
327
+ it 'raises ArchiveNotAccessibleError'
328
+ end
329
+
330
+ context 'invalid or unreadable archive' do
331
+ it 'raises ArchiveInvalidError'
332
+ end
333
+ end
334
+ end
335
+
336
+ describe '#remove_member' do
337
+ context "backend: #{backend_name}" do
338
+ subject { MultiZip.new(temp_filename, :backend => backend_name) }
339
+
340
+ let(:temp_filename) { "/tmp/multizip_test.zip" }
341
+ let(:member_file_name) { archive_member_files.first }
342
+
343
+ after do
344
+ FileUtils.rm(temp_filename) if File.exists?(temp_filename)
345
+ end
346
+
347
+ context 'archive exists' do
348
+ before do
349
+ FileUtils.cp(filename, temp_filename)
350
+ expect(
351
+ MultiZip.new(temp_filename).member_exists?(member_file_name)
352
+ ).to be_truthy
353
+ end
354
+
355
+ let!(:result) do
356
+ subject.remove_member(member_file_name)
357
+ end
358
+
359
+ context 'member removed successfully' do
360
+ it 'returns true' do
361
+ expect(result).to be_truthy
362
+ end
363
+ it 'removes the member from the file' do
364
+ expect(
365
+ MultiZip.new(temp_filename).member_exists?(member_file_name)
366
+ ).to be_falsey
367
+ end
368
+ it 'does not remove any other members' do
369
+ zip = MultiZip.new(temp_filename)
370
+ (archive_member_files - [member_file_name]).each do |mfn|
371
+ expect(zip.member_exists?(mfn)).to be_truthy
372
+ end
373
+ end
374
+ end
375
+
376
+ context 'member not successfully added' do
377
+ it 'raises MemberNotRemovedError'
378
+ it 'does not remove member from the archive'
379
+ end
380
+ end
381
+
382
+ context 'archive not found' do
383
+ it_behaves_like 'raises ArchiveNotFoundError', :remove_member, archive_member_files.first
384
+ end
385
+
386
+ context 'archive is not a file' do
387
+ it 'raises ArchiveNotFoundError'
388
+ end
389
+
390
+ context 'archive cannot be accessed due to permissions' do
391
+ it 'raises ArchiveNotAccessibleError'
392
+ end
393
+
394
+ context 'invalid or unreadable archive' do
395
+ it 'raises ArchiveInvalidError'
396
+ end
397
+ end
398
+ end
399
+
400
+ describe '#remove_members' do
401
+ context "backend: #{backend_name}" do
402
+ subject { MultiZip.new(temp_filename, :backend => backend_name) }
403
+
404
+ let(:temp_filename) { "/tmp/multizip_test.zip" }
405
+ let(:member_file_names) { archive_member_files[0..1] }
406
+
407
+ after do
408
+ FileUtils.rm(temp_filename) if File.exists?(temp_filename)
409
+ end
410
+
411
+ context 'archive exists' do
412
+ before do
413
+ FileUtils.cp(filename, temp_filename)
414
+ member_file_names.each do |mfn|
415
+ expect(
416
+ MultiZip.new(temp_filename).member_exists?(mfn)
417
+ ).to be_truthy
418
+ end
419
+ end
420
+
421
+ let!(:result) do
422
+ subject.remove_members(member_file_names)
423
+ end
424
+
425
+ context 'members removed successfully' do
426
+ it 'returns true' do
427
+ expect(result).to be_truthy
428
+ end
429
+ it 'removes the members from the file' do
430
+ member_file_names.each do |mfn|
431
+ expect(
432
+ MultiZip.new(temp_filename).member_exists?(mfn)
433
+ ).to be_falsey
434
+ end
435
+ end
436
+ it 'does not remove any other members' do
437
+ zip = MultiZip.new(temp_filename)
438
+ (archive_member_files - member_file_names).each do |mfn|
439
+ expect(zip.member_exists?(mfn)).to be_truthy
440
+ end
441
+ end
442
+ end
443
+
444
+ context 'member not successfully added' do
445
+ it 'raises MemberNotRemovedError'
446
+ it 'does not remove member from the archive'
447
+ end
448
+ end
449
+
450
+ context 'archive not found' do
451
+ it_behaves_like 'raises ArchiveNotFoundError', :remove_members, archive_member_files
452
+ end
453
+
454
+ context 'archive is not a file' do
455
+ it 'raises ArchiveNotFoundError'
456
+ end
457
+
458
+ context 'archive cannot be accessed due to permissions' do
459
+ it 'raises ArchiveNotAccessibleError'
460
+ end
461
+
462
+ context 'invalid or unreadable archive' do
463
+ it 'raises ArchiveInvalidError'
464
+ end
465
+ end
466
+ end
467
+ end
468
+
469
+ shared_examples 'raises MemberNotFoundError' do |*args|
470
+ it 'raises MemberNotFoundError' do
471
+ expect(lambda{ subject.send(args.shift, *args) }).to raise_error(MultiZip::MemberNotFoundError)
472
+ end
473
+ end
474
+
475
+ shared_examples 'raises InvalidArchiveError' do |*args|
476
+ let(:filename) { invalid_archive_fixture_filename }
477
+ it 'raises InvalidArchiveError' do
478
+ expect(lambda{ subject.send(args.shift, *args) }).to raise_error(MultiZip::InvalidArchiveError)
479
+ end
480
+ end
481
+
482
+ shared_examples 'raises ArchiveNotFoundError' do |*args|
483
+ let(:filename) { 'doesnt_exist' }
484
+ it 'raises ArchiveNotFoundError' do
485
+ expect(lambda{ subject.send(args.shift, *args) }).to raise_error(MultiZip::ArchiveNotFoundError)
486
+ end
487
+ end
@@ -0,0 +1 @@
1
+ This is not a valid zip archive.
Binary file
@@ -0,0 +1,6 @@
1
+ require 'spec_helper'
2
+ require 'backend_shared_example'
3
+
4
+ RSpec.describe MultiZip do
5
+ it_behaves_like 'zip backend', 'archive_zip'
6
+ end
@@ -0,0 +1,8 @@
1
+ require 'spec_helper'
2
+ require 'backend_shared_example'
3
+
4
+ RSpec.describe MultiZip do
5
+ if test_with_rubyzip?
6
+ it_behaves_like 'zip backend', 'rubyzip'
7
+ end
8
+ end
@@ -0,0 +1,8 @@
1
+ require 'spec_helper'
2
+ require 'backend_shared_example'
3
+
4
+ RSpec.describe MultiZip do
5
+ if test_with_zipruby?
6
+ it_behaves_like 'zip backend', 'zipruby'
7
+ end
8
+ end
@@ -0,0 +1,53 @@
1
+ require 'spec_helper'
2
+
3
+ RSpec.describe MultiZip do
4
+ let(:filename) { archive_fixture_filename }
5
+ let(:subject) { MultiZip.new(filename) }
6
+
7
+ describe '.new' do
8
+ it 'accepts a block'
9
+ end
10
+
11
+ describe '#backend=' do
12
+ context 'supported backends' do
13
+ before do
14
+ # so we don't get NoSupportedBackendError in subject.
15
+ expect_any_instance_of(MultiZip).to receive(:default_backend)
16
+ end
17
+
18
+ backends_to_test.each do |backend_name|
19
+ it "sets backend to #{backend_name}" do
20
+ subject.backend = backend_name
21
+ expect(subject.backend).to eq(backend_name.to_sym)
22
+ end
23
+ end
24
+ end
25
+
26
+ context 'unknown backend' do
27
+ it 'raises exception' do
28
+ expect(
29
+ lambda { subject.backend = 'unsupported' }
30
+ ).to raise_exception(MultiZip::NoSupportedBackendError)
31
+ end
32
+ end
33
+ end
34
+
35
+ describe "#backend" do
36
+ context "no backend specified" do
37
+ backends_to_test.each do |gem_name|
38
+ context "#{gem_name} gem has been required" do
39
+ before do
40
+ apply_constants(gem_name)
41
+ end
42
+
43
+ after { stash_constants(gem_name) }
44
+
45
+ it "is :#{gem_name}" do
46
+ expect(subject.backend).to eq(gem_name.to_sym)
47
+ end
48
+
49
+ end
50
+ end
51
+ end
52
+ end
53
+ end