PageRenderTime 58ms CodeModel.GetById 20ms RepoModel.GetById 1ms app.codeStats 0ms

/vendor/rubyzip-0.5.12/test/ziptest.rb

https://github.com/carter/mephisto
Ruby | 1594 lines | 1360 code | 206 blank | 28 comment | 62 complexity | 5a5e20c1896e0d3d57acf66aa48396d2 MD5 | raw file
Possible License(s): GPL-2.0, BSD-3-Clause
  1. #!/usr/bin/env ruby
  2. $VERBOSE = true
  3. $: << "../lib"
  4. require 'test/unit'
  5. require 'zip/zip'
  6. require 'gentestfiles'
  7. include Zip
  8. class ZipEntryTest < Test::Unit::TestCase
  9. TEST_ZIPFILE = "someZipFile.zip"
  10. TEST_COMMENT = "a comment"
  11. TEST_COMPRESSED_SIZE = 1234
  12. TEST_CRC = 325324
  13. TEST_EXTRA = "Some data here"
  14. TEST_COMPRESSIONMETHOD = ZipEntry::DEFLATED
  15. TEST_NAME = "entry name"
  16. TEST_SIZE = 8432
  17. TEST_ISDIRECTORY = false
  18. def test_constructorAndGetters
  19. entry = ZipEntry.new(TEST_ZIPFILE,
  20. TEST_NAME,
  21. TEST_COMMENT,
  22. TEST_EXTRA,
  23. TEST_COMPRESSED_SIZE,
  24. TEST_CRC,
  25. TEST_COMPRESSIONMETHOD,
  26. TEST_SIZE)
  27. assert_equal(TEST_COMMENT, entry.comment)
  28. assert_equal(TEST_COMPRESSED_SIZE, entry.compressed_size)
  29. assert_equal(TEST_CRC, entry.crc)
  30. assert_instance_of(Zip::ZipExtraField, entry.extra)
  31. assert_equal(TEST_COMPRESSIONMETHOD, entry.compression_method)
  32. assert_equal(TEST_NAME, entry.name)
  33. assert_equal(TEST_SIZE, entry.size)
  34. assert_equal(TEST_ISDIRECTORY, entry.is_directory)
  35. end
  36. def test_is_directoryAndIsFile
  37. assert(ZipEntry.new(TEST_ZIPFILE, "hello").file?)
  38. assert(! ZipEntry.new(TEST_ZIPFILE, "hello").directory?)
  39. assert(ZipEntry.new(TEST_ZIPFILE, "dir/hello").file?)
  40. assert(! ZipEntry.new(TEST_ZIPFILE, "dir/hello").directory?)
  41. assert(ZipEntry.new(TEST_ZIPFILE, "hello/").directory?)
  42. assert(! ZipEntry.new(TEST_ZIPFILE, "hello/").file?)
  43. assert(ZipEntry.new(TEST_ZIPFILE, "dir/hello/").directory?)
  44. assert(! ZipEntry.new(TEST_ZIPFILE, "dir/hello/").file?)
  45. end
  46. def test_equality
  47. entry1 = ZipEntry.new("file.zip", "name", "isNotCompared",
  48. "something extra", 123, 1234,
  49. ZipEntry::DEFLATED, 10000)
  50. entry2 = ZipEntry.new("file.zip", "name", "isNotComparedXXX",
  51. "something extra", 123, 1234,
  52. ZipEntry::DEFLATED, 10000)
  53. entry3 = ZipEntry.new("file.zip", "name2", "isNotComparedXXX",
  54. "something extra", 123, 1234,
  55. ZipEntry::DEFLATED, 10000)
  56. entry4 = ZipEntry.new("file.zip", "name2", "isNotComparedXXX",
  57. "something extraXX", 123, 1234,
  58. ZipEntry::DEFLATED, 10000)
  59. entry5 = ZipEntry.new("file.zip", "name2", "isNotComparedXXX",
  60. "something extraXX", 12, 1234,
  61. ZipEntry::DEFLATED, 10000)
  62. entry6 = ZipEntry.new("file.zip", "name2", "isNotComparedXXX",
  63. "something extraXX", 12, 123,
  64. ZipEntry::DEFLATED, 10000)
  65. entry7 = ZipEntry.new("file.zip", "name2", "isNotComparedXXX",
  66. "something extraXX", 12, 123,
  67. ZipEntry::STORED, 10000)
  68. entry8 = ZipEntry.new("file.zip", "name2", "isNotComparedXXX",
  69. "something extraXX", 12, 123,
  70. ZipEntry::STORED, 100000)
  71. assert_equal(entry1, entry1)
  72. assert_equal(entry1, entry2)
  73. assert(entry2 != entry3)
  74. assert(entry3 != entry4)
  75. assert(entry4 != entry5)
  76. assert(entry5 != entry6)
  77. assert(entry6 != entry7)
  78. assert(entry7 != entry8)
  79. assert(entry7 != "hello")
  80. assert(entry7 != 12)
  81. assert(entry7 != ZipStreamableFile.new(entry7, "aPath"))
  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. zis.close
  342. end
  343. def test_openWithBlock
  344. ZipInputStream.open(TestZipFile::TEST_ZIP2.zip_name) {
  345. |zis|
  346. assert_stream_contents(zis, TestZipFile::TEST_ZIP2)
  347. }
  348. end
  349. def test_openWithoutBlock
  350. zis = ZipInputStream.open(TestZipFile::TEST_ZIP2.zip_name)
  351. assert_stream_contents(zis, TestZipFile::TEST_ZIP2)
  352. end
  353. def test_incompleteReads
  354. ZipInputStream.open(TestZipFile::TEST_ZIP2.zip_name) {
  355. |zis|
  356. entry = zis.get_next_entry
  357. assert_equal(TestZipFile::TEST_ZIP2.entry_names[0], entry.name)
  358. assert zis.gets.length > 0
  359. entry = zis.get_next_entry
  360. assert_equal(TestZipFile::TEST_ZIP2.entry_names[1], entry.name)
  361. assert_equal(0, entry.size)
  362. assert_equal(nil, zis.gets)
  363. entry = zis.get_next_entry
  364. assert_equal(TestZipFile::TEST_ZIP2.entry_names[2], entry.name)
  365. assert zis.gets.length > 0
  366. entry = zis.get_next_entry
  367. assert_equal(TestZipFile::TEST_ZIP2.entry_names[3], entry.name)
  368. assert zis.gets.length > 0
  369. }
  370. end
  371. def test_rewind
  372. ZipInputStream.open(TestZipFile::TEST_ZIP2.zip_name) {
  373. |zis|
  374. e = zis.get_next_entry
  375. assert_equal(TestZipFile::TEST_ZIP2.entry_names[0], e.name)
  376. # Do a little reading
  377. buf = ""
  378. buf << zis.read(100)
  379. buf << (zis.gets || "")
  380. buf << (zis.gets || "")
  381. zis.rewind
  382. buf2 = ""
  383. buf2 << zis.read(100)
  384. buf2 << (zis.gets || "")
  385. buf2 << (zis.gets || "")
  386. assert_equal(buf, buf2)
  387. zis.rewind
  388. assert_entry(e.name, zis, e.name)
  389. }
  390. end
  391. def test_mix_read_and_gets
  392. ZipInputStream.open(TestZipFile::TEST_ZIP2.zip_name) {
  393. |zis|
  394. e = zis.get_next_entry
  395. assert_equal("#!/usr/bin/env ruby", zis.gets.chomp)
  396. assert_equal("", zis.gets.chomp)
  397. assert_equal("$VERBOSE =", zis.read(10))
  398. }
  399. end
  400. end
  401. module CrcTest
  402. class TestOutputStream
  403. include IOExtras::AbstractOutputStream
  404. attr_accessor :buffer
  405. def initialize
  406. @buffer = ""
  407. end
  408. def << (data)
  409. @buffer << data
  410. self
  411. end
  412. end
  413. def run_crc_test(compressorClass)
  414. str = "Here's a nice little text to compute the crc for! Ho hum, it is nice nice nice nice indeed."
  415. fakeOut = TestOutputStream.new
  416. deflater = compressorClass.new(fakeOut)
  417. deflater << str
  418. assert_equal(0x919920fc, deflater.crc)
  419. end
  420. end
  421. class PassThruCompressorTest < Test::Unit::TestCase
  422. include CrcTest
  423. def test_size
  424. File.open("dummy.txt", "wb") {
  425. |file|
  426. compressor = PassThruCompressor.new(file)
  427. assert_equal(0, compressor.size)
  428. t1 = "hello world"
  429. t2 = ""
  430. t3 = "bingo"
  431. compressor << t1
  432. assert_equal(compressor.size, t1.size)
  433. compressor << t2
  434. assert_equal(compressor.size, t1.size + t2.size)
  435. compressor << t3
  436. assert_equal(compressor.size, t1.size + t2.size + t3.size)
  437. }
  438. end
  439. def test_crc
  440. run_crc_test(PassThruCompressor)
  441. end
  442. end
  443. class DeflaterTest < Test::Unit::TestCase
  444. include CrcTest
  445. def test_outputOperator
  446. txt = load_file("data/file2.txt")
  447. deflate(txt, "deflatertest.bin")
  448. inflatedTxt = inflate("deflatertest.bin")
  449. assert_equal(txt, inflatedTxt)
  450. end
  451. private
  452. def load_file(fileName)
  453. txt = nil
  454. File.open(fileName, "rb") { |f| txt = f.read }
  455. end
  456. def deflate(data, fileName)
  457. File.open(fileName, "wb") {
  458. |file|
  459. deflater = Deflater.new(file)
  460. deflater << data
  461. deflater.finish
  462. assert_equal(deflater.size, data.size)
  463. file << "trailing data for zlib with -MAX_WBITS"
  464. }
  465. end
  466. def inflate(fileName)
  467. txt = nil
  468. File.open(fileName, "rb") {
  469. |file|
  470. inflater = Inflater.new(file)
  471. txt = inflater.sysread
  472. }
  473. end
  474. def test_crc
  475. run_crc_test(Deflater)
  476. end
  477. end
  478. class ZipOutputStreamTest < Test::Unit::TestCase
  479. include AssertEntry
  480. TEST_ZIP = TestZipFile::TEST_ZIP2.clone
  481. TEST_ZIP.zip_name = "output.zip"
  482. def test_new
  483. zos = ZipOutputStream.new(TEST_ZIP.zip_name)
  484. zos.comment = TEST_ZIP.comment
  485. write_test_zip(zos)
  486. zos.close
  487. assert_test_zip_contents(TEST_ZIP)
  488. end
  489. def test_open
  490. ZipOutputStream.open(TEST_ZIP.zip_name) {
  491. |zos|
  492. zos.comment = TEST_ZIP.comment
  493. write_test_zip(zos)
  494. }
  495. assert_test_zip_contents(TEST_ZIP)
  496. end
  497. def test_writingToClosedStream
  498. assert_i_o_error_in_closed_stream { |zos| zos << "hello world" }
  499. assert_i_o_error_in_closed_stream { |zos| zos.puts "hello world" }
  500. assert_i_o_error_in_closed_stream { |zos| zos.write "hello world" }
  501. end
  502. def test_cannotOpenFile
  503. name = TestFiles::EMPTY_TEST_DIR
  504. begin
  505. zos = ZipOutputStream.open(name)
  506. rescue Exception
  507. assert($!.kind_of?(Errno::EISDIR) || # Linux
  508. $!.kind_of?(Errno::EEXIST) || # Windows/cygwin
  509. $!.kind_of?(Errno::EACCES), # Windows
  510. "Expected Errno::EISDIR (or on win/cygwin: Errno::EEXIST), but was: #{$!.class}")
  511. end
  512. end
  513. def assert_i_o_error_in_closed_stream
  514. assert_raise(IOError) {
  515. zos = ZipOutputStream.new("test_putOnClosedStream.zip")
  516. zos.close
  517. yield zos
  518. }
  519. end
  520. def write_test_zip(zos)
  521. TEST_ZIP.entry_names.each {
  522. |entryName|
  523. zos.put_next_entry(entryName)
  524. File.open(entryName, "rb") { |f| zos.write(f.read) }
  525. }
  526. end
  527. end
  528. module Enumerable
  529. def compare_enumerables(otherEnumerable)
  530. otherAsArray = otherEnumerable.to_a
  531. index=0
  532. each_with_index {
  533. |element, index|
  534. return false unless yield(element, otherAsArray[index])
  535. }
  536. return index+1 == otherAsArray.size
  537. end
  538. end
  539. class ZipCentralDirectoryEntryTest < Test::Unit::TestCase
  540. def test_read_from_stream
  541. File.open("data/testDirectory.bin", "rb") {
  542. |file|
  543. entry = ZipEntry.read_c_dir_entry(file)
  544. assert_equal("longAscii.txt", entry.name)
  545. assert_equal(ZipEntry::DEFLATED, entry.compression_method)
  546. assert_equal(106490, entry.size)
  547. assert_equal(3784, entry.compressed_size)
  548. assert_equal(0xfcd1799c, entry.crc)
  549. assert_equal("", entry.comment)
  550. entry = ZipEntry.read_c_dir_entry(file)
  551. assert_equal("empty.txt", entry.name)
  552. assert_equal(ZipEntry::STORED, entry.compression_method)
  553. assert_equal(0, entry.size)
  554. assert_equal(0, entry.compressed_size)
  555. assert_equal(0x0, entry.crc)
  556. assert_equal("", entry.comment)
  557. entry = ZipEntry.read_c_dir_entry(file)
  558. assert_equal("short.txt", entry.name)
  559. assert_equal(ZipEntry::STORED, entry.compression_method)
  560. assert_equal(6, entry.size)
  561. assert_equal(6, entry.compressed_size)
  562. assert_equal(0xbb76fe69, entry.crc)
  563. assert_equal("", entry.comment)
  564. entry = ZipEntry.read_c_dir_entry(file)
  565. assert_equal("longBinary.bin", entry.name)
  566. assert_equal(ZipEntry::DEFLATED, entry.compression_method)
  567. assert_equal(1000024, entry.size)
  568. assert_equal(70847, entry.compressed_size)
  569. assert_equal(0x10da7d59, entry.crc)
  570. assert_equal("", entry.comment)
  571. entry = ZipEntry.read_c_dir_entry(file)
  572. assert_equal(nil, entry)
  573. # Fields that are not check by this test:
  574. # version made by 2 bytes
  575. # version needed to extract 2 bytes
  576. # general purpose bit flag 2 bytes
  577. # last mod file time 2 bytes
  578. # last mod file date 2 bytes
  579. # compressed size 4 bytes
  580. # uncompressed size 4 bytes
  581. # disk number start 2 bytes
  582. # internal file attributes 2 bytes
  583. # external file attributes 4 bytes
  584. # relative offset of local header 4 bytes
  585. # file name (variable size)
  586. # extra field (variable size)
  587. # file comment (variable size)
  588. }
  589. end
  590. def test_ReadEntryFromTruncatedZipFile
  591. fragment=""
  592. File.open("data/testDirectory.bin") { |f| fragment = f.read(12) } # cdir entry header is at least 46 bytes
  593. fragment.extend(IOizeString)
  594. entry = ZipEntry.new
  595. entry.read_c_dir_entry(fragment)
  596. fail "ZipError expected"
  597. rescue ZipError
  598. end
  599. end
  600. class ZipEntrySetTest < Test::Unit::TestCase
  601. ZIP_ENTRIES = [
  602. ZipEntry.new("zipfile.zip", "name1", "comment1"),
  603. ZipEntry.new("zipfile.zip", "name2", "comment1"),
  604. ZipEntry.new("zipfile.zip", "name3", "comment1"),
  605. ZipEntry.new("zipfile.zip", "name4", "comment1"),
  606. ZipEntry.new("zipfile.zip", "name5", "comment1"),
  607. ZipEntry.new("zipfile.zip", "name6", "comment1")
  608. ]
  609. def setup
  610. @zipEntrySet = ZipEntrySet.new(ZIP_ENTRIES)
  611. end
  612. def test_include
  613. assert(@zipEntrySet.include?(ZIP_ENTRIES.first))
  614. assert(! @zipEntrySet.include?(ZipEntry.new("different.zip", "different", "aComment")))
  615. end
  616. def test_size
  617. assert_equal(ZIP_ENTRIES.size, @zipEntrySet.size)
  618. assert_equal(ZIP_ENTRIES.size, @zipEntrySet.length)
  619. @zipEntrySet << ZipEntry.new("a", "b", "c")
  620. assert_equal(ZIP_ENTRIES.size + 1, @zipEntrySet.length)
  621. end
  622. def test_add
  623. zes = ZipEntrySet.new
  624. entry1 = ZipEntry.new("zf.zip", "name1")
  625. entry2 = ZipEntry.new("zf.zip", "name2")
  626. zes << entry1
  627. assert(zes.include?(entry1))
  628. zes.push(entry2)
  629. assert(zes.include?(entry2))
  630. end
  631. def test_delete
  632. assert_equal(ZIP_ENTRIES.size, @zipEntrySet.size)
  633. entry = @zipEntrySet.delete(ZIP_ENTRIES.first)
  634. assert_equal(ZIP_ENTRIES.size - 1, @zipEntrySet.size)
  635. assert_equal(ZIP_ENTRIES.first, entry)
  636. entry = @zipEntrySet.delete(ZIP_ENTRIES.first)
  637. assert_equal(ZIP_ENTRIES.size - 1, @zipEntrySet.size)
  638. assert_nil(entry)
  639. end
  640. def test_each
  641. # Tested indirectly via each_with_index
  642. count = 0
  643. @zipEntrySet.each_with_index {
  644. |entry, index|
  645. assert(ZIP_ENTRIES.include?(entry))
  646. count = count.succ
  647. }
  648. assert_equal(ZIP_ENTRIES.size, count)
  649. end
  650. def test_entries
  651. assert_equal(ZIP_ENTRIES.sort, @zipEntrySet.entries.sort)
  652. end
  653. def test_compound
  654. newEntry = ZipEntry.new("zf.zip", "new entry", "new entry's comment")
  655. assert_equal(ZIP_ENTRIES.size, @zipEntrySet.size)
  656. @zipEntrySet << newEntry
  657. assert_equal(ZIP_ENTRIES.size + 1, @zipEntrySet.size)
  658. assert(@zipEntrySet.include?(newEntry))
  659. @zipEntrySet.delete(newEntry)
  660. assert_equal(ZIP_ENTRIES.size, @zipEntrySet.size)
  661. end
  662. def test_dup
  663. copy = @zipEntrySet.dup
  664. assert_equal(@zipEntrySet, copy)
  665. # demonstrate that this is a deep copy
  666. copy.entries[0].name = "a totally different name"
  667. assert(@zipEntrySet != copy)
  668. end
  669. def test_parent
  670. entries = [
  671. ZipEntry.new("zf.zip", "a"),
  672. ZipEntry.new("zf.zip", "a/"),
  673. ZipEntry.new("zf.zip", "a/b"),
  674. ZipEntry.new("zf.zip", "a/b/"),
  675. ZipEntry.new("zf.zip", "a/b/c"),
  676. ZipEntry.new("zf.zip", "a/b/c/")
  677. ]
  678. entrySet = ZipEntrySet.new(entries)
  679. assert_equal(nil, entrySet.parent(entries[0]))
  680. assert_equal(nil, entrySet.parent(entries[1]))
  681. assert_equal(entries[1], entrySet.parent(entries[2]))
  682. assert_equal(entries[1], entrySet.parent(entries[3]))
  683. assert_equal(entries[3], entrySet.parent(entries[4]))
  684. assert_equal(entries[3], entrySet.parent(entries[5]))
  685. end
  686. def test_glob
  687. res = @zipEntrySet.glob('name[2-4]')
  688. assert_equal(3, res.size)
  689. assert_equal(ZIP_ENTRIES[1,3], res)
  690. end
  691. def test_glob2
  692. entries = [
  693. ZipEntry.new("zf.zip", "a/"),
  694. ZipEntry.new("zf.zip", "a/b/b1"),
  695. ZipEntry.new("zf.zip", "a/b/c/"),
  696. ZipEntry.new("zf.zip", "a/b/c/c1")
  697. ]
  698. entrySet = ZipEntrySet.new(entries)
  699. assert_equal(entries[0,1], entrySet.glob("*"))
  700. # assert_equal(entries[FIXME], entrySet.glob("**"))
  701. # res = entrySet.glob('a*')
  702. # assert_equal(entries.size, res.size)
  703. # assert_equal(entrySet.map { |e| e.name }, res.map { |e| e.name })
  704. end
  705. end
  706. class ZipCentralDirectoryTest < Test::Unit::TestCase
  707. def test_read_from_stream
  708. File.open(TestZipFile::TEST_ZIP2.zip_name, "rb") {
  709. |zipFile|
  710. cdir = ZipCentralDirectory.read_from_stream(zipFile)
  711. assert_equal(TestZipFile::TEST_ZIP2.entry_names.size, cdir.size)
  712. assert(cdir.entries.sort.compare_enumerables(TestZipFile::TEST_ZIP2.entry_names.sort) {
  713. |cdirEntry, testEntryName|
  714. cdirEntry.name == testEntryName
  715. })
  716. assert_equal(TestZipFile::TEST_ZIP2.comment, cdir.comment)
  717. }
  718. end
  719. def test_readFromInvalidStream
  720. File.open("data/file2.txt", "rb") {
  721. |zipFile|
  722. cdir = ZipCentralDirectory.new
  723. cdir.read_from_stream(zipFile)
  724. }
  725. fail "ZipError expected!"
  726. rescue ZipError
  727. end
  728. def test_ReadFromTruncatedZipFile
  729. fragment=""
  730. File.open("data/testDirectory.bin") { |f| fragment = f.read }
  731. fragment.slice!(12) # removed part of first cdir entry. eocd structure still complete
  732. fragment.extend(IOizeString)
  733. entry = ZipCentralDirectory.new
  734. entry.read_from_stream(fragment)
  735. fail "ZipError expected"
  736. rescue ZipError
  737. end
  738. def test_write_to_stream
  739. entries = [ ZipEntry.new("file.zip", "flimse", "myComment", "somethingExtra"),
  740. ZipEntry.new("file.zip", "secondEntryName"),
  741. ZipEntry.new("file.zip", "lastEntry.txt", "Has a comment too") ]
  742. cdir = ZipCentralDirectory.new(entries, "my zip comment")
  743. File.open("cdirtest.bin", "wb") { |f| cdir.write_to_stream(f) }
  744. cdirReadback = ZipCentralDirectory.new
  745. File.open("cdirtest.bin", "rb") { |f| cdirReadback.read_from_stream(f) }
  746. assert_equal(cdir.entries.sort, cdirReadback.entries.sort)
  747. end
  748. def test_equality
  749. cdir1 = ZipCentralDirectory.new([ ZipEntry.new("file.zip", "flimse", nil,
  750. "somethingExtra"),
  751. ZipEntry.new("file.zip", "secondEntryName"),
  752. ZipEntry.new("file.zip", "lastEntry.txt") ],
  753. "my zip comment")
  754. cdir2 = ZipCentralDirectory.new([ ZipEntry.new("file.zip", "flimse", nil,
  755. "somethingExtra"),
  756. ZipEntry.new("file.zip", "secondEntryName"),
  757. ZipEntry.new("file.zip", "lastEntry.txt") ],
  758. "my zip comment")
  759. cdir3 = ZipCentralDirectory.new([ ZipEntry.new("file.zip", "flimse", nil,
  760. "somethingExtra"),
  761. ZipEntry.new("file.zip", "secondEntryName"),
  762. ZipEntry.new("file.zip", "lastEntry.txt") ],
  763. "comment?")
  764. cdir4 = ZipCentralDirectory.new([ ZipEntry.new("file.zip", "flimse", nil,
  765. "somethingExtra"),
  766. ZipEntry.new("file.zip", "lastEntry.txt") ],
  767. "comment?")
  768. assert_equal(cdir1, cdir1)
  769. assert_equal(cdir1, cdir2)
  770. assert(cdir1 != cdir3)
  771. assert(cdir2 != cdir3)
  772. assert(cdir2 != cdir3)
  773. assert(cdir3 != cdir4)
  774. assert(cdir3 != "hello")
  775. end
  776. end
  777. class BasicZipFileTest < Test::Unit::TestCase
  778. include AssertEntry
  779. def setup
  780. @zipFile = ZipFile.new(TestZipFile::TEST_ZIP2.zip_name)
  781. @testEntryNameIndex=0
  782. end
  783. def test_entries
  784. assert_equal(TestZipFile::TEST_ZIP2.entry_names.sort,
  785. @zipFile.entries.entries.sort.map {|e| e.name} )
  786. end
  787. def test_each
  788. count = 0
  789. visited = {}
  790. @zipFile.each {
  791. |entry|
  792. assert(TestZipFile::TEST_ZIP2.entry_names.include?(entry.name))
  793. assert(! visited.include?(entry.name))
  794. visited[entry.name] = nil
  795. count = count.succ
  796. }
  797. assert_equal(TestZipFile::TEST_ZIP2.entry_names.length, count)
  798. end
  799. def test_foreach
  800. count = 0
  801. visited = {}
  802. ZipFile.foreach(TestZipFile::TEST_ZIP2.zip_name) {
  803. |entry|
  804. assert(TestZipFile::TEST_ZIP2.entry_names.include?(entry.name))
  805. assert(! visited.include?(entry.name))
  806. visited[entry.name] = nil
  807. count = count.succ
  808. }
  809. assert_equal(TestZipFile::TEST_ZIP2.entry_names.length, count)
  810. end
  811. def test_get_input_stream
  812. count = 0
  813. visited = {}
  814. @zipFile.each {
  815. |entry|
  816. assert_entry(entry.name, @zipFile.get_input_stream(entry), entry.name)
  817. assert(! visited.include?(entry.name))
  818. visited[entry.name] = nil
  819. count = count.succ
  820. }
  821. assert_equal(TestZipFile::TEST_ZIP2.entry_names.length, count)
  822. end
  823. def test_get_input_streamBlock
  824. fileAndEntryName = @zipFile.entries.first.name
  825. @zipFile.get_input_stream(fileAndEntryName) {
  826. |zis|
  827. assert_entryContentsForStream(fileAndEntryName,
  828. zis,
  829. fileAndEntryName)
  830. }
  831. end
  832. end
  833. module CommonZipFileFixture
  834. include AssertEntry
  835. EMPTY_FILENAME = "emptyZipFile.zip"
  836. TEST_ZIP = TestZipFile::TEST_ZIP2.clone
  837. TEST_ZIP.zip_name = "4entry_copy.zip"
  838. def setup
  839. File.delete(EMPTY_FILENAME) if File.exists?(EMPTY_FILENAME)
  840. File.copy(TestZipFile::TEST_ZIP2.zip_name, TEST_ZIP.zip_name)
  841. end
  842. end
  843. class ZipFileTest < Test::Unit::TestCase
  844. include CommonZipFileFixture
  845. def test_createFromScratch
  846. comment = "a short comment"
  847. zf = ZipFile.new(EMPTY_FILENAME, ZipFile::CREATE)
  848. zf.get_output_stream("myFile") { |os| os.write "myFile contains just this" }
  849. zf.mkdir("dir1")
  850. zf.comment = comment
  851. zf.close
  852. zfRead = ZipFile.new(EMPTY_FILENAME)
  853. assert_equal(comment, zfRead.comment)
  854. assert_equal(2, zfRead.entries.length)
  855. end
  856. def test_get_output_stream
  857. entryCount = nil
  858. ZipFile.open(TEST_ZIP.zip_name) {
  859. |zf|
  860. entryCount = zf.size
  861. zf.get_output_stream('newEntry.txt') {
  862. |os|
  863. os.write "Putting stuff in newEntry.txt"
  864. }
  865. assert_equal(entryCount+1, zf.size)
  866. assert_equal("Putting stuff in newEntry.txt", zf.read("newEntry.txt"))
  867. zf.get_output_stream(zf.get_entry('data/generated/empty.txt')) {
  868. |os|
  869. os.write "Putting stuff in data/generated/empty.txt"
  870. }
  871. assert_equal(entryCount+1, zf.size)
  872. assert_equal("Putting stuff in data/generated/empty.txt", zf.read("data/generated/empty.txt"))
  873. zf.get_output_stream('entry.bin') {
  874. |os|
  875. os.write(File.open('data/generated/4entry.zip', 'rb').read)
  876. }
  877. }
  878. ZipFile.open(TEST_ZIP.zip_name) {
  879. |zf|
  880. assert_equal(entryCount+2, zf.size)
  881. assert_equal("Putting stuff in newEntry.txt", zf.read("newEntry.txt"))
  882. assert_equal("Putting stuff in data/generated/empty.txt", zf.read("data/generated/empty.txt"))
  883. assert_equal(File.open('data/generated/4entry.zip', 'rb').read, zf.read("entry.bin"))
  884. }
  885. end
  886. def test_add
  887. srcFile = "data/file2.txt"
  888. entryName = "newEntryName.rb"
  889. assert(File.exists?(srcFile))
  890. zf = ZipFile.new(EMPTY_FILENAME, ZipFile::CREATE)
  891. zf.add(entryName, srcFile)
  892. zf.close
  893. zfRead = ZipFile.new(EMPTY_FILENAME)
  894. assert_equal("", zfRead.comment)
  895. assert_equal(1, zfRead.entries.length)
  896. assert_equal(entryName, zfRead.entries.first.name)
  897. AssertEntry.assert_contents(srcFile,
  898. zfRead.get_input_stream(entryName) { |zis| zis.read })
  899. end
  900. def test_addExistingEntryName
  901. assert_raise(ZipEntryExistsError) {
  902. ZipFile.open(TEST_ZIP.zip_name) {
  903. |zf|
  904. zf.add(zf.entries.first.name, "data/file2.txt")
  905. }
  906. }
  907. end
  908. def test_addExistingEntryNameReplace
  909. gotCalled = false
  910. replacedEntry = nil
  911. ZipFile.open(TEST_ZIP.zip_name) {
  912. |zf|
  913. replacedEntry = zf.entries.first.name
  914. zf.add(replacedEntry, "data/file2.txt") { gotCalled = true; true }
  915. }
  916. assert(gotCalled)
  917. ZipFile.open(TEST_ZIP.zip_name) {
  918. |zf|
  919. assert_contains(zf, replacedEntry, "data/file2.txt")
  920. }
  921. end
  922. def test_addDirectory
  923. ZipFile.open(TEST_ZIP.zip_name) {
  924. |zf|
  925. zf.add(TestFiles::EMPTY_TEST_DIR, TestFiles::EMPTY_TEST_DIR)
  926. }
  927. ZipFile.open(TEST_ZIP.zip_name) {
  928. |zf|
  929. dirEntry = zf.entries.detect { |e| e.name == TestFiles::EMPTY_TEST_DIR+"/" }
  930. assert(dirEntry.is_directory)
  931. }
  932. end
  933. def test_remove
  934. entryToRemove, *remainingEntries = TEST_ZIP.entry_names
  935. File.copy(TestZipFile::TEST_ZIP2.zip_name, TEST_ZIP.zip_name)
  936. zf = ZipFile.new(TEST_ZIP.zip_name)
  937. assert(zf.entries.map { |e| e.name }.include?(entryToRemove))
  938. zf.remove(entryToRemove)
  939. assert(! zf.entries.map { |e| e.name }.include?(entryToRemove))
  940. assert_equal(zf.entries.map {|x| x.name }.sort, remainingEntries.sort)
  941. zf.close
  942. zfRead = ZipFile.new(TEST_ZIP.zip_name)
  943. assert(! zfRead.entries.map { |e| e.name }.include?(entryToRemove))
  944. assert_equal(zfRead.entries.map {|x| x.name }.sort, remainingEntries.sort)
  945. zfRead.close
  946. end
  947. def test_rename
  948. entryToRename, *remainingEntries = TEST_ZIP.entry_names
  949. zf = ZipFile.new(TEST_ZIP.zip_name)
  950. assert(zf.entries.map { |e| e.name }.include?(entryToRename))
  951. newName = "changed name"
  952. assert(! zf.entries.map { |e| e.name }.include?(newName))
  953. zf.rename(entryToRename, newName)
  954. assert(zf.entries.map { |e| e.name }.include?(newName))
  955. zf.close
  956. zfRead = ZipFile.new(TEST_ZIP.zip_name)
  957. assert(zfRead.entries.map { |e| e.name }.include?(newName))
  958. zfRead.close
  959. end
  960. def test_renameToExistingEntry
  961. oldEntries = nil
  962. ZipFile.open(TEST_ZIP.zip_name) { |zf| oldEntries = zf.entries }
  963. assert_raise(ZipEntryExistsError) {
  964. ZipFile.open(TEST_ZIP.zip_name) {
  965. |zf|
  966. zf.rename(zf.entries[0], zf.entries[1].name)
  967. }
  968. }
  969. ZipFile.open(TEST_ZIP.zip_name) {
  970. |zf|
  971. assert_equal(oldEntries.sort.map{ |e| e.name }, zf.entries.sort.map{ |e| e.name })
  972. }
  973. end
  974. def test_renameToExistingEntryOverwrite
  975. oldEntries = nil
  976. ZipFile.open(TEST_ZIP.zip_name) { |zf| oldEntries = zf.entries }
  977. gotCalled = false
  978. renamedEntryName = nil
  979. ZipFile.open(TEST_ZIP.zip_name) {
  980. |zf|
  981. renamedEntryName = zf.entries[0].name
  982. zf.rename(zf.entries[0], zf.entries[1].name) { gotCalled = true; true }
  983. }
  984. assert(gotCalled)
  985. oldEntries.delete_if { |e| e.name == renamedEntryName }
  986. ZipFile.open(TEST_ZIP.zip_name) {
  987. |zf|
  988. assert_equal(oldEntries.sort.map{ |e| e.name },
  989. zf.entries.sort.map{ |e| e.name })
  990. }
  991. end
  992. def test_renameNonEntry
  993. nonEntry = "bogusEntry"
  994. target_entry = "target_entryName"
  995. zf = ZipFile.new(TEST_ZIP.zip_name)
  996. assert(! zf.entries.include?(nonEntry))
  997. assert_raise(Errno::ENOENT) {
  998. zf.rename(nonEntry, target_entry)
  999. }
  1000. zf.commit
  1001. assert(! zf.entries.include?(target_entry))
  1002. ensure
  1003. zf.close
  1004. end
  1005. def test_renameEntryToExistingEntry
  1006. entry1, entry2, *remaining = TEST_ZIP.entry_names
  1007. zf = ZipFile.new(TEST_ZIP.zip_name)
  1008. assert_raise(ZipEntryExistsError) {
  1009. zf.rename(entry1, entry2)
  1010. }
  1011. ensure
  1012. zf.close
  1013. end
  1014. def test_replace
  1015. entryToReplace = TEST_ZIP.entry_names[2]
  1016. newEntrySrcFilename = "data/file2.txt"
  1017. zf = ZipFile.new(TEST_ZIP.zip_name)
  1018. zf.replace(entryToReplace, newEntrySrcFilename)
  1019. zf.close
  1020. zfRead = ZipFile.new(TEST_ZIP.zip_name)
  1021. AssertEntry::assert_contents(newEntrySrcFilename,
  1022. zfRead.get_input_stream(entryToReplace) { |is| is.read })
  1023. AssertEntry::assert_contents(TEST_ZIP.entry_names[0],
  1024. zfRead.get_input_stream(TEST_ZIP.entry_names[0]) { |is| is.read })
  1025. AssertEntry::assert_contents(TEST_ZIP.entry_names[1],
  1026. zfRead.get_input_stream(TEST_ZIP.entry_names[1]) { |is| is.read })
  1027. AssertEntry::assert_contents(TEST_ZIP.entry_names[3],
  1028. zfRead.get_input_stream(TEST_ZIP.entry_names[3]) { |is| is.read })
  1029. zfRead.close
  1030. end
  1031. def test_replaceNonEntry
  1032. entryToReplace = "nonExistingEntryname"
  1033. ZipFile.open(TEST_ZIP.zip_name) {
  1034. |zf|
  1035. assert_raise(Errno::ENOENT) {
  1036. zf.replace(entryToReplace, "data/file2.txt")
  1037. }
  1038. }
  1039. end
  1040. def test_commit
  1041. newName = "renamedFirst"
  1042. zf = ZipFile.new(TEST_ZIP.zip_name)
  1043. oldName = zf.entries.first
  1044. zf.rename(oldName, newName)
  1045. zf.commit
  1046. zfRead = ZipFile.new(TEST_ZIP.zip_name)
  1047. assert(zfRead.entries.detect { |e| e.name == newName } != nil)
  1048. assert(zfRead.entries.detect { |e| e.name == oldName } == nil)
  1049. zfRead.close
  1050. zf.close
  1051. end
  1052. # This test tests that after commit, you
  1053. # can delete the file you used to add the entry to the zip file
  1054. # with
  1055. def test_commitUseZipEntry
  1056. File.copy(TestFiles::RANDOM_ASCII_FILE1, "okToDelete.txt")
  1057. zf = ZipFile.open(TEST_ZIP.zip_name)
  1058. zf.add("okToDelete.txt", "okToDelete.txt")
  1059. assert_contains(zf, "okToDelete.txt")
  1060. zf.commit
  1061. File.move("okToDelete.txt", "okToDeleteMoved.txt")
  1062. assert_contains(zf, "okToDelete.txt", "okToDeleteMoved.txt")
  1063. end
  1064. # def test_close
  1065. # zf = ZipFile.new(TEST_ZIP.zip_name)
  1066. # zf.close
  1067. # assert_raise(IOError) {
  1068. # zf.extract(TEST_ZIP.entry_names.first, "hullubullu")
  1069. # }
  1070. # end
  1071. def test_compound1
  1072. renamedName = "renamedName"
  1073. originalEntries = []
  1074. begin
  1075. zf = ZipFile.new(TEST_ZIP.zip_name)
  1076. originalEntries = zf.entries.dup
  1077. assert_not_contains(zf, TestFiles::RANDOM_ASCII_FILE1)
  1078. zf.add(TestFiles::RANDOM_ASCII_FILE1,
  1079. TestFiles::RANDOM_ASCII_FILE1)
  1080. assert_contains(zf, TestFiles::RANDOM_ASCII_FILE1)
  1081. zf.rename(zf.entries[0], renamedName)
  1082. assert_contains(zf, renamedName)
  1083. TestFiles::BINARY_TEST_FILES.each {
  1084. |filename|
  1085. zf.add(filename, filename)
  1086. assert_contains(zf, filename)
  1087. }
  1088. assert_contains(zf, originalEntries.last.to_s)
  1089. zf.remove(originalEntries.last.to_s)
  1090. assert_not_contains(zf, originalEntries.last.to_s)
  1091. ensure
  1092. zf.close
  1093. end
  1094. begin
  1095. zfRead = ZipFile.new(TEST_ZIP.zip_name)
  1096. assert_contains(zfRead, TestFiles::RANDOM_ASCII_FILE1)
  1097. assert_contains(zfRead, renamedName)
  1098. TestFiles::BINARY_TEST_FILES.each {
  1099. |filename|
  1100. assert_contains(zfRead, filename)
  1101. }
  1102. assert_not_contains(zfRead, originalEntries.last.to_s)
  1103. ensure
  1104. zfRead.close
  1105. end
  1106. end
  1107. def test_compound2
  1108. begin
  1109. zf = ZipFile.new(TEST_ZIP.zip_name)
  1110. originalEntries = zf.entries.dup
  1111. originalEntries.each {
  1112. |entry|
  1113. zf.remove(entry)
  1114. assert_not_contains(zf, entry)
  1115. }
  1116. assert(zf.entries.empty?)
  1117. TestFiles::ASCII_TEST_FILES.each {
  1118. |filename|
  1119. zf.add(filename, filename)
  1120. assert_contains(zf, filename)
  1121. }
  1122. assert_equal(zf.entries.sort.map { |e| e.name }, TestFiles::ASCII_TEST_FILES)
  1123. zf.rename(TestFiles::ASCII_TEST_FILES[0], "newName")
  1124. assert_not_contains(zf, TestFiles::ASCII_TEST_FILES[0])
  1125. assert_contains(zf, "newName")
  1126. ensure
  1127. zf.close
  1128. end
  1129. begin
  1130. zfRead = ZipFile.new(TEST_ZIP.zip_name)
  1131. asciiTestFiles = TestFiles::ASCII_TEST_FILES.dup
  1132. asciiTestFiles.shift
  1133. asciiTestFiles.each {
  1134. |filename|
  1135. assert_contains(zf, filename)
  1136. }
  1137. assert_contains(zf, "newName")
  1138. ensure
  1139. zfRead.close
  1140. end
  1141. end
  1142. private
  1143. def assert_contains(zf, entryName, filename = entryName)
  1144. assert(zf.entries.detect { |e| e.name == entryName} != nil, "entry #{entryName} not in #{zf.entries.join(', ')} in zip file #{zf}")
  1145. assert_entryContents(zf, entryName, filename) if File.exists?(filename)
  1146. end
  1147. def assert_not_contains(zf, entryName)
  1148. assert(zf.entries.detect { |e| e.name == entryName} == nil, "entry #{entryName} in #{zf.entries.join(', ')} in zip file #{zf}")
  1149. end
  1150. end
  1151. class ZipFileExtractTest < Test::Unit::TestCase
  1152. include CommonZipFileFixture
  1153. EXTRACTED_FILENAME = "extEntry"
  1154. ENTRY_TO_EXTRACT, *REMAINING_ENTRIES = TEST_ZIP.entry_names.reverse
  1155. def setup
  1156. super
  1157. File.delete(EXTRACTED_FILENAME) if File.exists?(EXTRACTED_FILENAME)
  1158. end
  1159. def test_extract
  1160. ZipFile.open(TEST_ZIP.zip_name) {
  1161. |zf|
  1162. zf.extract(ENTRY_TO_EXTRACT, EXTRACTED_FILENAME)
  1163. assert(File.exists?(EXTRACTED_FILENAME))
  1164. AssertEntry::assert_contents(EXTRACTED_FILENAME,
  1165. zf.get_input_stream(ENTRY_TO_EXTRACT) { |is| is.read })
  1166. }
  1167. end
  1168. def test_extractExists
  1169. writtenText = "written text"
  1170. File.open(EXTRACTED_FILENAME, "w") { |f| f.write(writtenText) }
  1171. assert_raise(ZipDestinationFileExistsError) {
  1172. ZipFile.open(TEST_ZIP.zip_name) {
  1173. |zf|
  1174. zf.extract(zf.entries.first, EXTRACTED_FILENAME)
  1175. }
  1176. }
  1177. File.open(EXTRACTED_FILENAME, "r") {
  1178. |f|
  1179. assert_equal(writtenText, f.read)
  1180. }
  1181. end
  1182. def test_extractExistsOverwrite
  1183. writtenText = "written text"
  1184. File.open(EXTRACTED_FILENAME, "w") { |f| f.write(writtenText) }
  1185. gotCalledCorrectly = false
  1186. ZipFile.open(TEST_ZIP.zip_name) {
  1187. |zf|
  1188. zf.extract(zf.entries.first, EXTRACTED_FILENAME) {
  1189. |entry, extractLoc|
  1190. gotCalledCorrectly = zf.entries.first == entry &&
  1191. extractLoc == EXTRACTED_FILENAME
  1192. true
  1193. }
  1194. }
  1195. assert(gotCalledCorrectly)
  1196. File.open(EXTRACTED_FILENAME, "r") {
  1197. |f|
  1198. assert(writtenText != f.read)
  1199. }
  1200. end
  1201. def test_extractNonEntry
  1202. zf = ZipFile.new(TEST_ZIP.zip_name)
  1203. assert_raise(Errno::ENOENT) { zf.extract("nonExistingEntry", "nonExistingEntry") }
  1204. ensure
  1205. zf.close if zf
  1206. end
  1207. def test_extractNonEntry2
  1208. outFile = "outfile"
  1209. assert_raise(Errno::ENOENT) {
  1210. zf = ZipFile.new(TEST_ZIP.zip_name)
  1211. nonEntry = "hotdog-diddelidoo"
  1212. assert(! zf.entries.include?(nonEntry))
  1213. zf.extract(nonEntry, outFile)
  1214. zf.close
  1215. }
  1216. assert(! File.exists?(outFile))
  1217. end
  1218. end
  1219. class ZipFileExtractDirectoryTest < Test::Unit::TestCase
  1220. include CommonZipFileFixture
  1221. TEST_OUT_NAME = "emptyOutDir"
  1222. def open_zip(&aProc)
  1223. assert(aProc != nil)
  1224. ZipFile.open(TestZipFile::TEST_ZIP4.zip_name, &aProc)
  1225. end
  1226. def extract_test_dir(&aProc)
  1227. open_zip {
  1228. |zf|
  1229. zf.extract(TestFiles::EMPTY_TEST_DIR, TEST_OUT_NAME, &aProc)
  1230. }
  1231. end
  1232. def setup
  1233. super
  1234. Dir.rmdir(TEST_OUT_NAME) if File.directory? TEST_OUT_NAME
  1235. File.delete(TEST_OUT_NAME) if File.exists? TEST_OUT_NAME
  1236. end
  1237. def test_extractDirectory
  1238. extract_test_dir
  1239. assert(File.directory?(TEST_OUT_NAME))
  1240. end
  1241. def test_extractDirectoryExistsAsDir
  1242. Dir.mkdir TEST_OUT_NAME
  1243. extract_test_dir
  1244. assert(File.directory?(TEST_OUT_NAME))
  1245. end
  1246. def test_extractDirectoryExistsAsFile
  1247. File.open(TEST_OUT_NAME, "w") { |f| f.puts "something" }
  1248. assert_raise(ZipDestinationFileExistsError) { extract_test_dir }
  1249. end
  1250. def test_extractDirectoryExistsAsFileOverwrite
  1251. File.open(TEST_OUT_NAME, "w") { |f| f.puts "something" }
  1252. gotCalled = false
  1253. extract_test_dir {
  1254. |entry, destPath|
  1255. gotCalled = true
  1256. assert_equal(TEST_OUT_NAME, destPath)
  1257. assert(entry.is_directory)
  1258. true
  1259. }
  1260. assert(gotCalled)
  1261. assert(File.directory?(TEST_OUT_NAME))
  1262. end
  1263. end
  1264. class ZipStreamableFileTest < Test::Unit::TestCase
  1265. def test_equality
  1266. zipEntry1 = ZipEntry.new("zf.zip", "entryname1", "comment")
  1267. zipEntry2 = ZipEntry.new("zf.zip", "entryname2", "comment")
  1268. zipStreamableFile1 = ZipStreamableFile.new(zipEntry1, "path")
  1269. zipStreamableFile2 = ZipStreamableFile.new(zipEntry1, "path")
  1270. zipStreamableFile3 = ZipStreamableFile.new(zipEntry1, "anotherPath")
  1271. zipStreamableFile4 = ZipStreamableFile.new(zipEntry2, "path")
  1272. assert_equal(zipStreamableFile1, zipStreamableFile1)
  1273. assert_equal(zipStreamableFile1, zipStreamableFile2)
  1274. assert(zipStreamableFile1 != zipStreamableFile3)
  1275. assert(zipStreamableFile1 != zipStreamableFile4)
  1276. assert(zipStreamableFile1 != zipEntry1)
  1277. assert(zipStreamableFile1 != "hej")
  1278. end
  1279. end
  1280. class ZipExtraFieldTest < Test::Unit::TestCase
  1281. def test_new
  1282. extra_pure = ZipExtraField.new("")
  1283. extra_withstr = ZipExtraField.new("foo")
  1284. assert_instance_of(ZipExtraField, extra_pure)
  1285. assert_instance_of(ZipExtraField, extra_withstr)
  1286. end
  1287. def test_unknownfield
  1288. extra = ZipExtraField.new("foo")
  1289. assert_equal(extra["Unknown"], "foo")
  1290. extra.merge("a")
  1291. assert_equal(extra["Unknown"], "fooa")
  1292. extra.merge("barbaz")
  1293. assert_equal(extra.to_s, "fooabarbaz")
  1294. end
  1295. def test_merge
  1296. str = "UT\x5\0\x3\250$\r@Ux\0\0"
  1297. extra1 = ZipExtraField.new("")
  1298. extra2 = ZipExtraField.new(str)
  1299. assert(! extra1.member?("UniversalTime"))
  1300. assert(extra2.member?("UniversalTime"))
  1301. extra1.merge(str)
  1302. assert_equal(extra1["UniversalTime"].mtime, extra2["UniversalTime"].mtime)
  1303. end
  1304. def test_length
  1305. str = "UT\x5\0\x3\250$\r@Ux\0\0Te\0\0testit"
  1306. extra = ZipExtraField.new(str)
  1307. assert_equal(extra.local_length, extra.to_local_bin.length)
  1308. assert_equal(extra.c_dir_length, extra.to_c_dir_bin.length)
  1309. extra.merge("foo")
  1310. assert_equal(extra.local_length, extra.to_local_bin.length)
  1311. assert_equal(extra.c_dir_length, extra.to_c_dir_bin.length)
  1312. end
  1313. def test_to_s
  1314. str = "UT\x5\0\x3\250$\r@Ux\0\0Te\0\0testit"
  1315. extra = ZipExtraField.new(str)
  1316. assert_instance_of(String, extra.to_s)
  1317. s = extra.to_s
  1318. extra.merge("foo")
  1319. assert_equal(s.length + 3, extra.to_s.length)
  1320. end
  1321. def test_equality
  1322. str = "UT\x5\0\x3\250$\r@"
  1323. extra1 = ZipExtraField.new(str)
  1324. extra2 = ZipExtraField.new(str)
  1325. extra3 = ZipExtraField.new(str)
  1326. assert_equal(extra1, extra2)
  1327. extra2["UniversalTime"].mtime = Time.now
  1328. assert(extra1 != extra2)
  1329. extra3.create("IUnix")
  1330. assert(extra1 != extra3)
  1331. extra1.create("IUnix")
  1332. assert_equal(extra1, extra3)
  1333. end
  1334. end
  1335. # Copyright (C) 2002-2005 Thomas Sondergaard
  1336. # rubyzip is free software; you can redistribute it and/or
  1337. # modify it under the terms of the ruby license.