import Testing import Foundation @testable import OnyxNotch @Suite("Hintergrundbild aus macOS' Verwaltung") struct WallpaperIndexTests { /// Baut einen Eintrag, wie ihn macOS ablegt. private func entry(_ path: String) -> [String: Any] { ["type": "imageFile", "url": ["relative": "file://" + path]] } private func nested(_ value: Any) throws -> Data { try PropertyListSerialization.data(fromPropertyList: value, format: .binary, options: 0) } @Test("Ein Bild in der äußeren Liste wird gefunden") func findsPlainEntry() { var found: [URL] = [] WallpaperLoader.collectImageFiles(["Desktop": entry("/tmp/a.jpg")], into: &found) #expect(found.map(\.path) == ["/tmp/a.jpg"]) } @Test("Ein Bild in einer verschachtelten Liste wird auch gefunden") func findsNestedEntry() throws { // Genau daran hängt es: die Konfiguration je Bildschirm steckt als // eigene Property-Liste in einem Datenfeld der äußeren. var found: [URL] = [] let inner = try nested(entry("/tmp/b.jpg")) WallpaperLoader.collectImageFiles( ["Displays": ["ABC": ["Desktop": ["Configuration": inner]]]], into: &found) #expect(found.map(\.path) == ["/tmp/b.jpg"]) } @Test("Mehrere Bildschirme ergeben mehrere Bilder") func findsAllScreens() throws { var found: [URL] = [] WallpaperLoader.collectImageFiles( ["Displays": ["A": try nested(entry("/tmp/a.jpg")), "B": try nested(entry("/tmp/b.jpg"))]], into: &found) #expect(Set(found.map(\.path)) == ["/tmp/a.jpg", "/tmp/b.jpg"]) } @Test("Einträge ohne Datei bleiben liegen") func ignoresNonFileEntries() { // Fotos und Aerials stehen als „asset" mit einer Kennung darin — daraus // lässt sich keine Datei machen, und ein Eintrag ohne Datei darf nicht // als Bild durchgehen. var found: [URL] = [] WallpaperLoader.collectImageFiles( ["Idle": ["type": "asset", "identifier": "3316307E-788F"], "Web": ["type": "imageFile", "url": ["relative": "https://example.com/a.jpg"]]], into: &found) #expect(found.isEmpty) } @Test("Nur der eigene Bildschirm zählt") func onlyOwnScreenCounts() throws { // In der Datei stehen auch alte Bildschirme und der Bildschirmschoner. // Das Neueste von allem zu nehmen führt zuverlässig zu einem Bild, das // mit dem Schreibtisch nichts zu tun hat — gemessen war das hier ein // weißes Platzhalterbild aus einem Kurzbefehl. var found: [URL] = [] let entry: [String: Any] = ["Desktop": ["Content": ["Choices": [ ["Configuration": try nested(entry("/tmp/richtig.jpg"))]]]]] WallpaperLoader.collectImageFiles(entry["Desktop"] as Any, into: &found) #expect(found.map(\.path) == ["/tmp/richtig.jpg"]) } @Test("Unbrauchbare Daten stürzen nicht ab") func survivesGarbage() { var found: [URL] = [] WallpaperLoader.collectImageFiles( ["A": Data("bplist00 aber kaputt".utf8), "B": 42, "C": Date()], into: &found) #expect(found.isEmpty) } }