PageRenderTime 157ms CodeModel.GetById 46ms RepoModel.GetById 14ms app.codeStats 1ms

/test/ziptest.rb

https://github.com/ddonahue99/rubyzip
Ruby | 1662 lines | 1421 code | 213 blank | 28 comment | 61 complexity | 4f7e7719fe98d2b78609119443accc05 MD5 | raw file
  1. #!/usr/bin/env ruby
  2. $VERBOSE = true
  3. $: << "../lib"
  4. require 'test/unit'
  5. require 'fileutils'
  6. require 'zip/zip'
  7. require 'gentestfiles'
  8. include Zip
  9. class ZipEntryTest < Test::Unit::TestCase
  10. TEST_ZIPFILE = "someZipFile.zip"
  11. TEST_COMMENT = "a comment"
  12. TEST_COMPRESSED_SIZE = 1234
  13. TEST_CRC = 325324
  14. TEST_EXTRA = "Some data here"
  15. TEST_COMPRESSIONMETHOD = ZipEntry::DEFLATED
  16. TEST_NAME = "entry name"
  17. TEST_SIZE = 8432
  18. TEST_ISDIRECTORY = false
  19. def test_constructorAndGetters
  20. entry = ZipEntry.new(TEST_ZIPFILE,
  21. TEST_NAME,
  22. TEST_COMMENT,
  23. TEST_EXTRA,
  24. TEST_COMPRESSED_SIZE,
  25. TEST_CRC,
  26. TEST_COMPRESSIONMETHOD,
  27. TEST_SIZE)
  28. assert_equal(TEST_COMMENT, entry.comment)
  29. assert_equal(TEST_COMPRESSED_SIZE, entry.compressed_size)
  30. assert_equal(TEST_CRC, entry.crc)
  31. assert_instance_of(Zip::ZipExtraField, entry.extra)
  32. assert_equal(TEST_COMPRESSIONMETHOD, entry.compression_method)
  33. assert_equal(TEST_NAME, entry.name)
  34. assert_equal(TEST_SIZE, entry.size)
  35. assert_equal(TEST_ISDIRECTORY, entry.is_directory)
  36. end
  37. def test_is_directoryAndIsFile
  38. assert(ZipEntry.new(TEST_ZIPFILE, "hello").file?)
  39. assert(! ZipEntry.new(TEST_ZIPFILE, "hello").directory?)
  40. assert(ZipEntry.new(TEST_ZIPFILE, "dir/hello").file?)
  41. assert(! ZipEntry.new(TEST_ZIPFILE, "dir/hello").directory?)
  42. assert(ZipEntry.new(TEST_ZIPFILE, "hello/").directory?)
  43. assert(! ZipEntry.new(TEST_ZIPFILE, "hello/").file?)
  44. assert(ZipEntry.new(TEST_ZIPFILE, "dir/hello/").directory?)
  45. assert(! ZipEntry.new(TEST_ZIPFILE, "dir/hello/").file?)
  46. end
  47. def test_equality
  48. entry1 = ZipEntry.new("file.zip", "name", "isNotCompared",
  49. "something extra", 123, 1234,
  50. ZipEntry::DEFLATED, 10000)
  51. entry2 = ZipEntry.new("file.zip", "name", "isNotComparedXXX",
  52. "something extra", 123, 1234,
  53. ZipEntry::DEFLATED, 10000)
  54. entry3 = ZipEntry.new("file.zip", "name2", "isNotComparedXXX",
  55. "something extra", 123, 1234,
  56. ZipEntry::DEFLATED, 10000)
  57. entry4 = ZipEntry.new("file.zip", "name2", "isNotComparedXXX",
  58. "something extraXX", 123, 1234,
  59. ZipEntry::DEFLATED, 10000)
  60. entry5 = ZipEntry.new("file.zip", "name2", "isNotComparedXXX",
  61. "something extraXX", 12, 1234,
  62. ZipEntry::DEFLATED, 10000)
  63. entry6 = ZipEntry.new("file.zip", "name2", "isNotComparedXXX",
  64. "something extraXX", 12, 123,
  65. ZipEntry::DEFLATED, 10000)
  66. entry7 = ZipEntry.new("file.zip", "name2", "isNotComparedXXX",
  67. "something extraXX", 12, 123,
  68. ZipEntry::STORED, 10000)
  69. entry8 = ZipEntry.new("file.zip", "name2", "isNotComparedXXX",
  70. "something extraXX", 12, 123,
  71. ZipEntry::STORED, 100000)
  72. assert_equal(entry1, entry1)
  73. assert_equal(entry1, entry2)
  74. assert(entry2 != entry3)
  75. assert(entry3 != entry4)
  76. assert(entry4 != entry5)
  77. assert(entry5 != entry6)
  78. assert(entry6 != entry7)
  79. assert(entry7 != entry8)
  80. assert(entry7 != "hello")
  81. assert(entry7 != 12)
  82. end
  83. def test_compare
  84. assert_equal(0, (ZipEntry.new("zf.zip", "a") <=> ZipEntry.new("zf.zip", "a")))
  85. assert_equal(1, (ZipEntry.new("zf.zip", "b") <=> ZipEntry.new("zf.zip", "a")))
  86. assert_equal(-1, (ZipEntry.new("zf.zip", "a") <=> ZipEntry.new("zf.zip", "b")))
  87. entries = [
  88. ZipEntry.new("zf.zip", "5"),
  89. ZipEntry.new("zf.zip", "1"),
  90. ZipEntry.new("zf.zip", "3"),
  91. ZipEntry.new("zf.zip", "4"),
  92. ZipEntry.new("zf.zip", "0"),
  93. ZipEntry.new("zf.zip", "2")
  94. ]
  95. entries.sort!
  96. assert_equal("0", entries[0].to_s)
  97. assert_equal("1", entries[1].to_s)
  98. assert_equal("2", entries[2].to_s)
  99. assert_equal("3", entries[3].to_s)
  100. assert_equal("4", entries[4].to_s)
  101. assert_equal("5", entries[5].to_s)
  102. end
  103. def test_parentAsString
  104. entry1 = ZipEntry.new("zf.zip", "aa")
  105. entry2 = ZipEntry.new("zf.zip", "aa/")
  106. entry3 = ZipEntry.new("zf.zip", "aa/bb")
  107. entry4 = ZipEntry.new("zf.zip", "aa/bb/")
  108. entry5 = ZipEntry.new("zf.zip", "aa/bb/cc")
  109. entry6 = ZipEntry.new("zf.zip", "aa/bb/cc/")
  110. assert_equal(nil, entry1.parent_as_string)
  111. assert_equal(nil, entry2.parent_as_string)
  112. assert_equal("aa/", entry3.parent_as_string)
  113. assert_equal("aa/", entry4.parent_as_string)
  114. assert_equal("aa/bb/", entry5.parent_as_string)
  115. assert_equal("aa/bb/", entry6.parent_as_string)
  116. end
  117. def test_entry_name_cannot_start_with_slash
  118. assert_raise(ZipEntryNameError) { ZipEntry.new("zf.zip", "/hej/der") }
  119. end
  120. end
  121. module IOizeString
  122. attr_reader :tell
  123. def read(count = nil)
  124. @tell ||= 0
  125. count = size unless count
  126. retVal = slice(@tell, count)
  127. @tell += count
  128. return retVal
  129. end
  130. def seek(index, offset)
  131. @tell ||= 0
  132. case offset
  133. when IO::SEEK_END
  134. newPos = size + index
  135. when IO::SEEK_SET
  136. newPos = index
  137. when IO::SEEK_CUR
  138. newPos = @tell + index
  139. else
  140. raise "Error in test method IOizeString::seek"
  141. end
  142. if (newPos < 0 || newPos >= size)
  143. raise Errno::EINVAL
  144. else
  145. @tell=newPos
  146. end
  147. end
  148. def reset
  149. @tell = 0
  150. end
  151. end
  152. class ZipLocalEntryTest < Test::Unit::TestCase
  153. def test_read_local_entryHeaderOfFirstTestZipEntry
  154. File.open(TestZipFile::TEST_ZIP3.zip_name, "rb") {
  155. |file|
  156. entry = ZipEntry.read_local_entry(file)
  157. assert_equal("", entry.comment)
  158. # Differs from windows and unix because of CR LF
  159. # assert_equal(480, entry.compressed_size)
  160. # assert_equal(0x2a27930f, entry.crc)
  161. # extra field is 21 bytes long
  162. # probably contains some unix attrutes or something
  163. # disabled: assert_equal(nil, entry.extra)
  164. assert_equal(ZipEntry::DEFLATED, entry.compression_method)
  165. assert_equal(TestZipFile::TEST_ZIP3.entry_names[0], entry.name)
  166. assert_equal(File.size(TestZipFile::TEST_ZIP3.entry_names[0]), entry.size)
  167. assert(! entry.is_directory)
  168. }
  169. end
  170. def test_readDateTime
  171. File.open("data/rubycode.zip", "rb") {
  172. |file|
  173. entry = ZipEntry.read_local_entry(file)
  174. assert_equal("zippedruby1.rb", entry.name)
  175. assert_equal(Time.at(1019261638), entry.time)
  176. }
  177. end
  178. def test_read_local_entryFromNonZipFile
  179. File.open("data/file2.txt") {
  180. |file|
  181. assert_equal(nil, ZipEntry.read_local_entry(file))
  182. }
  183. end
  184. def test_read_local_entryFromTruncatedZipFile
  185. zipFragment=""
  186. File.open(TestZipFile::TEST_ZIP2.zip_name) { |f| zipFragment = f.read(12) } # local header is at least 30 bytes
  187. zipFragment.extend(IOizeString).reset
  188. entry = ZipEntry.new
  189. entry.read_local_entry(zipFragment)
  190. fail "ZipError expected"
  191. rescue ZipError
  192. end
  193. def test_writeEntry
  194. entry = ZipEntry.new("file.zip", "entryName", "my little comment",
  195. "thisIsSomeExtraInformation", 100, 987654,
  196. ZipEntry::DEFLATED, 400)
  197. write_to_file("localEntryHeader.bin", "centralEntryHeader.bin", entry)
  198. entryReadLocal, entryReadCentral = read_from_file("localEntryHeader.bin", "centralEntryHeader.bin")
  199. compare_local_entry_headers(entry, entryReadLocal)
  200. compare_c_dir_entry_headers(entry, entryReadCentral)
  201. end
  202. private
  203. def compare_local_entry_headers(entry1, entry2)
  204. assert_equal(entry1.compressed_size , entry2.compressed_size)
  205. assert_equal(entry1.crc , entry2.crc)
  206. assert_equal(entry1.extra , entry2.extra)
  207. assert_equal(entry1.compression_method, entry2.compression_method)
  208. assert_equal(entry1.name , entry2.name)
  209. assert_equal(entry1.size , entry2.size)
  210. assert_equal(entry1.localHeaderOffset, entry2.localHeaderOffset)
  211. end
  212. def compare_c_dir_entry_headers(entry1, entry2)
  213. compare_local_entry_headers(entry1, entry2)
  214. assert_equal(entry1.comment, entry2.comment)
  215. end
  216. def write_to_file(localFileName, centralFileName, entry)
  217. File.open(localFileName, "wb") { |f| entry.write_local_entry(f) }
  218. File.open(centralFileName, "wb") { |f| entry.write_c_dir_entry(f) }
  219. end
  220. def read_from_file(localFileName, centralFileName)
  221. localEntry = nil
  222. cdirEntry = nil
  223. File.open(localFileName, "rb") { |f| localEntry = ZipEntry.read_local_entry(f) }
  224. File.open(centralFileName, "rb") { |f| cdirEntry = ZipEntry.read_c_dir_entry(f) }
  225. return [localEntry, cdirEntry]
  226. end
  227. end
  228. module DecompressorTests
  229. # expects @refText, @refLines and @decompressor
  230. TEST_FILE="data/file1.txt"
  231. def setup
  232. @refText=""
  233. File.open(TEST_FILE) { |f| @refText = f.read }
  234. @refLines = @refText.split($/)
  235. end
  236. def test_readEverything
  237. assert_equal(@refText, @decompressor.sysread)
  238. end
  239. def test_readInChunks
  240. chunkSize = 5
  241. while (decompressedChunk = @decompressor.sysread(chunkSize))
  242. assert_equal(@refText.slice!(0, chunkSize), decompressedChunk)
  243. end
  244. assert_equal(0, @refText.size)
  245. end
  246. def test_mixingReadsAndProduceInput
  247. # Just some preconditions to make sure we have enough data for this test
  248. assert(@refText.length > 1000)
  249. assert(@refLines.length > 40)
  250. assert_equal(@refText[0...100], @decompressor.sysread(100))
  251. assert(! @decompressor.input_finished?)
  252. buf = @decompressor.produce_input
  253. assert_equal(@refText[100...(100+buf.length)], buf)
  254. end
  255. end
  256. class InflaterTest < Test::Unit::TestCase
  257. include DecompressorTests
  258. def setup
  259. super
  260. @file = File.new("data/file1.txt.deflatedData", "rb")
  261. @decompressor = Inflater.new(@file)
  262. end
  263. def teardown
  264. @file.close
  265. end
  266. end
  267. class PassThruDecompressorTest < Test::Unit::TestCase
  268. include DecompressorTests
  269. def setup
  270. super
  271. @file = File.new(TEST_FILE)
  272. @decompressor = PassThruDecompressor.new(@file, File.size(TEST_FILE))
  273. end
  274. def teardown
  275. @file.close
  276. end
  277. end
  278. module AssertEntry
  279. def assert_next_entry(filename, zis)
  280. assert_entry(filename, zis, zis.get_next_entry.name)
  281. end
  282. def assert_entry(filename, zis, entryName)
  283. assert_equal(filename, entryName)
  284. assert_entryContentsForStream(filename, zis, entryName)
  285. end
  286. def assert_entryContentsForStream(filename, zis, entryName)
  287. File.open(filename, "rb") {
  288. |file|
  289. expected = file.read
  290. actual = zis.read
  291. if (expected != actual)
  292. if ((expected && actual) && (expected.length > 400 || actual.length > 400))
  293. zipEntryFilename=entryName+".zipEntry"
  294. File.open(zipEntryFilename, "wb") { |file| file << actual }
  295. fail("File '#{filename}' is different from '#{zipEntryFilename}'")
  296. else
  297. assert_equal(expected, actual)
  298. end
  299. end
  300. }
  301. end
  302. def AssertEntry.assert_contents(filename, aString)
  303. fileContents = ""
  304. File.open(filename, "rb") { |f| fileContents = f.read }
  305. if (fileContents != aString)
  306. if (fileContents.length > 400 || aString.length > 400)
  307. stringFile = filename + ".other"
  308. File.open(stringFile, "wb") { |f| f << aString }
  309. fail("File '#{filename}' is different from contents of string stored in '#{stringFile}'")
  310. else
  311. assert_equal(fileContents, aString)
  312. end
  313. end
  314. end
  315. def assert_stream_contents(zis, testZipFile)
  316. assert(zis != nil)
  317. testZipFile.entry_names.each {
  318. |entryName|
  319. assert_next_entry(entryName, zis)
  320. }
  321. assert_equal(nil, zis.get_next_entry)
  322. end
  323. def assert_test_zip_contents(testZipFile)
  324. ZipInputStream.open(testZipFile.zip_name) {
  325. |zis|
  326. assert_stream_contents(zis, testZipFile)
  327. }
  328. end
  329. def assert_entryContents(zipFile, entryName, filename = entryName.to_s)
  330. zis = zipFile.get_input_stream(entryName)
  331. assert_entryContentsForStream(filename, zis, entryName)
  332. ensure
  333. zis.close if zis
  334. end
  335. end
  336. class ZipInputStreamTest < Test::Unit::TestCase
  337. include AssertEntry
  338. def test_new
  339. zis = ZipInputStream.new(TestZipFile::TEST_ZIP2.zip_name)
  340. assert_stream_contents(zis, TestZipFile::TEST_ZIP2)
  341. assert_equal(true, zis.eof?)
  342. zis.close
  343. end
  344. def test_openWithBlock
  345. ZipInputStream.open(TestZipFile::TEST_ZIP2.zip_name) {
  346. |zis|
  347. assert_stream_contents(zis, TestZipFile::TEST_ZIP2)
  348. assert_equal(true, zis.eof?)
  349. }
  350. end
  351. def test_openWithoutBlock
  352. zis = ZipInputStream.open(TestZipFile::TEST_ZIP2.zip_name)
  353. assert_stream_contents(zis, TestZipFile::TEST_ZIP2)
  354. end
  355. def test_incompleteReads
  356. ZipInputStream.open(TestZipFile::TEST_ZIP2.zip_name) {
  357. |zis|
  358. entry = zis.get_next_entry # longAscii.txt
  359. assert_equal(false, zis.eof?)
  360. assert_equal(TestZipFile::TEST_ZIP2.entry_names[0], entry.name)
  361. assert zis.gets.length > 0
  362. assert_equal(false, zis.eof?)
  363. entry = zis.get_next_entry # empty.txt
  364. assert_equal(TestZipFile::TEST_ZIP2.entry_names[1], entry.name)
  365. assert_equal(0, entry.size)
  366. assert_equal(nil, zis.gets)
  367. assert_equal(true, zis.eof?)
  368. entry = zis.get_next_entry # empty_chmod640.txt
  369. assert_equal(TestZipFile::TEST_ZIP2.entry_names[2], entry.name)
  370. assert_equal(0, entry.size)
  371. assert_equal(nil, zis.gets)
  372. assert_equal(true, zis.eof?)
  373. entry = zis.get_next_entry # short.txt
  374. assert_equal(TestZipFile::TEST_ZIP2.entry_names[3], entry.name)
  375. assert zis.gets.length > 0
  376. entry = zis.get_next_entry # longBinary.bin
  377. assert_equal(TestZipFile::TEST_ZIP2.entry_names[4], entry.name)
  378. assert zis.gets.length > 0
  379. }
  380. end
  381. def test_rewind
  382. ZipInputStream.open(TestZipFile::TEST_ZIP2.zip_name) {
  383. |zis|
  384. e = zis.get_next_entry
  385. assert_equal(TestZipFile::TEST_ZIP2.entry_names[0], e.name)
  386. # Do a little reading
  387. buf = ""
  388. buf << zis.read(100)
  389. buf << (zis.gets || "")
  390. buf << (zis.gets || "")
  391. assert_equal(false, zis.eof?)
  392. zis.rewind
  393. buf2 = ""
  394. buf2 << zis.read(100)
  395. buf2 << (zis.gets || "")
  396. buf2 << (zis.gets || "")
  397. assert_equal(buf, buf2)
  398. zis.rewind
  399. assert_equal(false, zis.eof?)
  400. assert_entry(e.name, zis, e.name)
  401. }
  402. end
  403. def test_mix_read_and_gets
  404. ZipInputStream.open(TestZipFile::TEST_ZIP2.zip_name) {
  405. |zis|
  406. e = zis.get_next_entry
  407. assert_equal("#!/usr/bin/env ruby", zis.gets.chomp)
  408. assert_equal(false, zis.eof?)
  409. assert_equal("", zis.gets.chomp)
  410. assert_equal(false, zis.eof?)
  411. assert_equal("$VERBOSE =", zis.read(10))
  412. assert_equal(false, zis.eof?)
  413. }
  414. end
  415. end
  416. module CrcTest
  417. class TestOutputStream
  418. include IOExtras::AbstractOutputStream
  419. attr_accessor :buffer
  420. def initialize
  421. @buffer = ""
  422. end
  423. def << (data)
  424. @buffer << data
  425. self
  426. end
  427. end
  428. def run_crc_test(compressorClass)
  429. str = "Here's a nice little text to compute the crc for! Ho hum, it is nice nice nice nice indeed."
  430. fakeOut = TestOutputStream.new
  431. deflater = compressorClass.new(fakeOut)
  432. deflater << str
  433. assert_equal(0x919920fc, deflater.crc)
  434. end
  435. end
  436. class PassThruCompressorTest < Test::Unit::TestCase
  437. include CrcTest
  438. def test_size
  439. File.open("dummy.txt", "wb") {
  440. |file|
  441. compressor = PassThruCompressor.new(file)
  442. assert_equal(0, compressor.size)
  443. t1 = "hello world"
  444. t2 = ""
  445. t3 = "bingo"
  446. compressor << t1
  447. assert_equal(compressor.size, t1.size)
  448. compressor << t2
  449. assert_equal(compressor.size, t1.size + t2.size)
  450. compressor << t3
  451. assert_equal(compressor.size, t1.size + t2.size + t3.size)
  452. }
  453. end
  454. def test_crc
  455. run_crc_test(PassThruCompressor)
  456. end
  457. end
  458. class DeflaterTest < Test::Unit::TestCase
  459. include CrcTest
  460. def test_outputOperator
  461. txt = load_file("data/file2.txt")
  462. deflate(txt, "deflatertest.bin")
  463. inflatedTxt = inflate("deflatertest.bin")
  464. assert_equal(txt, inflatedTxt)
  465. end
  466. private
  467. def load_file(fileName)
  468. txt = nil
  469. File.open(fileName, "rb") { |f| txt = f.read }
  470. end
  471. def deflate(data, fileName)
  472. File.open(fileName, "wb") {
  473. |file|
  474. deflater = Deflater.new(file)
  475. deflater << data
  476. deflater.finish
  477. assert_equal(deflater.size, data.size)
  478. file << "trailing data for zlib with -MAX_WBITS"
  479. }
  480. end
  481. def inflate(fileName)
  482. txt = nil
  483. File.open(fileName, "rb") {
  484. |file|
  485. inflater = Inflater.new(file)
  486. txt = inflater.sysread
  487. }
  488. end
  489. def test_crc
  490. run_crc_test(Deflater)
  491. end
  492. end
  493. class ZipOutputStreamTest < Test::Unit::TestCase
  494. include AssertEntry
  495. TEST_ZIP = TestZipFile::TEST_ZIP2.clone
  496. TEST_ZIP.zip_name = "output.zip"
  497. def test_new
  498. zos = ZipOutputStream.new(TEST_ZIP.zip_name)
  499. zos.comment = TEST_ZIP.comment
  500. write_test_zip(zos)
  501. zos.close
  502. assert_test_zip_contents(TEST_ZIP)
  503. end
  504. def test_open
  505. ZipOutputStream.open(TEST_ZIP.zip_name) {
  506. |zos|
  507. zos.comment = TEST_ZIP.comment
  508. write_test_zip(zos)
  509. }
  510. assert_test_zip_contents(TEST_ZIP)
  511. end
  512. def test_write_buffer
  513. buffer = ZipOutputStream.write_buffer {
  514. |zos|
  515. zos.comment = TEST_ZIP.comment
  516. write_test_zip(zos)
  517. }
  518. File.open(TEST_ZIP.zip_name, 'w') { |f| f.write buffer.string }
  519. assert_test_zip_contents(TEST_ZIP)
  520. end
  521. def test_writingToClosedStream
  522. assert_i_o_error_in_closed_stream { |zos| zos << "hello world" }
  523. assert_i_o_error_in_closed_stream { |zos| zos.puts "hello world" }
  524. assert_i_o_error_in_closed_stream { |zos| zos.write "hello world" }
  525. end
  526. def test_cannotOpenFile
  527. name = TestFiles::EMPTY_TEST_DIR
  528. begin
  529. zos = ZipOutputStream.open(name)
  530. rescue Exception
  531. assert($!.kind_of?(Errno::EISDIR) || # Linux
  532. $!.kind_of?(Errno::EEXIST) || # Windows/cygwin
  533. $!.kind_of?(Errno::EACCES), # Windows
  534. "Expected Errno::EISDIR (or on win/cygwin: Errno::EEXIST), but was: #{$!.class}")
  535. end
  536. end
  537. def test_put_next_entry
  538. stored_text = "hello world in stored text"
  539. entry_name = "file1"
  540. comment = "my comment"
  541. ZipOutputStream.open(TEST_ZIP.zip_name) do
  542. |zos|
  543. zos.put_next_entry(entry_name, comment, nil, ZipEntry::STORED)
  544. zos << stored_text
  545. end
  546. assert(File.read(TEST_ZIP.zip_name)[stored_text])
  547. ZipFile.open(TEST_ZIP.zip_name) do
  548. |zf|
  549. assert_equal(stored_text, zf.read(entry_name))
  550. end
  551. end
  552. def assert_i_o_error_in_closed_stream
  553. assert_raise(IOError) {
  554. zos = ZipOutputStream.new("test_putOnClosedStream.zip")
  555. zos.close
  556. yield zos
  557. }
  558. end
  559. def write_test_zip(zos)
  560. TEST_ZIP.entry_names.each {
  561. |entryName|
  562. zos.put_next_entry(entryName)
  563. File.open(entryName, "rb") { |f| zos.write(f.read) }
  564. }
  565. end
  566. end
  567. module Enumerable
  568. def compare_enumerables(otherEnumerable)
  569. otherAsArray = otherEnumerable.to_a
  570. index=0
  571. each_with_index {
  572. |element, index|
  573. return false unless yield(element, otherAsArray[index])
  574. }
  575. return self.size == otherAsArray.size
  576. end
  577. end
  578. class ZipCentralDirectoryEntryTest < Test::Unit::TestCase
  579. def test_read_from_stream
  580. File.open("data/testDirectory.bin", "rb") {
  581. |file|
  582. entry = ZipEntry.read_c_dir_entry(file)
  583. assert_equal("longAscii.txt", entry.name)
  584. assert_equal(ZipEntry::DEFLATED, entry.compression_method)
  585. assert_equal(106490, entry.size)
  586. assert_equal(3784, entry.compressed_size)
  587. assert_equal(0xfcd1799c, entry.crc)
  588. assert_equal("", entry.comment)
  589. entry = ZipEntry.read_c_dir_entry(file)
  590. assert_equal("empty.txt", entry.name)
  591. assert_equal(ZipEntry::STORED, entry.compression_method)
  592. assert_equal(0, entry.size)
  593. assert_equal(0, entry.compressed_size)
  594. assert_equal(0x0, entry.crc)
  595. assert_equal("", entry.comment)
  596. entry = ZipEntry.read_c_dir_entry(file)
  597. assert_equal("short.txt", entry.name)
  598. assert_equal(ZipEntry::STORED, entry.compression_method)
  599. assert_equal(6, entry.size)
  600. assert_equal(6, entry.compressed_size)
  601. assert_equal(0xbb76fe69, entry.crc)
  602. assert_equal("", entry.comment)
  603. entry = ZipEntry.read_c_dir_entry(file)
  604. assert_equal("longBinary.bin", entry.name)
  605. assert_equal(ZipEntry::DEFLATED, entry.compression_method)
  606. assert_equal(1000024, entry.size)
  607. assert_equal(70847, entry.compressed_size)
  608. assert_equal(0x10da7d59, entry.crc)
  609. assert_equal("", entry.comment)
  610. entry = ZipEntry.read_c_dir_entry(file)
  611. assert_equal(nil, entry)
  612. # Fields that are not check by this test:
  613. # version made by 2 bytes
  614. # version needed to extract 2 bytes
  615. # general purpose bit flag 2 bytes
  616. # last mod file time 2 bytes
  617. # last mod file date 2 bytes
  618. # compressed size 4 bytes
  619. # uncompressed size 4 bytes
  620. # disk number start 2 bytes
  621. # internal file attributes 2 bytes
  622. # external file attributes 4 bytes
  623. # relative offset of local header 4 bytes
  624. # file name (variable size)
  625. # extra field (variable size)
  626. # file comment (variable size)
  627. }
  628. end
  629. def test_ReadEntryFromTruncatedZipFile
  630. fragment=""
  631. File.open("data/testDirectory.bin") { |f| fragment = f.read(12) } # cdir entry header is at least 46 bytes
  632. fragment.extend(IOizeString)
  633. entry = ZipEntry.new
  634. entry.read_c_dir_entry(fragment)
  635. fail "ZipError expected"
  636. rescue ZipError
  637. end
  638. end
  639. class ZipEntrySetTest < Test::Unit::TestCase
  640. ZIP_ENTRIES = [
  641. ZipEntry.new("zipfile.zip", "name1", "comment1"),
  642. ZipEntry.new("zipfile.zip", "name2", "comment1"),
  643. ZipEntry.new("zipfile.zip", "name3", "comment1"),
  644. ZipEntry.new("zipfile.zip", "name4", "comment1"),
  645. ZipEntry.new("zipfile.zip", "name5", "comment1"),
  646. ZipEntry.new("zipfile.zip", "name6", "comment1")
  647. ]
  648. def setup
  649. @zipEntrySet = ZipEntrySet.new(ZIP_ENTRIES)
  650. end
  651. def test_include
  652. assert(@zipEntrySet.include?(ZIP_ENTRIES.first))
  653. assert(! @zipEntrySet.include?(ZipEntry.new("different.zip", "different", "aComment")))
  654. end
  655. def test_size
  656. assert_equal(ZIP_ENTRIES.size, @zipEntrySet.size)
  657. assert_equal(ZIP_ENTRIES.size, @zipEntrySet.length)
  658. @zipEntrySet << ZipEntry.new("a", "b", "c")
  659. assert_equal(ZIP_ENTRIES.size + 1, @zipEntrySet.length)
  660. end
  661. def test_add
  662. zes = ZipEntrySet.new
  663. entry1 = ZipEntry.new("zf.zip", "name1")
  664. entry2 = ZipEntry.new("zf.zip", "name2")
  665. zes << entry1
  666. assert(zes.include?(entry1))
  667. zes.push(entry2)
  668. assert(zes.include?(entry2))
  669. end
  670. def test_delete
  671. assert_equal(ZIP_ENTRIES.size, @zipEntrySet.size)
  672. entry = @zipEntrySet.delete(ZIP_ENTRIES.first)
  673. assert_equal(ZIP_ENTRIES.size - 1, @zipEntrySet.size)
  674. assert_equal(ZIP_ENTRIES.first, entry)
  675. entry = @zipEntrySet.delete(ZIP_ENTRIES.first)
  676. assert_equal(ZIP_ENTRIES.size - 1, @zipEntrySet.size)
  677. assert_nil(entry)
  678. end
  679. def test_each
  680. # Tested indirectly via each_with_index
  681. count = 0
  682. @zipEntrySet.each_with_index {
  683. |entry, index|
  684. assert(ZIP_ENTRIES.include?(entry))
  685. count = count.succ
  686. }
  687. assert_equal(ZIP_ENTRIES.size, count)
  688. end
  689. def test_entries
  690. assert_equal(ZIP_ENTRIES.sort, @zipEntrySet.entries.sort)
  691. end
  692. def test_compound
  693. newEntry = ZipEntry.new("zf.zip", "new entry", "new entry's comment")
  694. assert_equal(ZIP_ENTRIES.size, @zipEntrySet.size)
  695. @zipEntrySet << newEntry
  696. assert_equal(ZIP_ENTRIES.size + 1, @zipEntrySet.size)
  697. assert(@zipEntrySet.include?(newEntry))
  698. @zipEntrySet.delete(newEntry)
  699. assert_equal(ZIP_ENTRIES.size, @zipEntrySet.size)
  700. end
  701. def test_dup
  702. copy = @zipEntrySet.dup
  703. assert_equal(@zipEntrySet, copy)
  704. # demonstrate that this is a deep copy
  705. copy.entries[0].name = "a totally different name"
  706. assert(@zipEntrySet != copy)
  707. end
  708. def test_parent
  709. entries = [
  710. ZipEntry.new("zf.zip", "a"),
  711. ZipEntry.new("zf.zip", "a/"),
  712. ZipEntry.new("zf.zip", "a/b"),
  713. ZipEntry.new("zf.zip", "a/b/"),
  714. ZipEntry.new("zf.zip", "a/b/c"),
  715. ZipEntry.new("zf.zip", "a/b/c/")
  716. ]
  717. entrySet = ZipEntrySet.new(entries)
  718. assert_equal(nil, entrySet.parent(entries[0]))
  719. assert_equal(nil, entrySet.parent(entries[1]))
  720. assert_equal(entries[1], entrySet.parent(entries[2]))
  721. assert_equal(entries[1], entrySet.parent(entries[3]))
  722. assert_equal(entries[3], entrySet.parent(entries[4]))
  723. assert_equal(entries[3], entrySet.parent(entries[5]))
  724. end
  725. def test_glob
  726. res = @zipEntrySet.glob('name[2-4]')
  727. assert_equal(3, res.size)
  728. assert_equal(ZIP_ENTRIES[1,3], res)
  729. end
  730. def test_glob2
  731. entries = [
  732. ZipEntry.new("zf.zip", "a/"),
  733. ZipEntry.new("zf.zip", "a/b/b1"),
  734. ZipEntry.new("zf.zip", "a/b/c/"),
  735. ZipEntry.new("zf.zip", "a/b/c/c1")
  736. ]
  737. entrySet = ZipEntrySet.new(entries)
  738. assert_equal(entries[0,1], entrySet.glob("*"))
  739. # assert_equal(entries[FIXME], entrySet.glob("**"))
  740. # res = entrySet.glob('a*')
  741. # assert_equal(entries.size, res.size)
  742. # assert_equal(entrySet.map { |e| e.name }, res.map { |e| e.name })
  743. end
  744. end
  745. class ZipCentralDirectoryTest < Test::Unit::TestCase
  746. def test_read_from_stream
  747. File.open(TestZipFile::TEST_ZIP2.zip_name, "rb") {
  748. |zipFile|
  749. cdir = ZipCentralDirectory.read_from_stream(zipFile)
  750. assert_equal(TestZipFile::TEST_ZIP2.entry_names.size, cdir.size)
  751. assert(cdir.entries.sort.compare_enumerables(TestZipFile::TEST_ZIP2.entry_names.sort) {
  752. |cdirEntry, testEntryName|
  753. cdirEntry.name == testEntryName
  754. })
  755. assert_equal(TestZipFile::TEST_ZIP2.comment, cdir.comment)
  756. }
  757. end
  758. def test_readFromInvalidStream
  759. File.open("data/file2.txt", "rb") {
  760. |zipFile|
  761. cdir = ZipCentralDirectory.new
  762. cdir.read_from_stream(zipFile)
  763. }
  764. fail "ZipError expected!"
  765. rescue ZipError
  766. end
  767. def test_ReadFromTruncatedZipFile
  768. fragment=""
  769. File.open("data/testDirectory.bin") { |f| fragment = f.read }
  770. fragment.slice!(12) # removed part of first cdir entry. eocd structure still complete
  771. fragment.extend(IOizeString)
  772. entry = ZipCentralDirectory.new
  773. entry.read_from_stream(fragment)
  774. fail "ZipError expected"
  775. rescue ZipError
  776. end
  777. def test_write_to_stream
  778. entries = [ ZipEntry.new("file.zip", "flimse", "myComment", "somethingExtra"),
  779. ZipEntry.new("file.zip", "secondEntryName"),
  780. ZipEntry.new("file.zip", "lastEntry.txt", "Has a comment too") ]
  781. cdir = ZipCentralDirectory.new(entries, "my zip comment")
  782. File.open("cdirtest.bin", "wb") { |f| cdir.write_to_stream(f) }
  783. cdirReadback = ZipCentralDirectory.new
  784. File.open("cdirtest.bin", "rb") { |f| cdirReadback.read_from_stream(f) }
  785. assert_equal(cdir.entries.sort, cdirReadback.entries.sort)
  786. end
  787. def test_equality
  788. cdir1 = ZipCentralDirectory.new([ ZipEntry.new("file.zip", "flimse", nil,
  789. "somethingExtra"),
  790. ZipEntry.new("file.zip", "secondEntryName"),
  791. ZipEntry.new("file.zip", "lastEntry.txt") ],
  792. "my zip comment")
  793. cdir2 = ZipCentralDirectory.new([ ZipEntry.new("file.zip", "flimse", nil,
  794. "somethingExtra"),
  795. ZipEntry.new("file.zip", "secondEntryName"),
  796. ZipEntry.new("file.zip", "lastEntry.txt") ],
  797. "my zip comment")
  798. cdir3 = ZipCentralDirectory.new([ ZipEntry.new("file.zip", "flimse", nil,
  799. "somethingExtra"),
  800. ZipEntry.new("file.zip", "secondEntryName"),
  801. ZipEntry.new("file.zip", "lastEntry.txt") ],
  802. "comment?")
  803. cdir4 = ZipCentralDirectory.new([ ZipEntry.new("file.zip", "flimse", nil,
  804. "somethingExtra"),
  805. ZipEntry.new("file.zip", "lastEntry.txt") ],
  806. "comment?")
  807. assert_equal(cdir1, cdir1)
  808. assert_equal(cdir1, cdir2)
  809. assert(cdir1 != cdir3)
  810. assert(cdir2 != cdir3)
  811. assert(cdir2 != cdir3)
  812. assert(cdir3 != cdir4)
  813. assert(cdir3 != "hello")
  814. end
  815. end
  816. class BasicZipFileTest < Test::Unit::TestCase
  817. include AssertEntry
  818. def setup
  819. @zipFile = ZipFile.new(TestZipFile::TEST_ZIP2.zip_name)
  820. @testEntryNameIndex=0
  821. end
  822. def test_entries
  823. assert_equal(TestZipFile::TEST_ZIP2.entry_names.sort,
  824. @zipFile.entries.entries.sort.map {|e| e.name} )
  825. end
  826. def test_each
  827. count = 0
  828. visited = {}
  829. @zipFile.each {
  830. |entry|
  831. assert(TestZipFile::TEST_ZIP2.entry_names.include?(entry.name))
  832. assert(! visited.include?(entry.name))
  833. visited[entry.name] = nil
  834. count = count.succ
  835. }
  836. assert_equal(TestZipFile::TEST_ZIP2.entry_names.length, count)
  837. end
  838. def test_foreach
  839. count = 0
  840. visited = {}
  841. ZipFile.foreach(TestZipFile::TEST_ZIP2.zip_name) {
  842. |entry|
  843. assert(TestZipFile::TEST_ZIP2.entry_names.include?(entry.name))
  844. assert(! visited.include?(entry.name))
  845. visited[entry.name] = nil
  846. count = count.succ
  847. }
  848. assert_equal(TestZipFile::TEST_ZIP2.entry_names.length, count)
  849. end
  850. def test_get_input_stream
  851. count = 0
  852. visited = {}
  853. @zipFile.each {
  854. |entry|
  855. assert_entry(entry.name, @zipFile.get_input_stream(entry), entry.name)
  856. assert(! visited.include?(entry.name))
  857. visited[entry.name] = nil
  858. count = count.succ
  859. }
  860. assert_equal(TestZipFile::TEST_ZIP2.entry_names.length, count)
  861. end
  862. def test_get_input_streamBlock
  863. fileAndEntryName = @zipFile.entries.first.name
  864. @zipFile.get_input_stream(fileAndEntryName) {
  865. |zis|
  866. assert_entryContentsForStream(fileAndEntryName,
  867. zis,
  868. fileAndEntryName)
  869. }
  870. end
  871. end
  872. module CommonZipFileFixture
  873. include AssertEntry
  874. EMPTY_FILENAME = "emptyZipFile.zip"
  875. TEST_ZIP = TestZipFile::TEST_ZIP2.clone
  876. TEST_ZIP.zip_name = "5entry_copy.zip"
  877. def setup
  878. File.delete(EMPTY_FILENAME) if File.exists?(EMPTY_FILENAME)
  879. FileUtils.cp(TestZipFile::TEST_ZIP2.zip_name, TEST_ZIP.zip_name)
  880. end
  881. end
  882. class ZipFileTest < Test::Unit::TestCase
  883. include CommonZipFileFixture
  884. def test_createFromScratchToBuffer
  885. comment = "a short comment"
  886. buffer = ZipFile.add_buffer do |zf|
  887. zf.get_output_stream("myFile") { |os| os.write "myFile contains just this" }
  888. zf.mkdir("dir1")
  889. zf.comment = comment
  890. end
  891. File.open(EMPTY_FILENAME, 'w') { |file| file.write buffer.string }
  892. `cp #{EMPTY_FILENAME} ~/test.zip`
  893. zfRead = ZipFile.new(EMPTY_FILENAME)
  894. assert_equal(comment, zfRead.comment)
  895. assert_equal(2, zfRead.entries.length)
  896. end
  897. def test_createFromScratch
  898. comment = "a short comment"
  899. zf = ZipFile.new(EMPTY_FILENAME, ZipFile::CREATE)
  900. zf.get_output_stream("myFile") { |os| os.write "myFile contains just this" }
  901. zf.mkdir("dir1")
  902. zf.comment = comment
  903. zf.close
  904. zfRead = ZipFile.new(EMPTY_FILENAME)
  905. assert_equal(comment, zfRead.comment)
  906. assert_equal(2, zfRead.entries.length)
  907. end
  908. def test_get_output_stream
  909. entryCount = nil
  910. ZipFile.open(TEST_ZIP.zip_name) {
  911. |zf|
  912. entryCount = zf.size
  913. zf.get_output_stream('newEntry.txt') {
  914. |os|
  915. os.write "Putting stuff in newEntry.txt"
  916. }
  917. assert_equal(entryCount+1, zf.size)
  918. assert_equal("Putting stuff in newEntry.txt", zf.read("newEntry.txt"))
  919. zf.get_output_stream(zf.get_entry('data/generated/empty.txt')) {
  920. |os|
  921. os.write "Putting stuff in data/generated/empty.txt"
  922. }
  923. assert_equal(entryCount+1, zf.size)
  924. assert_equal("Putting stuff in data/generated/empty.txt", zf.read("data/generated/empty.txt"))
  925. zf.get_output_stream('entry.bin') {
  926. |os|
  927. os.write(File.open('data/generated/5entry.zip', 'rb').read)
  928. }
  929. }
  930. ZipFile.open(TEST_ZIP.zip_name) {
  931. |zf|
  932. assert_equal(entryCount+2, zf.size)
  933. assert_equal("Putting stuff in newEntry.txt", zf.read("newEntry.txt"))
  934. assert_equal("Putting stuff in data/generated/empty.txt", zf.read("data/generated/empty.txt"))
  935. assert_equal(File.open('data/generated/5entry.zip', 'rb').read, zf.read("entry.bin"))
  936. }
  937. end
  938. def test_add
  939. srcFile = "data/file2.txt"
  940. entryName = "newEntryName.rb"
  941. assert(File.exists?(srcFile))
  942. zf = ZipFile.new(EMPTY_FILENAME, ZipFile::CREATE)
  943. zf.add(entryName, srcFile)
  944. zf.close
  945. zfRead = ZipFile.new(EMPTY_FILENAME)
  946. assert_equal("", zfRead.comment)
  947. assert_equal(1, zfRead.entries.length)
  948. assert_equal(entryName, zfRead.entries.first.name)
  949. AssertEntry.assert_contents(srcFile,
  950. zfRead.get_input_stream(entryName) { |zis| zis.read })
  951. end
  952. def test_addExistingEntryName
  953. assert_raise(ZipEntryExistsError) {
  954. ZipFile.open(TEST_ZIP.zip_name) {
  955. |zf|
  956. zf.add(zf.entries.first.name, "data/file2.txt")
  957. }
  958. }
  959. end
  960. def test_addExistingEntryNameReplace
  961. gotCalled = false
  962. replacedEntry = nil
  963. ZipFile.open(TEST_ZIP.zip_name) {
  964. |zf|
  965. replacedEntry = zf.entries.first.name
  966. zf.add(replacedEntry, "data/file2.txt") { gotCalled = true; true }
  967. }
  968. assert(gotCalled)
  969. ZipFile.open(TEST_ZIP.zip_name) {
  970. |zf|
  971. assert_contains(zf, replacedEntry, "data/file2.txt")
  972. }
  973. end
  974. def test_addDirectory
  975. ZipFile.open(TEST_ZIP.zip_name) {
  976. |zf|
  977. zf.add(TestFiles::EMPTY_TEST_DIR, TestFiles::EMPTY_TEST_DIR)
  978. }
  979. ZipFile.open(TEST_ZIP.zip_name) {
  980. |zf|
  981. dirEntry = zf.entries.detect { |e| e.name == TestFiles::EMPTY_TEST_DIR+"/" }
  982. assert(dirEntry.is_directory)
  983. }
  984. end
  985. def test_remove
  986. entryToRemove, *remainingEntries = TEST_ZIP.entry_names
  987. FileUtils.cp(TestZipFile::TEST_ZIP2.zip_name, TEST_ZIP.zip_name)
  988. zf = ZipFile.new(TEST_ZIP.zip_name)
  989. assert(zf.entries.map { |e| e.name }.include?(entryToRemove))
  990. zf.remove(entryToRemove)
  991. assert(! zf.entries.map { |e| e.name }.include?(entryToRemove))
  992. assert_equal(zf.entries.map {|x| x.name }.sort, remainingEntries.sort)
  993. zf.close
  994. zfRead = ZipFile.new(TEST_ZIP.zip_name)
  995. assert(! zfRead.entries.map { |e| e.name }.include?(entryToRemove))
  996. assert_equal(zfRead.entries.map {|x| x.name }.sort, remainingEntries.sort)
  997. zfRead.close
  998. end
  999. def test_rename
  1000. entryToRename, *remainingEntries = TEST_ZIP.entry_names
  1001. zf = ZipFile.new(TEST_ZIP.zip_name)
  1002. assert(zf.entries.map { |e| e.name }.include?(entryToRename))
  1003. contents = zf.read(entryToRename)
  1004. newName = "changed entry name"
  1005. assert(! zf.entries.map { |e| e.name }.include?(newName))
  1006. zf.rename(entryToRename, newName)
  1007. assert(zf.entries.map { |e| e.name }.include?(newName))
  1008. assert_equal(contents, zf.read(newName))
  1009. zf.close
  1010. zfRead = ZipFile.new(TEST_ZIP.zip_name)
  1011. assert(zfRead.entries.map { |e| e.name }.include?(newName))
  1012. assert_equal(contents, zf.read(newName))
  1013. zfRead.close
  1014. end
  1015. def test_renameToExistingEntry
  1016. oldEntries = nil
  1017. ZipFile.open(TEST_ZIP.zip_name) { |zf| oldEntries = zf.entries }
  1018. assert_raise(ZipEntryExistsError) {
  1019. ZipFile.open(TEST_ZIP.zip_name) {
  1020. |zf|
  1021. zf.rename(zf.entries[0], zf.entries[1].name)
  1022. }
  1023. }
  1024. ZipFile.open(TEST_ZIP.zip_name) {
  1025. |zf|
  1026. assert_equal(oldEntries.sort.map{ |e| e.name }, zf.entries.sort.map{ |e| e.name })
  1027. }
  1028. end
  1029. def test_renameToExistingEntryOverwrite
  1030. oldEntries = nil
  1031. ZipFile.open(TEST_ZIP.zip_name) { |zf| oldEntries = zf.entries }
  1032. gotCalled = false
  1033. renamedEntryName = nil
  1034. ZipFile.open(TEST_ZIP.zip_name) {
  1035. |zf|
  1036. renamedEntryName = zf.entries[0].name
  1037. zf.rename(zf.entries[0], zf.entries[1].name) { gotCalled = true; true }
  1038. }
  1039. assert(gotCalled)
  1040. oldEntries.delete_if { |e| e.name == renamedEntryName }
  1041. ZipFile.open(TEST_ZIP.zip_name) {
  1042. |zf|
  1043. assert_equal(oldEntries.sort.map{ |e| e.name },
  1044. zf.entries.sort.map{ |e| e.name })
  1045. }
  1046. end
  1047. def test_renameNonEntry
  1048. nonEntry = "bogusEntry"
  1049. target_entry = "target_entryName"
  1050. zf = ZipFile.new(TEST_ZIP.zip_name)
  1051. assert(! zf.entries.include?(nonEntry))
  1052. assert_raise(Errno::ENOENT) {
  1053. zf.rename(nonEntry, target_entry)
  1054. }
  1055. zf.commit
  1056. assert(! zf.entries.include?(target_entry))
  1057. ensure
  1058. zf.close
  1059. end
  1060. def test_renameEntryToExistingEntry
  1061. entry1, entry2, *remaining = TEST_ZIP.entry_names
  1062. zf = ZipFile.new(TEST_ZIP.zip_name)
  1063. assert_raise(ZipEntryExistsError) {
  1064. zf.rename(entry1, entry2)
  1065. }
  1066. ensure
  1067. zf.close
  1068. end
  1069. def test_replace
  1070. entryToReplace = TEST_ZIP.entry_names[2]
  1071. newEntrySrcFilename = "data/file2.txt"
  1072. zf = ZipFile.new(TEST_ZIP.zip_name)
  1073. zf.replace(entryToReplace, newEntrySrcFilename)
  1074. zf.close
  1075. zfRead = ZipFile.new(TEST_ZIP.zip_name)
  1076. AssertEntry::assert_contents(newEntrySrcFilename,
  1077. zfRead.get_input_stream(entryToReplace) { |is| is.read })
  1078. AssertEntry::assert_contents(TEST_ZIP.entry_names[0],
  1079. zfRead.get_input_stream(TEST_ZIP.entry_names[0]) { |is| is.read })
  1080. AssertEntry::assert_contents(TEST_ZIP.entry_names[1],
  1081. zfRead.get_input_stream(TEST_ZIP.entry_names[1]) { |is| is.read })
  1082. AssertEntry::assert_contents(TEST_ZIP.entry_names[3],
  1083. zfRead.get_input_stream(TEST_ZIP.entry_names[3]) { |is| is.read })
  1084. zfRead.close
  1085. end
  1086. def test_replaceNonEntry
  1087. entryToReplace = "nonExistingEntryname"
  1088. ZipFile.open(TEST_ZIP.zip_name) {
  1089. |zf|
  1090. assert_raise(Errno::ENOENT) {
  1091. zf.replace(entryToReplace, "data/file2.txt")
  1092. }
  1093. }
  1094. end
  1095. def test_commit
  1096. newName = "renamedFirst"
  1097. zf = ZipFile.new(TEST_ZIP.zip_name)
  1098. oldName = zf.entries.first
  1099. zf.rename(oldName, newName)
  1100. zf.commit
  1101. zfRead = ZipFile.new(TEST_ZIP.zip_name)
  1102. assert(zfRead.entries.detect { |e| e.name == newName } != nil)
  1103. assert(zfRead.entries.detect { |e| e.name == oldName } == nil)
  1104. zfRead.close
  1105. zf.close
  1106. end
  1107. def test_write_buffer
  1108. newName = "renamedFirst"
  1109. zf = ZipFile.new(TEST_ZIP.zip_name)
  1110. oldName = zf.entries.first
  1111. zf.rename(oldName, newName)
  1112. buffer = zf.write_buffer
  1113. File.open(TEST_ZIP.zip_name, 'w') { |f| f.write buffer.string }
  1114. zfRead = ZipFile.new(TEST_ZIP.zip_name)
  1115. assert(zfRead.entries.detect { |e| e.name == newName } != nil)
  1116. assert(zfRead.entries.detect { |e| e.name == oldName } == nil)
  1117. zfRead.close
  1118. zf.close
  1119. end
  1120. # This test tests that after commit, you
  1121. # can delete the file you used to add the entry to the zip file
  1122. # with
  1123. def test_commitUseZipEntry
  1124. FileUtils.cp(TestFiles::RANDOM_ASCII_FILE1, "okToDelete.txt")
  1125. zf = ZipFile.open(TEST_ZIP.zip_name)
  1126. zf.add("okToDelete.txt", "okToDelete.txt")
  1127. assert_contains(zf, "okToDelete.txt")
  1128. zf.commit
  1129. File.rename("okToDelete.txt", "okToDeleteMoved.txt")
  1130. assert_contains(zf, "okToDelete.txt", "okToDeleteMoved.txt")
  1131. end
  1132. # def test_close
  1133. # zf = ZipFile.new(TEST_ZIP.zip_name)
  1134. # zf.close
  1135. # assert_raise(IOError) {
  1136. # zf.extract(TEST_ZIP.entry_names.first, "hullubullu")
  1137. # }
  1138. # end
  1139. def test_compound1
  1140. renamedName = "renamedName"
  1141. originalEntries = []
  1142. begin
  1143. zf = ZipFile.new(TEST_ZIP.zip_name)
  1144. originalEntries = zf.entries.dup
  1145. assert_not_contains(zf, TestFiles::RANDOM_ASCII_FILE1)
  1146. zf.add(TestFiles::RANDOM_ASCII_FILE1,
  1147. TestFiles::RANDOM_ASCII_FILE1)
  1148. assert_contains(zf, TestFiles::RANDOM_ASCII_FILE1)
  1149. zf.rename(zf.entries[0], renamedName)
  1150. assert_contains(zf, renamedName)
  1151. TestFiles::BINARY_TEST_FILES.each {
  1152. |filename|
  1153. zf.add(filename, filename)
  1154. assert_contains(zf, filename)
  1155. }
  1156. assert_contains(zf, originalEntries.last.to_s)
  1157. zf.remove(originalEntries.last.to_s)
  1158. assert_not_contains(zf, originalEntries.last.to_s)
  1159. ensure
  1160. zf.close
  1161. end
  1162. begin
  1163. zfRead = ZipFile.new(TEST_ZIP.zip_name)
  1164. assert_contains(zfRead, TestFiles::RANDOM_ASCII_FILE1)
  1165. assert_contains(zfRead, renamedName)
  1166. TestFiles::BINARY_TEST_FILES.each {
  1167. |filename|
  1168. assert_contains(zfRead, filename)
  1169. }
  1170. assert_not_contains(zfRead, originalEntries.last.to_s)
  1171. ensure
  1172. zfRead.close
  1173. end
  1174. end
  1175. def test_compound2
  1176. begin
  1177. zf = ZipFile.new(TEST_ZIP.zip_name)
  1178. originalEntries = zf.entries.dup
  1179. originalEntries.each {
  1180. |entry|
  1181. zf.remove(entry)
  1182. assert_not_contains(zf, entry)
  1183. }
  1184. assert(zf.entries.empty?)
  1185. TestFiles::ASCII_TEST_FILES.each {
  1186. |filename|
  1187. zf.add(filename, filename)
  1188. assert_contains(zf, filename)
  1189. }
  1190. assert_equal(zf.entries.sort.map { |e| e.name }, TestFiles::ASCII_TEST_FILES)
  1191. zf.rename(TestFiles::ASCII_TEST_FILES[0], "newName")
  1192. assert_not_contains(zf, TestFiles::ASCII_TEST_FILES[0])
  1193. assert_contains(zf, "newName")
  1194. ensure
  1195. zf.close
  1196. end
  1197. begin
  1198. zfRead = ZipFile.new(TEST_ZIP.zip_name)
  1199. asciiTestFiles = TestFiles::ASCII_TEST_FILES.dup
  1200. asciiTestFiles.shift
  1201. asciiTestFiles.each {
  1202. |filename|
  1203. assert_contains(zf, filename)
  1204. }
  1205. assert_contains(zf, "newName")
  1206. ensure
  1207. zfRead.close
  1208. end
  1209. end
  1210. private
  1211. def assert_contains(zf, entryName, filename = entryName)
  1212. assert(zf.entries.detect { |e| e.name == entryName} != nil, "entry #{entryName} not in #{zf.entries.join(', ')} in zip file #{zf}")
  1213. assert_entryContents(zf, entryName, filename) if File.exists?(filename)
  1214. end
  1215. def assert_not_contains(zf, entryName)
  1216. assert(zf.entries.detect { |e| e.name == entryName} == nil, "entry #{entryName} in #{zf.entries.join(', ')} in zip file #{zf}")
  1217. end
  1218. end
  1219. class ZipFileExtractTest < Test::Unit::TestCase
  1220. include CommonZipFileFixture
  1221. EXTRACTED_FILENAME = "extEntry"
  1222. ENTRY_TO_EXTRACT, *REMAINING_ENTRIES = TEST_ZIP.entry_names.reverse
  1223. def setup
  1224. super
  1225. File.delete(EXTRACTED_FILENAME) if File.exists?(EXTRACTED_FILENAME)
  1226. end
  1227. def test_extract
  1228. ZipFile.open(TEST_ZIP.zip_name) {
  1229. |zf|
  1230. zf.extract(ENTRY_TO_EXTRACT, EXTRACTED_FILENAME)
  1231. assert(File.exists?(EXTRACTED_FILENAME))
  1232. AssertEntry::assert_contents(EXTRACTED_FILENAME,
  1233. zf.get_input_stream(ENTRY_TO_EXTRACT) { |is| is.read })
  1234. File::unlink(EXTRACTED_FILENAME)
  1235. entry = zf.get_entry(ENTRY_TO_EXTRACT)
  1236. entry.extract(EXTRACTED_FILENAME)
  1237. assert(File.exists?(EXTRACTED_FILENAME))
  1238. AssertEntry::assert_contents(EXTRACTED_FILENAME,
  1239. entry.get_input_stream() { |is| is.read })
  1240. }
  1241. end
  1242. def test_extractExists
  1243. writtenText = "written text"
  1244. File.open(EXTRACTED_FILENAME, "w") { |f| f.write(writtenText) }
  1245. assert_raise(ZipDestinationFileExistsError) {
  1246. ZipFile.open(TEST_ZIP.zip_name) {
  1247. |zf|
  1248. zf.extract(zf.entries.first, EXTRACTED_FILENAME)
  1249. }
  1250. }
  1251. File.open(EXTRACTED_FILENAME, "r") {
  1252. |f|
  1253. assert_equal(writtenText, f.read)
  1254. }
  1255. end
  1256. def test_extractExistsOverwrite
  1257. writtenText = "written text"
  1258. File.open(EXTRACTED_FILENAME, "w") { |f| f.write(writtenText) }
  1259. gotCalledCorrectly = false
  1260. ZipFile.open(TEST_ZIP.zip_name) {
  1261. |zf|
  1262. zf.extract(zf.entries.first, EXTRACTED_FILENAME) {
  1263. |entry, extractLoc|
  1264. gotCalledCorrectly = zf.entries.first == entry &&
  1265. extractLoc == EXTRACTED_FILENAME
  1266. true
  1267. }
  1268. }
  1269. assert(gotCalledCorrectly)
  1270. File.open(EXTRACTED_FILENAME, "r") {
  1271. |f|
  1272. assert(writtenText != f.read)
  1273. }
  1274. end
  1275. def test_extractNonEntry
  1276. zf = ZipFile.new(TEST_ZIP.zip_name)
  1277. assert_raise(Errno::ENOENT) { zf.extract("nonExistingEntry", "nonExistingEntry") }
  1278. ensure
  1279. zf.close if zf
  1280. end
  1281. def test_extractNonEntry2
  1282. outFile = "outfile"
  1283. assert_raise(Errno::ENOENT) {
  1284. zf = ZipFile.new(TEST_ZIP.zip_name)
  1285. nonEntry = "hotdog-diddelidoo"
  1286. assert(! zf.entries.include?(nonEntry))
  1287. zf.extract(nonEntry, outFile)
  1288. zf.close
  1289. }
  1290. assert(! File.exists?(outFile))
  1291. end
  1292. end
  1293. class ZipFileExtractDirectoryTest < Test::Unit::TestCase
  1294. include CommonZipFileFixture
  1295. TEST_OUT_NAME = "emptyOutDir"
  1296. def open_zip(&aProc)
  1297. assert(aProc != nil)
  1298. ZipFile.open(TestZipFile::TEST_ZIP4.zip_name, &aProc)
  1299. end
  1300. def extract_test_dir(&aProc)
  1301. open_zip {
  1302. |zf|
  1303. zf.extract(TestFiles::EMPTY_TEST_DIR, TEST_OUT_NAME, &aProc)
  1304. }
  1305. end
  1306. def setup
  1307. super
  1308. Dir.rmdir(TEST_OUT_NAME) if File.directory? TEST_OUT_NAME
  1309. File.delete(TEST_OUT_NAME) if File.exists? TEST_OUT_NAME
  1310. end
  1311. def test_extractDirectory
  1312. extract_test_dir
  1313. assert(File.directory?(TEST_OUT_NAME))
  1314. end
  1315. def test_extractDirectoryExistsAsDir
  1316. Dir.mkdir TEST_OUT_NAME
  1317. extract_test_dir
  1318. assert(File.directory?(TEST_OUT_NAME))
  1319. end
  1320. def test_extractDirectoryExistsAsFile
  1321. File.open(TEST_OUT_NAME, "w") { |f| f.puts "something" }
  1322. assert_raise(ZipDestinationFileExistsError) { extract_test_dir }
  1323. end
  1324. def test_extractDirectoryExistsAsFileOverwrite
  1325. File.open(TEST_OUT_NAME, "w") { |f| f.puts "something" }
  1326. gotCalled = false
  1327. extract_test_dir {
  1328. |entry, destPath|
  1329. gotCalled = true
  1330. assert_equal(TEST_OUT_NAME, destPath)
  1331. assert(entry.is_directory)
  1332. true
  1333. }
  1334. assert(gotCalled)
  1335. assert(File.directory?(TEST_OUT_NAME))
  1336. end
  1337. end
  1338. class ZipExtraFieldTest < Test::Unit::TestCase
  1339. def test_new
  1340. extra_pure = ZipExtraField.new("")
  1341. extra_withstr = ZipExtraField.new("foo")
  1342. assert_instance_of(ZipExtraField, extra_pure)
  1343. assert_instance_of(ZipExtraField, extra_withstr)
  1344. end
  1345. def test_unknownfield
  1346. extra = ZipExtraField.new("foo")
  1347. assert_equal(extra["Unknown"], "foo")
  1348. extra.merge("a")
  1349. assert_equal(extra["Unknown"], "fooa")
  1350. extra.merge("barbaz")
  1351. assert_equal(extra.to_s, "fooabarbaz")
  1352. end
  1353. def test_merge
  1354. str = "UT\x5\0\x3\250$\r@Ux\0\0"
  1355. extra1 = ZipExtraField.new("")
  1356. extra2 = ZipExtraField.new(str)
  1357. assert(! extra1.member?("UniversalTime"))
  1358. assert(extra2.member?("UniversalTime"))
  1359. extra1.merge(str)
  1360. assert_equal(extra1["UniversalTime"].mtime, extra2["UniversalTime"].mtime)
  1361. end
  1362. def test_length
  1363. str = "UT\x5\0\x3\250$\r@Ux\0\0Te\0\0testit"
  1364. extra = ZipExtraField.new(str)
  1365. assert_equal(extra.local_length, extra.to_local_bin.length)
  1366. assert_equal(extra.c_dir_length, extra.to_c_dir_bin.length)
  1367. extra.merge("foo")
  1368. assert_equal(extra.local_length, extra.to_local_bin.length)
  1369. assert_equal(extra.c_dir_length, extra.to_c_dir_bin.length)
  1370. end
  1371. def test_to_s
  1372. str = "UT\x5\0\x3\250$\r@Ux\0\0Te\0\0testit"
  1373. extra = ZipExtraField.new(str)
  1374. assert_instance_of(String, extra.to_s)
  1375. s = extra.to_s
  1376. extra.merge("foo")
  1377. assert_equal(s.length + 3, extra.to_s.length)
  1378. end
  1379. def test_equality
  1380. str = "UT\x5\0\x3\250$\r@"
  1381. extra1 = ZipExtraField.new(str)
  1382. extra2 = ZipExtraField.new(str)
  1383. extra3 = ZipExtraField.new(str)
  1384. assert_equal(extra1, extra2)
  1385. extra2["UniversalTime"].mtime = Time.now
  1386. assert(extra1 != extra2)
  1387. extra3.create("IUnix")
  1388. assert(extra1 != extra3)
  1389. extra1.create("IUnix")
  1390. assert_equal(extra1, extra3)
  1391. end
  1392. end
  1393. # Copyright (C) 2002-2005 Thomas Sondergaard
  1394. # rubyzip is free software; you can redistribute it and/or
  1395. # modify it under the terms of the ruby license.