QuietUnrar/Carthage/Checkouts/UnzipKit/Tests/WriteDataTests.swift

472 lines
22 KiB
Swift
Raw Normal View History

//
// WriteDataTests.swift
// UnzipKit
//
// Created by Dov Frankel on 6/16/15.
// Copyright (c) 2015 Abbey Code. All rights reserved.
//
#if os(iOS)
import UIKit
#else
import Cocoa
#endif
import XCTest
import UnzipKit
class WriteDataTests: UZKArchiveTestCase {
func testWriteData() {
let testFilePaths = [String](nonZipTestFilePaths as! Set<String>).sorted(by: <)
let testDates = [
UZKArchiveTestCase.dateFormatter().date(from: "12/20/2014 9:35 AM"),
UZKArchiveTestCase.dateFormatter().date(from: "12/21/2014 10:00 AM"),
UZKArchiveTestCase.dateFormatter().date(from: "12/22/2014 11:54 PM")]
var testFileData = [Data]()
let testArchiveURL = tempDirectory.appendingPathComponent("WriteDataTest.zip")
let archive = try! UZKArchive(url: testArchiveURL)
for (index, testFilePath) in testFilePaths.enumerated() {
let fileData = try? Data(contentsOf: testFileURLs[testFilePath] as! URL)
testFileData.append(fileData!)
do {
try archive.write(fileData!, filePath: testFilePath, fileDate: testDates[index],
compressionMethod: .default, password: nil)
} catch let error as NSError {
XCTFail("Error writing to file \(testFilePath): \(error)")
}
}
var index = 0
try! archive.performOnData(inArchive: { (fileInfo, fileData, stop) -> Void in
let expectedData = testFileData[index]
let expectedCRC = crc32(0, (expectedData as NSData).bytes.bindMemory(to: Bytef.self, capacity: expectedData.count), uInt(expectedData.count))
XCTAssertEqual(fileInfo.filename, testFilePaths[index], "Incorrect filename in archive")
XCTAssertEqual(fileInfo.timestamp, testDates[index]!, "Incorrect timestamp in archive")
XCTAssertEqual(fileInfo.crc, expectedCRC, "CRC of extracted data doesn't match what was written")
XCTAssertEqual(fileData, expectedData, "Data extracted doesn't match what was written")
index += 1;
})
XCTAssert(index > 0, "No data iterated through")
}
func testWriteData_Unicode() {
let testFilePaths = [String](nonZipUnicodeFilePaths as! Set<String>).sorted(by: <)
let testDates = [
UZKArchiveTestCase.dateFormatter().date(from: "12/20/2014 9:35 AM"),
UZKArchiveTestCase.dateFormatter().date(from: "12/21/2014 10:00 AM"),
UZKArchiveTestCase.dateFormatter().date(from: "12/22/2014 11:54 PM")]
var testFileData = [Data]()
let testArchiveURL = tempDirectory.appendingPathComponent("UnicodeWriteDataTest.zip")
let archive = try! UZKArchive(url: testArchiveURL)
for (index, testFilePath) in testFilePaths.enumerated() {
let fileData = try? Data(contentsOf: unicodeFileURLs[testFilePath] as! URL)
testFileData.append(fileData!)
do {
try archive.write(fileData!, filePath: testFilePath, fileDate: testDates[index],
compressionMethod: .default, password: nil)
} catch let error as NSError {
XCTFail("Error writing to file \(testFilePath): \(error)")
}
}
var index = 0
try! archive.performOnData(inArchive: { (fileInfo, fileData, stop) -> Void in
let expectedData = testFileData[index]
let expectedCRC = crc32(0, (expectedData as NSData).bytes.bindMemory(to: Bytef.self, capacity: expectedData.count), uInt(expectedData.count))
XCTAssertEqual(fileInfo.filename, testFilePaths[index], "Incorrect filename in archive")
XCTAssertEqual(fileInfo.timestamp, testDates[index]!, "Incorrect timestamp in archive")
XCTAssertEqual(fileInfo.crc, expectedCRC, "CRC of extracted data doesn't match what was written")
XCTAssertEqual(fileData, expectedData, "Data extracted doesn't match what was written")
index += 1;
})
XCTAssert(index > 0, "No data iterated through")
}
func testWriteData_Overwrite() {
let testFilePaths = [String](nonZipTestFilePaths as! Set<String>).sorted(by: <)
let testDates = [
UZKArchiveTestCase.dateFormatter().date(from: "12/20/2014 9:35 AM"),
UZKArchiveTestCase.dateFormatter().date(from: "12/21/2014 10:00 AM"),
UZKArchiveTestCase.dateFormatter().date(from: "12/22/2014 11:54 PM")]
var testFileData = [Data]()
let testArchiveURL = tempDirectory.appendingPathComponent("RewriteDataTest.zip")
let archive = try! UZKArchive(url: testArchiveURL)
for (index, testFilePath) in testFilePaths.enumerated() {
let fileData = try? Data(contentsOf: testFileURLs[testFilePath] as! URL)
testFileData.append(fileData!)
do {
try archive.write(fileData!, filePath: testFilePath, fileDate: testDates[index],
compressionMethod: .default, password: nil)
} catch let error as NSError {
XCTFail("Error writing to file \(testFilePath): \(error)")
}
}
var index = 0
try! archive.performOnData(inArchive: { (fileInfo, fileData, stop) -> Void in
let expectedData = testFileData[index]
let expectedCRC = crc32(0, (expectedData as NSData).bytes.bindMemory(to: Bytef.self, capacity: expectedData.count), uInt(expectedData.count))
XCTAssertEqual(fileInfo.filename, testFilePaths[index], "Incorrect filename in archive")
XCTAssertEqual(fileInfo.timestamp, testDates[index]!, "Incorrect timestamp in archive")
XCTAssertEqual(fileInfo.crc, expectedCRC, "CRC of extracted data doesn't match what was written")
XCTAssertEqual(fileData, expectedData, "Data extracted doesn't match what was written")
index += 1;
})
XCTAssert(index > 0, "No data iterated through")
// Now write the files' contents to the zip in reverse
NSLog("Testing a second write, by reversing the contents and timestamps of the files from the first run")
for i in 0..<testFilePaths.count {
let x = testFilePaths.count - 1 - i
do {
try archive.write(testFileData[x], filePath: testFilePaths[i],
fileDate: testDates[x], compressionMethod: .default, password: nil)
} catch let error as NSError {
XCTFail("Error writing to file \(testFilePaths[x]) with data of " +
"file \(testFilePaths[i]): \(error)")
}
}
var forwardIndex = 0
try! archive.performOnData(inArchive: { (fileInfo, fileData, stop) -> Void in
XCTAssertEqual(fileInfo.filename, testFilePaths[forwardIndex], "Incorrect filename in archive");
let reverseIndex = testFilePaths.count - 1 - forwardIndex
let expectedData = testFileData[reverseIndex]
let expectedCRC = crc32(0, (expectedData as NSData).bytes.bindMemory(to: Bytef.self, capacity: expectedData.count), uInt(expectedData.count))
XCTAssertEqual(fileInfo.timestamp, testDates[reverseIndex]!, "Incorrect timestamp in archive")
XCTAssertEqual(fileInfo.crc, expectedCRC, "CRC of extracted data doesn't match what was written")
XCTAssertEqual(fileData, expectedData, "Data extracted doesn't match what was written")
forwardIndex += 1;
})
XCTAssert(index > 0, "No data iterated through")
}
func testWriteData_Overwrite_Unicode() {
let testFilePaths = [String](nonZipUnicodeFilePaths as! Set<String>).sorted(by: <)
let testDates = [
UZKArchiveTestCase.dateFormatter().date(from: "12/20/2014 9:35 AM"),
UZKArchiveTestCase.dateFormatter().date(from: "12/21/2014 10:00 AM"),
UZKArchiveTestCase.dateFormatter().date(from: "12/22/2014 11:54 PM")]
var testFileData = [Data]()
let testArchiveURL = tempDirectory.appendingPathComponent("RewriteDataTest.zip")
let archive = try! UZKArchive(url: testArchiveURL)
for (index, testFilePath) in testFilePaths.enumerated() {
let fileData = try? Data(contentsOf: unicodeFileURLs[testFilePath] as! URL)
testFileData.append(fileData!)
do {
try archive.write(fileData!, filePath: testFilePath, fileDate: testDates[index],
compressionMethod: .default, password: nil)
} catch let error as NSError {
XCTFail("Error writing to file \(testFilePath): \(error)")
}
}
var index = 0
try! archive.performOnData(inArchive: { (fileInfo, fileData, stop) -> Void in
let expectedData = testFileData[index]
let expectedCRC = crc32(0, (expectedData as NSData).bytes.bindMemory(to: Bytef.self, capacity: expectedData.count), uInt(expectedData.count))
XCTAssertEqual(fileInfo.filename, testFilePaths[index], "Incorrect filename in archive")
XCTAssertEqual(fileInfo.timestamp, testDates[index]!, "Incorrect timestamp in archive")
XCTAssertEqual(fileInfo.crc, expectedCRC, "CRC of extracted data doesn't match what was written")
XCTAssertEqual(fileData, expectedData, "Data extracted doesn't match what was written")
index += 1;
})
XCTAssert(index > 0, "No data iterated through")
// Now write the files' contents to the zip in reverse
NSLog("Testing a second write, by reversing the contents and timestamps of the files from the first run")
for i in 0..<testFilePaths.count {
let x = testFilePaths.count - 1 - i
do {
try archive.write(testFileData[x], filePath: testFilePaths[i],
fileDate: testDates[x], compressionMethod: .default, password: nil)
} catch let error as NSError {
XCTFail("Error writing to file \(testFilePaths[x]) with data of " +
"file \(testFilePaths[i]): \(error)")
}
}
var forwardIndex = 0
try! archive.performOnData(inArchive: { (fileInfo, fileData, stop) -> Void in
XCTAssertEqual(fileInfo.filename, testFilePaths[forwardIndex], "Incorrect filename in archive");
let reverseIndex = testFilePaths.count - 1 - forwardIndex
let expectedData = testFileData[reverseIndex]
let expectedCRC = crc32(0, (expectedData as NSData).bytes.bindMemory(to: Bytef.self, capacity: expectedData.count), uInt(expectedData.count))
XCTAssertEqual(fileInfo.timestamp, testDates[reverseIndex]!, "Incorrect timestamp in archive")
XCTAssertEqual(fileInfo.crc, expectedCRC, "CRC of extracted data doesn't match what was written")
XCTAssertEqual(fileData, expectedData, "Data extracted doesn't match what was written")
forwardIndex += 1;
})
XCTAssert(index > 0, "No data iterated through")
}
func testWriteData_NoOverwrite() {
let testFilePaths = [String](nonZipTestFilePaths as! Set<String>).sorted(by: <)
let testDates = [
UZKArchiveTestCase.dateFormatter().date(from: "12/20/2014 9:35 AM"),
UZKArchiveTestCase.dateFormatter().date(from: "12/21/2014 10:00 AM"),
UZKArchiveTestCase.dateFormatter().date(from: "12/22/2014 11:54 PM")]
var testFileData = [Data]()
let testArchiveURL = tempDirectory.appendingPathComponent("RewriteDataTest.zip")
let archive = try! UZKArchive(url: testArchiveURL)
for (index, testFilePath) in testFilePaths.enumerated() {
let fileData = try? Data(contentsOf: testFileURLs[testFilePath] as! URL)
testFileData.append(fileData!)
do {
try archive.write(fileData!, filePath: testFilePath, fileDate: testDates[index],
compressionMethod: .default, password: nil, overwrite: false)
} catch let error as NSError {
XCTFail("Error writing to file \(testFilePath): \(error)")
}
}
var index = 0
try! archive.performOnData(inArchive: { (fileInfo, fileData, stop) -> Void in
let expectedData = testFileData[index]
let expectedCRC = crc32(0, (expectedData as NSData).bytes.bindMemory(to: Bytef.self, capacity: expectedData.count), uInt(expectedData.count))
XCTAssertEqual(fileInfo.filename, testFilePaths[index], "Incorrect filename in archive")
XCTAssertEqual(fileInfo.timestamp, testDates[index]!, "Incorrect timestamp in archive")
XCTAssertEqual(fileInfo.crc, expectedCRC, "CRC of extracted data doesn't match what was written")
XCTAssertEqual(fileData, expectedData, "Data extracted doesn't match what was written")
index += 1;
})
XCTAssert(index > 0, "No data iterated through")
// Now write the files' contents to the zip in reverse
for i in 0..<testFilePaths.count {
let x = testFilePaths.count - 1 - i
do {
try archive.write(testFileData[x], filePath: testFilePaths[i],
fileDate: testDates[x], compressionMethod: .default, password: nil, overwrite: false)
} catch let error as NSError {
XCTFail("Error writing to file \(testFilePaths[x]) with data of " +
"file \(testFilePaths[i]): \(error)")
}
}
let newFileList = try! archive.listFileInfo()
// This is the most we can guarantee, the number of files in the directory
XCTAssertEqual(newFileList.count, testFilePaths.count * 2, "Files not appended correctly")
}
func testWriteData_MultipleWrites() {
let testArchiveURL = tempDirectory.appendingPathComponent("MultipleDataWriteTest.zip")
let testFilename = nonZipTestFilePaths.first as! String
let testFileURL = testFileURLs[testFilename] as! URL
let testFileData = try! Data(contentsOf: testFileURL)
let archive = try! UZKArchive(url: testArchiveURL)
var lastFileSize: UInt64 = 0
for _ in 0..<100 {
do {
try archive.write(testFileData, filePath: testFilename, fileDate: nil,
compressionMethod: .default, password: nil)
} catch let error as NSError {
XCTFail("Error writing to file \(testFileURL): \(error)")
}
let fm = FileManager.default
let fileAttributes = try! fm.attributesOfItem(atPath: testArchiveURL.path)
let fileSize = fileAttributes[FileAttributeKey.size] as! NSNumber
if lastFileSize > 0 {
XCTAssertEqual(lastFileSize, fileSize.uint64Value, "File changed size between writes")
}
lastFileSize = fileSize.uint64Value
}
}
// func testWriteData_ManyFiles_MemoryUsage_ForProfiling() {
// let testArchiveURL = tempDirectory.appendingPathComponent("ManyFilesMemoryUsageTest.zip")
// let testFilename = nonZipTestFilePaths.first as! String
// let testFileURL = testFileURLs[testFilename] as! URL
// let testFileData = try! Data(contentsOf: testFileURL)
//
// let archive = try! UZKArchive(url: testArchiveURL)
//
// for i in 1...1000 {
// do {
// try archive.write(testFileData, filePath: "File \(i).txt", fileDate: nil,
// compressionMethod: .default, password: nil, overwrite: true, progress: nil)
// } catch let error as NSError {
// XCTFail("Error writing to file \(testFileURL): \(error)")
// }
// }
// }
func testWriteData_DefaultDate() {
let testArchiveURL = tempDirectory.appendingPathComponent("DefaultDateWriteTest.zip")
let testFilename = nonZipTestFilePaths.first as! String
let testFileURL = testFileURLs[testFilename] as! URL
let testFileData = try! Data(contentsOf: testFileURL)
let archive = try! UZKArchive(url: testArchiveURL)
do {
try archive.write(testFileData, filePath: testFilename, fileDate: nil,
compressionMethod: .default, password: nil)
} catch let error as NSError {
XCTFail("Error writing to file \(testFileURL): \(error)")
}
let fileList = try! archive.listFileInfo()
let writtenFileInfo = fileList.first!
let expectedDate = Date().timeIntervalSinceReferenceDate
let actualDate = writtenFileInfo.timestamp.timeIntervalSinceReferenceDate
XCTAssertEqual(actualDate, expectedDate, accuracy: 30, "Incorrect default date value written to file")
}
#if os(OSX)
func testWriteData_PasswordProtected() {
let testFilePaths = [String](nonZipTestFilePaths as! Set<String>).sorted(by: <)
var testFileData = [Data]()
let testArchiveURL = tempDirectory.appendingPathComponent("SwiftWriteDataTest.zip")
let password = "111111"
let writeArchive = try! UZKArchive(path: testArchiveURL.path, password: password)
for testFilePath in testFilePaths {
let fileData = try? Data(contentsOf: testFileURLs[testFilePath] as! URL)
testFileData.append(fileData!)
do {
try writeArchive.write(fileData!, filePath: testFilePath)
} catch let error as NSError {
XCTFail("Error writing to file \(testFilePath): \(error)")
}
}
// Read with UnzipKit
let readArchive = try! UZKArchive(path: testArchiveURL.path, password: password)
XCTAssertTrue(readArchive.isPasswordProtected(), "Archive is not marked as password-protected")
var index = 0
try! readArchive.performOnData(inArchive: { (fileInfo, fileData, stop) -> Void in
let expectedData = testFileData[index]
let expectedCRC = crc32(0, (expectedData as NSData).bytes.bindMemory(to: Bytef.self, capacity: expectedData.count), uInt(expectedData.count))
XCTAssertEqual(fileInfo.filename, testFilePaths[index], "Incorrect filename in archive")
XCTAssertEqual(fileInfo.crc, expectedCRC, "CRC of extracted data doesn't match what was written")
XCTAssertEqual(fileData, expectedData, "Data extracted doesn't match what was written")
index += 1;
})
XCTAssertEqual(index, testFilePaths.count, "Not all files enumerated")
// Read with the unzip command line tool
let success = extractArchive(testArchiveURL, password: password)
XCTAssertTrue(success, "Failed to extract the archive on the command line")
}
func testWriteData_ExternalVolume() {
// Create a simple zip file
let tempDirURL = URL(fileURLWithPath: self.randomDirectoryName())
let textFileName = "testWriteData_ExternalVolume.txt"
let textFileURL = tempDirURL.appendingPathComponent(textFileName)
try! FileManager.default.createDirectory(at: tempDirURL, withIntermediateDirectories: true, attributes: [:])
try! "This is the original text".write(to: textFileURL, atomically: false, encoding: String.Encoding.utf8)
let tempZipFileURL = self.archive(withFiles: [textFileURL])
NSLog("Original ZIP file: \(String(describing: tempZipFileURL?.path))")
// Write that zip file to contents of a DMG and mount it
let dmgSourceFolderURL = tempDirURL.appendingPathComponent("DMGSource")
try! FileManager.default.createDirectory(at: dmgSourceFolderURL, withIntermediateDirectories: true, attributes: [:])
try! FileManager.default.copyItem(at: tempZipFileURL!, to: dmgSourceFolderURL.appendingPathComponent(tempZipFileURL!.lastPathComponent))
let dmgURL = tempDirURL.appendingPathComponent("testWriteData_ExternalVolume.dmg")
let mountPoint = createAndMountDMG(path: dmgURL, source: dmgSourceFolderURL, fileSystem: .HFS)!
NSLog("Disk image: \(dmgURL.path)")
defer {
unmountDMG(URL: mountPoint)
}
// Update a file from the archive with overwrite=YES
let externalVolumeZipURL = mountPoint.appendingPathComponent(tempZipFileURL!.lastPathComponent)
let archive = try! UZKArchive(url: externalVolumeZipURL)
let newText = "This is the new text"
let newTextData = newText.data(using: String.Encoding.utf8)
var writeSuccessful = true
do {
try archive.write(newTextData!, filePath: textFileName, fileDate: nil,
compressionMethod: UZKCompressionMethod.default, password: nil,
overwrite: true)
} catch let error {
NSLog("Error writing data to archive on external volume: \(error)")
writeSuccessful = false
}
XCTAssertTrue(writeSuccessful, "Failed to update archive on external volume")
let archivedFileData = try! archive.extractData(fromFile: textFileName)
XCTAssertNotNil(archivedFileData, "No data extracted from file in archive on external volume")
let archivedText = NSString(data: archivedFileData, encoding: String.Encoding.utf8.rawValue)!
XCTAssertEqual(archivedText as String, newText, "Incorrect text extracted from archive on external volume")
}
#endif
}