removed unwanted bar now with waveforms, major updates and enhancements

This commit is contained in:
Mark Gregory
2026-11-06 15:21:41 +00:00
parent c39c2bd757
commit bb136ee202
15 changed files with 239 additions and 437 deletions
-59
View File
@@ -3187,64 +3187,5 @@ extension KJamsCloneTests {
XCTAssertLessThan(player.audioContinuity.largestStep,0.08,"Loop handoffs must not introduce a hard sample discontinuity")
}
@MainActor func testAppleMusicAuthorizationAndSubscriptionGuardPlayback() async throws {
guard #available(macOS 14.0, *) else { throw XCTSkip("MusicKit playback requires macOS 14") }
let client = TestAppleMusicClient(),session = AppleMusicSession(client:client)
XCTAssertEqual(client.authorizationRequests,0)
client.granted = .denied;await session.connect()
XCTAssertEqual(session.access,.denied);XCTAssertNotNil(session.error);XCTAssertEqual(client.browseRequests,0)
client.granted = .authorized;client.subscription = false;await session.connect()
for _ in 0..<100 where session.busy { try await Task.sleep(nanoseconds:1_000_000) }
let track = try XCTUnwrap(session.tracks.first)
await session.play(track);XCTAssertTrue(client.played.isEmpty);XCTAssertNotNil(session.error)
client.subscription = true;await session.connect()
for _ in 0..<100 where session.busy { try await Task.sleep(nanoseconds:1_000_000) }
await session.play(track);XCTAssertEqual(client.played,[track.id]);XCTAssertTrue(session.playback.playing)
session.seek(1000);XCTAssertEqual(client.playback.position,track.duration)
session.stop();XCTAssertFalse(session.playback.playing)
}
@MainActor func testAppleMusicSearchRejectsStaleResultsAndPaginatesWithoutDuplicates() async throws {
guard #available(macOS 14.0, *) else { throw XCTSkip("MusicKit playback requires macOS 14") }
let client = TestAppleMusicClient(),session = AppleMusicSession(client:client)
session.query = "slow";session.reload();try await Task.sleep(nanoseconds:5_000_000)
session.query = "latest";session.reload();try await Task.sleep(nanoseconds:150_000_000)
XCTAssertEqual(session.tracks.map(\.id),["latest"])
session.more()
for _ in 0..<100 where session.loadingMore { try await Task.sleep(nanoseconds:1_000_000) }
XCTAssertEqual(session.tracks.map(\.id),["latest","next"]);XCTAssertFalse(session.hasMore);XCTAssertTrue(client.played.isEmpty)
let view = NSHostingView(rootView:AppleMusicBrowser(session:session,hasPlayingDeck:{false},stopDecks:{}).frame(width:1100,height:420))
view.frame = NSRect(x:0,y:0,width:1100,height:420);view.layoutSubtreeIfNeeded()
let bitmap = try XCTUnwrap(view.bitmapImageRepForCachingDisplay(in:view.bounds));view.cacheDisplay(in:view.bounds,to:bitmap)
let png = try XCTUnwrap(bitmap.representation(using:.png,properties:[:]))
XCTContext.runActivity(named:"Apple Music browser layout") { activity in
let attachment = XCTAttachment(data:png,uniformTypeIdentifier:"public.png");attachment.lifetime = .keepAlways;activity.add(attachment)
}
}
}
@available(macOS 14.0, *) @MainActor private final class TestAppleMusicClient: AppleMusicClient {
var access: AppleMusicAccess = .authorized
var granted: AppleMusicAccess = .authorized
var subscription = true
var authorizationRequests = 0,browseRequests = 0
var played = [String]()
var playback = AppleMusicPlayback()
func authorize() async -> AppleMusicAccess { authorizationRequests += 1;access = granted;return granted }
func subscribed() async throws -> Bool { subscription }
func playlists() async throws -> [AppleMusicPlaylist] { [.init(id:"playlist",name:"My playlist")] }
func browse(query: String,playlist: String?,offset: Int) async throws -> AppleMusicPage {
browseRequests += 1
if query == "slow" { try? await Task.sleep(nanoseconds:100_000_000) }
let id = query.isEmpty ? "library" : query
let track = AppleMusicTrack(id:id,title:id,artist:"Artist",album:"Album",duration:180,artwork:nil)
return .init(tracks:offset == 0 ? [track] : [track,.init(id:"next",title:"Next",artist:"Artist",album:"Album",duration:180,artwork:nil)],hasMore:offset == 0)
}
func play(_ id: String) async throws { played.append(id);playback = .init(title:id,artist:"Artist",playing:true,position:0,duration:180) }
func enqueue(_ id: String) async throws { }
func resume() async throws { playback.playing = true }
func pause() { playback.playing = false }
func stop() { playback.playing = false;playback.position = 0 }
func seek(_ seconds: Double) { playback.position = seconds }
func next() async throws { }
}