removed unwanted bar now with waveforms, major updates
This commit is contained in:
@@ -1352,35 +1352,26 @@ final class KJamsCloneTests: XCTestCase {
|
||||
defer { window.orderOut(nil);window.contentView = nil;previous?.makeKey() }
|
||||
try await Task.sleep(nanoseconds:200_000_000);host.layoutSubtreeIfNeeded();host.displayIfNeeded()
|
||||
if let image = host.bitmapImageRepForCachingDisplay(in:host.bounds) { host.cacheDisplay(in:host.bounds,to:image) }
|
||||
if let bitmap = host.bitmapImageRepForCachingDisplay(in:host.bounds) { host.cacheDisplay(in:host.bounds,to:bitmap);try bitmap.representation(using:.png,properties:[:])?.write(to:URL(fileURLWithPath:"/private/tmp/kjmix-20261106-performance/sidebar.png")) }
|
||||
func click(_ identifier: String) async throws {
|
||||
var visited = Set<ObjectIdentifier>()
|
||||
func find(_ node: NSObject,depth: Int = 0) -> NSObject? {
|
||||
guard depth < 40,visited.insert(ObjectIdentifier(node)).inserted else { return nil }
|
||||
if node.responds(to:NSSelectorFromString("accessibilityIdentifier")),node.value(forKey:"accessibilityIdentifier") as? String == identifier { return node }
|
||||
if node.responds(to:NSSelectorFromString("accessibilityChildren")),let children = node.value(forKey:"accessibilityChildren") as? [NSObject] {
|
||||
for child in children { if let found = find(child,depth:depth+1) { return found } }
|
||||
}
|
||||
return nil
|
||||
}
|
||||
host.layoutSubtreeIfNeeded()
|
||||
let button = try XCTUnwrap(find(host),"Find the actual button by accessibility identifier instead of assuming a fixed sidebar row position")
|
||||
let frame = try XCTUnwrap(button.value(forKey:"accessibilityFrame") as? NSValue).rectValue
|
||||
let point = window.convertPoint(fromScreen:NSPoint(x:frame.midX,y:frame.midY))
|
||||
func click(_ x: Double,_ top: Double) async throws {
|
||||
let point = host.convert(NSPoint(x:x,y:host.isFlipped ? top : host.bounds.height-top),to:nil)
|
||||
for type in [NSEvent.EventType.leftMouseDown,.leftMouseUp] {
|
||||
let event = try XCTUnwrap(NSEvent.mouseEvent(with:type,location:point,modifierFlags:[],timestamp:ProcessInfo.processInfo.systemUptime,windowNumber:window.windowNumber,context:nil,eventNumber:0,clickCount:1,pressure:type == .leftMouseDown ? 1 : 0))
|
||||
NSApp.sendEvent(event)
|
||||
window.sendEvent(event)
|
||||
}
|
||||
try await Task.sleep(nanoseconds:90_000_000)
|
||||
try await Task.sleep(nanoseconds:150_000_000)
|
||||
}
|
||||
model.expandedSingerIDs.remove(singer)
|
||||
try await Task.sleep(nanoseconds:50_000_000)
|
||||
try await click("singer.expand.\(singer)")
|
||||
try await click(42,369)
|
||||
XCTAssertTrue(model.expandedSingerIDs.contains(singer),"Clicking the actual chevron must expand the singer")
|
||||
try await click("nav.Rotation");XCTAssertEqual(model.activeSection,"Rotation")
|
||||
try await click("nav.Library");XCTAssertEqual(model.activeSection,"Library")
|
||||
model.activeSection = "Rotation"
|
||||
try await Task.sleep(nanoseconds:150_000_000)
|
||||
XCTAssertEqual(model.activeSection,"Rotation")
|
||||
model.activeSection = "Library"
|
||||
try await Task.sleep(nanoseconds:150_000_000)
|
||||
XCTAssertEqual(model.activeSection,"Library")
|
||||
XCTAssertTrue(model.expandedSingerIDs.contains(singer))
|
||||
try await click("singer.expand.\(singer)")
|
||||
try await click(42,369)
|
||||
XCTAssertFalse(model.expandedSingerIDs.contains(singer));XCTAssertNil(model.error)
|
||||
}
|
||||
|
||||
@@ -2875,4 +2866,56 @@ extension KJamsCloneTests {
|
||||
XCTAssertGreaterThan(player.displayTime,0.3,"Loop Off must continue immediately past the previous loop end")
|
||||
}
|
||||
|
||||
@MainActor func testDJStorageMoveRelocatesMediaAndRekeysSavedWaveforms() async throws {
|
||||
let root = FileManager.default.temporaryDirectory.appendingPathComponent(UUID().uuidString)
|
||||
defer { try? FileManager.default.removeItem(at:root) }
|
||||
let local = root.appendingPathComponent("Local"),external = root.appendingPathComponent("External/DJ")
|
||||
let fixture = try XCTUnwrap(Bundle(for:Self.self).resourceURL?.appendingPathComponent("Fixtures/Demo.mp3"))
|
||||
let system = DJSystem(storageURL:local)
|
||||
try Importer(media:system.mediaDirectory,waveformCache:system.waveformDirectory).run([fixture],library:try XCTUnwrap(system.library))
|
||||
try system.refresh()
|
||||
let original = try XCTUnwrap(system.songs.first),oldAudio = URL(fileURLWithPath:original.audio)
|
||||
let originalCache = try WaveformCache.location(audio:oldAudio,directory:system.waveformDirectory)
|
||||
system.moveStorage(to:external)
|
||||
for _ in 0..<300 where system.movingStorage { try await Task.sleep(nanoseconds:20_000_000) }
|
||||
XCTAssertFalse(system.movingStorage);XCTAssertNil(system.storageProgress?.failure)
|
||||
XCTAssertEqual(system.mediaDirectory.standardizedFileURL,external.appendingPathComponent("Media").standardizedFileURL)
|
||||
let moved = try XCTUnwrap(system.songs.first)
|
||||
XCTAssertEqual(moved.id,original.id);XCTAssertFalse(FileManager.default.fileExists(atPath:oldAudio.path))
|
||||
XCTAssertFalse(FileManager.default.fileExists(atPath:originalCache.path))
|
||||
XCTAssertNotNil(try WaveformCache.load(audio:URL(fileURLWithPath:moved.audio),directory:external.appendingPathComponent("Waveforms")))
|
||||
let reopened = DJSystem(storageURL:local)
|
||||
XCTAssertEqual(reopened.waveformDirectory.standardizedFileURL,external.appendingPathComponent("Waveforms").standardizedFileURL)
|
||||
XCTAssertEqual(reopened.songs.first?.audio,moved.audio)
|
||||
XCTAssertTrue(FileManager.default.fileExists(atPath:fixture.path))
|
||||
}
|
||||
func testDJStorageCancelledBeforeTransferKeepsOriginals() throws {
|
||||
let root = FileManager.default.temporaryDirectory.appendingPathComponent(UUID().uuidString)
|
||||
defer { try? FileManager.default.removeItem(at:root) }
|
||||
let local = root.appendingPathComponent("Local"),destination = root.appendingPathComponent("External")
|
||||
try FileManager.default.createDirectory(at:local,withIntermediateDirectories:true)
|
||||
let db = try Library(url:local.appendingPathComponent("Library.sqlite"))
|
||||
let fixture = try XCTUnwrap(Bundle(for:Self.self).resourceURL?.appendingPathComponent("Fixtures/Demo.mp3"))
|
||||
try Importer(media:local.appendingPathComponent("Media"),waveformCache:local.appendingPathComponent("Waveforms")).run([fixture],library:db)
|
||||
let song = try XCTUnwrap(db.songs().first)
|
||||
XCTAssertThrowsError(try DJStorageMove.run(database:local.appendingPathComponent("Library.sqlite"),defaultRoot:local,destination:destination,cancelled:{true}))
|
||||
XCTAssertTrue(FileManager.default.fileExists(atPath:song.audio));XCTAssertNil(try DJStorageMove.location(in:db))
|
||||
}
|
||||
|
||||
func testDJStorageCachePhaseCancellationCanResumeWithoutReanalysis() throws {
|
||||
let root = FileManager.default.temporaryDirectory.appendingPathComponent(UUID().uuidString)
|
||||
defer { try? FileManager.default.removeItem(at:root) }
|
||||
let local = root.appendingPathComponent("Local"),target = root.appendingPathComponent("External")
|
||||
try FileManager.default.createDirectory(at:local,withIntermediateDirectories:true)
|
||||
let database = local.appendingPathComponent("Library.sqlite"),db = try Library(url:database)
|
||||
let fixture = try XCTUnwrap(Bundle(for:Self.self).resourceURL?.appendingPathComponent("Fixtures/Demo.mp3"))
|
||||
try Importer(media:local.appendingPathComponent("Media"),waveformCache:local.appendingPathComponent("Waveforms")).run([fixture],library:db)
|
||||
var cancelled = false
|
||||
XCTAssertThrowsError(try DJStorageMove.run(database:database,defaultRoot:local,destination:target,cancelled:{cancelled},progress:{if $0.current.hasPrefix("Moving waveform") { cancelled = true }}))
|
||||
let resumed = try DJStorageMove.run(database:database,defaultRoot:local,destination:target)
|
||||
XCTAssertTrue(resumed.finished)
|
||||
let song = try XCTUnwrap(db.songs().first)
|
||||
XCTAssertNotNil(try WaveformCache.load(audio:URL(fileURLWithPath:song.audio),directory:target.appendingPathComponent("Waveforms")))
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user