Files
ICCery-CPU/Tests/TestRunnerMain.swift
gronod 474888541b
Build macOS Packages / Build macOS (Intel) (pull_request) Successful in 32s
Build macOS Packages / Build macOS (Apple Silicon) (pull_request) Successful in 37s
Build macOS Packages / Build macOS (Universal) (pull_request) Failing after 10s
feat: add hardware print quality option supporting Canon 5-notch Custom slider and Epson modes (Closes #5)
2026-09-07 23:37:01 +01:00

384 lines
16 KiB
Swift

import Foundation
import AppKit
// Standalone CLI test runner for environments without full Xcode / XCTest.framework (e.g. Command Line Tools).
func expect(_ condition: @autoclosure () -> Bool, _ message: String = "", file: StaticString = #file, line: UInt = #line) {
if !condition() {
fputs("❌ FAIL: \(file):\(line): condition was false. \(message)\n", stderr)
exit(1)
}
}
func expectEqual<T: Equatable>(_ actual: T, _ expected: T, _ message: String = "", file: StaticString = #file, line: UInt = #line) {
if actual != expected {
fputs("❌ FAIL: \(file):\(line): expected '\(expected)', got '\(actual)'. \(message)\n", stderr)
exit(1)
}
}
func expectNil<T>(_ actual: T?, _ message: String = "", file: StaticString = #file, line: UInt = #line) {
if let actual = actual {
fputs("❌ FAIL: \(file):\(line): expected nil, got '\(actual)'. \(message)\n", stderr)
exit(1)
}
}
@main
struct TestRunner {
static func main() {
print("==> Running TargetPrint test suite...")
// MARK: - 1. PPD Options & Choice Tests (Issues #1 and #2)
print("--> PPDOptionsTests")
// Hex decoding
expectEqual(CUPSManager.decodePPDString("plain"), "plain")
expectEqual(CUPSManager.decodePPDString("CD<2F>DVD"), "CD/DVD")
expectEqual(CUPSManager.decodePPDString("Photo<20>Paper<2E> Glossy"), "Photo Paper. Glossy")
expectEqual(CUPSManager.decodePPDString("Colon<3A>Test"), "Colon:Test")
expectEqual(CUPSManager.decodePPDString("Unclosed<2F"), "Unclosed<2F")
expectEqual(CUPSManager.decodePPDString("Invalid<ZZ>"), "Invalid<ZZ>")
// Standard PPD
let stdPPD = """
*OpenUI *PageSize/Media Size: PickOne
*PageSize A4/A4: ""
*PageSize Letter/US Letter: ""
*CloseUI: *PageSize
*OpenUI *MediaType/Media Type: PickOne
*MediaType Plain/Plain Paper: ""
*MediaType Glossy/Photo Glossy: ""
*CloseUI: *MediaType
*OpenUI *InputSlot/Paper Source: PickOne
*InputSlot Auto/Automatic Selection: ""
*InputSlot Upper/Upper Cassette: ""
*CloseUI: *InputSlot
"""
let stdOpts = CUPSManager.discoverPPDOptions(stdPPD)
expectEqual(stdOpts.pageSizes, ["A4", "Letter"])
expectEqual(stdOpts.mediaTypeKeyword, "MediaType")
expectEqual(stdOpts.mediaTypeChoices, [
PPDChoice(name: "Plain", title: "Plain Paper"),
PPDChoice(name: "Glossy", title: "Photo Glossy")
])
expectEqual(stdOpts.mediaTypes, ["Plain Paper", "Photo Glossy"])
expectEqual(stdOpts.trayKeyword, "InputSlot")
expectEqual(stdOpts.trayChoices, [
PPDChoice(name: "Auto", title: "Automatic Selection"),
PPDChoice(name: "Upper", title: "Upper Cassette")
])
expectEqual(stdOpts.trays, ["Automatic Selection", "Upper Cassette"])
// Epson PPD
let epsonPPD = """
*OpenUI *MediaType/Media Type: PickOne
*MediaType 0/plain papers: ""
*MediaType 13/Epson Premium Glossy: ""
*MediaType 26/CD<2F>DVD: ""
*CloseUI: *MediaType
*OpenUI *EPIJ_FdSo/Paper Source: PickOne
*EPIJ_FdSo 2/Cassette 1: ""
*EPIJ_FdSo 3/Cassette 2: ""
*EPIJ_FdSo 12/Rear Paper Feed Slot: ""
*CloseUI: *EPIJ_FdSo
"""
let epsonOpts = CUPSManager.discoverPPDOptions(epsonPPD)
expectEqual(epsonOpts.mediaTypeKeyword, "MediaType")
expectEqual(epsonOpts.mediaTypeChoices, [
PPDChoice(name: "0", title: "plain papers"),
PPDChoice(name: "13", title: "Epson Premium Glossy"),
PPDChoice(name: "26", title: "CD/DVD")
])
expectEqual(epsonOpts.mediaTypes, ["plain papers", "Epson Premium Glossy", "CD/DVD"])
expectEqual(epsonOpts.trayKeyword, "EPIJ_FdSo")
expectEqual(epsonOpts.trayChoices, [
PPDChoice(name: "2", title: "Cassette 1"),
PPDChoice(name: "3", title: "Cassette 2"),
PPDChoice(name: "12", title: "Rear Paper Feed Slot")
])
expectEqual(epsonOpts.trays, ["Cassette 1", "Cassette 2", "Rear Paper Feed Slot"])
// Canon PPD
let canonPPD = """
*OpenUI *CNIJMediaType/Media Type: PickOne
*CNIJMediaType 0/Plain Paper: ""
*CNIJMediaType 92/Photo Paper Plus Glossy II: ""
*CloseUI: *CNIJMediaType
*OpenUI *CNIJMediaSupply/Paper Source: PickOne
*CNIJMediaSupply 7/Rear Tray: ""
*CNIJMediaSupply 33/Manual Feed: ""
*CloseUI: *CNIJMediaSupply
"""
let canonOpts = CUPSManager.discoverPPDOptions(canonPPD)
expectEqual(canonOpts.mediaTypeKeyword, "CNIJMediaType")
expectEqual(canonOpts.mediaTypeChoices, [
PPDChoice(name: "0", title: "Plain Paper"),
PPDChoice(name: "92", title: "Photo Paper Plus Glossy II")
])
expectEqual(canonOpts.mediaTypes, ["Plain Paper", "Photo Paper Plus Glossy II"])
expectEqual(canonOpts.trayKeyword, "CNIJMediaSupply")
expectEqual(canonOpts.trayChoices, [
PPDChoice(name: "7", title: "Rear Tray"),
PPDChoice(name: "33", title: "Manual Feed")
])
expectEqual(canonOpts.trays, ["Rear Tray", "Manual Feed"])
// Empty PPD
let emptyOpts = CUPSManager.discoverPPDOptions("")
expectNil(emptyOpts.mediaTypeKeyword)
expect(emptyOpts.mediaTypeChoices.isEmpty)
expect(emptyOpts.mediaTypes.isEmpty)
expectNil(emptyOpts.trayKeyword)
expect(emptyOpts.trayChoices.isEmpty)
expect(emptyOpts.trays.isEmpty)
// Strip quotes & fallback
let quotePPD = """
*OpenUI *MediaType/Media Type: PickOne
*MediaType Custom/"My Custom Paper": ""
*MediaType Fallback: ""
*CloseUI: *MediaType
"""
let quoteOpts = CUPSManager.discoverPPDOptions(quotePPD)
expectEqual(quoteOpts.mediaTypeChoices, [
PPDChoice(name: "Custom", title: "My Custom Paper"),
PPDChoice(name: "Fallback", title: "Fallback")
])
// PrintEngine dynamic resolution and vendor keys
let epsonQueue = PrinterQueue(
name: "TestEpson",
displayName: "Test Epson",
uri: "usb://epson",
make: "Epson",
model: "XP-55",
isAirPrint: false,
mediaSizes: ["A4"],
mediaTypes: epsonOpts.mediaTypes,
mediaTypeChoices: epsonOpts.mediaTypeChoices,
mediaTypeKeyword: epsonOpts.mediaTypeKeyword,
trays: epsonOpts.trays,
trayChoices: epsonOpts.trayChoices,
trayKeyword: epsonOpts.trayKeyword,
resolutions: [],
ppdText: epsonPPD
)
let engine = PrintEngine()
engine.mediaType = "Epson Premium Glossy"
engine.paperSource = "Cassette 1"
let printInfo = NSPrintInfo()
engine.applyOptionalPPDKeys(to: printInfo, queue: epsonQueue)
let settingsKey = NSPrintInfo.AttributeKey(rawValue: "com.apple.print.printSettings")
let settings = printInfo.dictionary()[settingsKey] as? NSDictionary
expectEqual(settings?["MediaType"] as? String, Optional("13"))
expectEqual(settings?["EPIJ_FdSo"] as? String, Optional("2"))
let canonQueue = PrinterQueue(
name: "TestCanon",
displayName: "Test Canon",
uri: "usb://canon",
make: "Canon",
model: "Pro9500",
isAirPrint: false,
mediaSizes: ["A4"],
mediaTypes: canonOpts.mediaTypes,
mediaTypeChoices: canonOpts.mediaTypeChoices,
mediaTypeKeyword: canonOpts.mediaTypeKeyword,
trays: canonOpts.trays,
trayChoices: canonOpts.trayChoices,
trayKeyword: canonOpts.trayKeyword,
resolutions: [],
ppdText: canonPPD
)
let canonEngine = PrintEngine()
canonEngine.mediaType = "Photo Paper Plus Glossy II"
canonEngine.paperSource = "Rear Tray"
let canonPrintInfo = NSPrintInfo()
canonEngine.applyOptionalPPDKeys(to: canonPrintInfo, queue: canonQueue)
let canonSettings = canonPrintInfo.dictionary()[settingsKey] as? NSDictionary
expectEqual(canonSettings?["CNIJMediaType"] as? String, Optional("92"))
expectEqual(canonSettings?["CNIJMediaSupply"] as? String, Optional("7"))
// Canon 5-notch Custom quality tests
let canonQualityPPD = """
*OpenUI *CNIJPrintQuality/Print Quality: PickOne
*CNIJPrintQuality 0/Super Fine: ""
*CNIJPrintQuality 5/Fine: ""
*CNIJPrintQuality 10/Normal(Fine): ""
*CNIJPrintQuality 15/Normal(Fast): ""
*CNIJPrintQuality 20/Fast: ""
*CloseUI: *CNIJPrintQuality
"""
let canonQOpts = CUPSManager.discoverPPDOptions(canonQualityPPD)
expectEqual(canonQOpts.qualityKeyword, "CNIJPrintQuality")
expectEqual(canonQOpts.qualityChoices, [
PPDChoice(name: "0", title: "Super Fine"),
PPDChoice(name: "5", title: "Fine"),
PPDChoice(name: "10", title: "Normal(Fine)"),
PPDChoice(name: "15", title: "Normal(Fast)"),
PPDChoice(name: "20", title: "Fast")
])
let canonQQueue = PrinterQueue(
name: "TestCanonQ",
displayName: "Test Canon Quality",
uri: "usb://canon",
make: "Canon",
model: "Pro9500",
isAirPrint: false,
mediaSizes: ["A4"],
mediaTypes: [],
mediaTypeChoices: [],
mediaTypeKeyword: nil,
trays: [],
trayChoices: [],
trayKeyword: nil,
qualityChoices: canonQOpts.qualityChoices,
qualityKeyword: canonQOpts.qualityKeyword,
resolutions: [],
ppdText: canonQualityPPD
)
// Super Fine: custom mode 5, slider notch 5, quality 0
let superFineEngine = PrintEngine()
superFineEngine.printQuality = "Super Fine"
let superFineInfo = NSPrintInfo()
superFineEngine.applyOptionalPPDKeys(to: superFineInfo, queue: canonQQueue)
let superFineSettings = superFineInfo.dictionary()[settingsKey] as? NSDictionary
expectEqual(superFineSettings?["CNIJPrintQuality"] as? String, Optional("0"))
expectEqual(superFineSettings?["CNIJPrintMode2"] as? String, Optional("5"))
expectEqual(superFineSettings?["CNIJPQualitySlider"] as? String, Optional("5"))
// Fine: preset mode 1, slider notch 4, quality 5
let fineEngine = PrintEngine()
fineEngine.printQuality = "Fine"
let fineInfo = NSPrintInfo()
fineEngine.applyOptionalPPDKeys(to: fineInfo, queue: canonQQueue)
let fineSettings = fineInfo.dictionary()[settingsKey] as? NSDictionary
expectEqual(fineSettings?["CNIJPrintQuality"] as? String, Optional("5"))
expectEqual(fineSettings?["CNIJPrintMode2"] as? String, Optional("1"))
expectEqual(fineSettings?["CNIJPQualitySlider"] as? String, Optional("4"))
// Epson quality test
let epsonQualityPPD = """
*OpenUI *EPIJ_Qual/Quality: PickOne
*EPIJ_Qual 307/Best Quality: ""
*EPIJ_Qual 305/Quality: ""
*EPIJ_Qual 304/Fine: ""
*CloseUI: *EPIJ_Qual
"""
let epsonQOpts = CUPSManager.discoverPPDOptions(epsonQualityPPD)
expectEqual(epsonQOpts.qualityKeyword, "EPIJ_Qual")
expectEqual(epsonQOpts.qualityChoices.count, 3)
expectEqual(epsonQOpts.qualityChoices.first?.name, "307")
expectEqual(epsonQOpts.qualityChoices.first?.title, "Best Quality")
let epsonQQueue = PrinterQueue(
name: "TestEpsonQ",
displayName: "Test Epson Quality",
uri: "usb://epson",
make: "Epson",
model: "XP-55",
isAirPrint: false,
mediaSizes: ["A4"],
mediaTypes: [],
mediaTypeChoices: [],
mediaTypeKeyword: nil,
trays: [],
trayChoices: [],
trayKeyword: nil,
qualityChoices: epsonQOpts.qualityChoices,
qualityKeyword: epsonQOpts.qualityKeyword,
resolutions: [],
ppdText: epsonQualityPPD
)
let epsonQEngine = PrintEngine()
epsonQEngine.printQuality = "Best Quality"
let epsonQInfo = NSPrintInfo()
epsonQEngine.applyOptionalPPDKeys(to: epsonQInfo, queue: epsonQQueue)
let epsonQSettings = epsonQInfo.dictionary()[settingsKey] as? NSDictionary
expectEqual(epsonQSettings?["EPIJ_Qual"] as? String, Optional("307"))
print(" [PASS] PPDOptionsTests")
// MARK: - 2. AirPrintTests
print("--> AirPrintTests")
expect(AirPrintDetector.isAirPrint(uri: "apple-airprint://Brother%20HL._ipp._tcp.local/", ppdText: "", make: "Brother", model: "HL-L3270CDW"))
expect(AirPrintDetector.isAirPrint(uri: "ipps://living-room.local/ipp/print", ppdText: "*Manufacturer: Apple\n*APAirPrint: True\n", make: "Apple", model: "AirPrint Printer"))
expect(AirPrintDetector.isAirPrint(uri: "dnssd://Foo._ipp._tcp.local/", ppdText: "", make: "Apple", model: "Living Room AirPrint"))
expect(!AirPrintDetector.isAirPrint(uri: "usb://EPSON/XP-55%20Series?serial=X5R001", ppdText: "*Manufacturer: Epson\n*EPSONColorControls: Off\n", make: "Epson", model: "XP-55"))
expect(!AirPrintDetector.isAirPrint(uri: "ipps://office-printer.local/ipp/print", ppdText: "*Manufacturer: HP\n*HPColorControl: Off\n", make: "HP", model: "OfficeJet Pro 9010"))
let epsonBypass = CUPSManager.vendorColorBypass(make: "Epson", model: "XP-55", ppdText: "")
expectEqual(epsonBypass["ColorModel"], "RGB")
expectEqual(epsonBypass["EPSONColorControls"], "Off")
let canonBypass = CUPSManager.vendorColorBypass(make: "Canon", model: "PRO-100", ppdText: "")
expectEqual(canonBypass["CNColorMatching"], "None")
let hpBypass = CUPSManager.vendorColorBypass(make: "HP", model: "9010", ppdText: "")
expectEqual(hpBypass["HPColorControl"], "Off")
print(" [PASS] AirPrintTests")
// MARK: - 3. GeometryTests
print("--> GeometryTests")
let w = Geometry.physicalInches(pixels: 2400, dpi: 300)
let h = Geometry.physicalInches(pixels: 3000, dpi: 300)
expectEqual(w, 8.0)
expectEqual(h, 10.0)
expect(Geometry.geometricAccuracyPass(expectedWidthIn: 8, expectedHeightIn: 10, actualWidthIn: w, actualHeightIn: h))
expectEqual(Geometry.physicalInches(pixels: 720, dpi: 0), 10.0)
expectEqual(Geometry.physicalInches(pixels: 720, dpi: -3), 10.0)
expectEqual(Geometry.physicalInches(pixels: 72, dpi: 72), 1.0)
let letter = Geometry.paper(named: "Letter")
expect(abs(letter.widthPt - 612.0) < 0.01)
expect(abs(letter.heightPt - 792.0) < 0.01)
print(" [PASS] GeometryTests")
// MARK: - 4. TargetJobTests
print("--> TargetJobTests")
let validJSON = """
{
"version": 1,
"jobTitle": "Epson_XP55_IlfordLustre_Target_P1-2",
"files": ["/tmp/a.tif", "/tmp/b.tif"],
"printSettings": {
"printerName": "EPSON_XP_55_Series",
"mediaSize": "A4",
"mediaType": "PremiumGlossy",
"paperSource": "Auto",
"resolution": "5760x1440dpi",
"printQuality": "Super Fine",
"scaling": 1.0,
"centered": true,
"forceUnmanagedColor": true
},
"uiPolicy": {
"lockColorManagement": true,
"allowBasicDriverChanges": true
},
"unknownKey": "ignored"
}
"""
do {
let parsed = try TargetJobParser.parse(text: validJSON)
expectEqual(parsed.version, 1)
expectEqual(parsed.jobTitle, "Epson_XP55_IlfordLustre_Target_P1-2")
expectEqual(parsed.files.count, 2)
expectEqual(parsed.printSettings.mediaType, "PremiumGlossy")
expectEqual(parsed.printSettings.printQuality, "Super Fine")
let serialized = try TargetJobParser.serialize(parsed)
let again = try TargetJobParser.parse(data: serialized)
expectEqual(parsed, again)
expectEqual(again.printSettings.printQuality, "Super Fine")
} catch {
fputs("TargetJob parsing error: \(error)\n", stderr)
exit(1)
}
print(" [PASS] TargetJobTests")
print("==> All test suites passed successfully! 🎉")
}
}