Give mixed selections something to do
A Drag of different kinds showed an empty wheel, because the catalog only answers for a single category. Filee's answer is a mixed profile, so add Zip (one archive, flat names) and Merge (non-PDFs are converted to PDF first); a multi-file drag of one kind gets Zip too.
This commit is contained in:
@@ -1,6 +1,7 @@
|
||||
import AppKit
|
||||
import CoreGraphics
|
||||
import Foundation
|
||||
import PDFKit
|
||||
|
||||
/// `--self-test` exercises the real conversion paths end to end and exits
|
||||
/// non-zero on failure. Kept in the shipped binary so a build can be verified
|
||||
@@ -29,6 +30,7 @@ enum SelfTest {
|
||||
testDocuments()
|
||||
testAudio()
|
||||
testEbook()
|
||||
testCombining()
|
||||
testGeometry()
|
||||
|
||||
print("")
|
||||
@@ -224,6 +226,25 @@ enum SelfTest {
|
||||
try ArchiveConverter.convert(source: folder, to: .tar, at: tar)
|
||||
try requireFile(tar)
|
||||
}
|
||||
|
||||
check("several files → one zip") {
|
||||
let first = directory.appendingPathComponent("note.txt")
|
||||
let second = directory.appendingPathComponent("spreadsheet.csv")
|
||||
try? "one".write(to: first, atomically: true, encoding: .utf8)
|
||||
try? "a,b\n1,2\n".write(to: second, atomically: true, encoding: .utf8)
|
||||
let zip = directory.appendingPathComponent("selection.zip")
|
||||
try ArchiveConverter.createArchive(from: [first, second], at: zip)
|
||||
try requireFile(zip)
|
||||
|
||||
let target = directory.appendingPathComponent("selection-unpacked", isDirectory: true)
|
||||
try ArchiveConverter.extract(source: zip, into: target)
|
||||
for name in ["note.txt", "spreadsheet.csv"] {
|
||||
let entry = target.appendingPathComponent(name)
|
||||
guard FileManager.default.fileExists(atPath: entry.path) else {
|
||||
throw TestFailure("\(name) missing from the archive")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static func testDocuments() {
|
||||
@@ -325,6 +346,59 @@ enum SelfTest {
|
||||
}
|
||||
}
|
||||
|
||||
/// Filee's "mixed profile": a drag of different kinds still has something
|
||||
/// useful to do, instead of an empty wheel.
|
||||
private static func testCombining() {
|
||||
section("Mixed selections")
|
||||
let photo = directory.appendingPathComponent("sample.png")
|
||||
let pdf = directory.appendingPathComponent("sample.pdf")
|
||||
let note = directory.appendingPathComponent("note.txt")
|
||||
|
||||
check("a mixed drag still gets a wheel") {
|
||||
let items = WheelBuilder.items(kind: .convert, urls: [photo, pdf])
|
||||
let tools = items.compactMap { item -> ToolID? in
|
||||
if case .tool(let tool) = item.payload { return tool }
|
||||
return nil
|
||||
}
|
||||
guard !items.isEmpty else { throw TestFailure("the convert wheel was empty") }
|
||||
guard tools.contains(.mergePDF), tools.contains(.createArchive) else {
|
||||
throw TestFailure("expected Merge and Zip, got \(tools.map(\.rawValue))")
|
||||
}
|
||||
}
|
||||
|
||||
check("a multi-file wheel can always be zipped") {
|
||||
let items = WheelBuilder.items(kind: .tools, urls: [photo, directory.appendingPathComponent("note.txt")])
|
||||
let tools = items.compactMap { item -> ToolID? in
|
||||
if case .tool(let tool) = item.payload { return tool }
|
||||
return nil
|
||||
}
|
||||
guard tools.contains(.createArchive) else {
|
||||
throw TestFailure("Zip is missing from a two-file image wheel")
|
||||
}
|
||||
}
|
||||
|
||||
check("photos and pdfs merge into one pdf") {
|
||||
let outcome = try ToolRunner.run(tool: .mergePDF, inputs: [photo, pdf], params: ToolParams())
|
||||
guard let merged = outcome.outputs.first,
|
||||
let document = PDFDocument(url: merged) else {
|
||||
throw TestFailure("no merged pdf was produced")
|
||||
}
|
||||
guard document.pageCount >= 2 else {
|
||||
throw TestFailure("merged pdf has \(document.pageCount) page(s)")
|
||||
}
|
||||
}
|
||||
|
||||
check("any files → one zip") {
|
||||
let outcome = try ToolRunner.run(tool: .createArchive, inputs: [note, photo], params: ToolParams())
|
||||
guard let zip = outcome.outputs.first else { throw TestFailure("no archive was produced") }
|
||||
try requireFile(zip)
|
||||
let entries = try ArchiveConverter.list(zip)
|
||||
for name in ["note.txt", "sample.png"] where !entries.contains(name) {
|
||||
throw TestFailure("\(name) is missing from the archive: \(entries)")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static func testGeometry() {
|
||||
section("Wheel geometry")
|
||||
let frame = CGRect(x: 0, y: 0, width: 400, height: 400)
|
||||
|
||||
Reference in New Issue
Block a user