removed unwanted bar now with waveforms, major updates and enhancements
This commit is contained in:
@@ -2358,7 +2358,10 @@ extension KJamsCloneTests {
|
||||
}
|
||||
model.dj.automix.enqueue([song,song]);try await selectTab(1)
|
||||
let libraryScroll = try XCTUnwrap(descendants(host).compactMap{$0 as? NSScrollView}.filter{$0.bounds.width > 600 && !$0.isHiddenOrHasHiddenAncestor}.max(by:{$0.bounds.height < $1.bounds.height}))
|
||||
XCTAssertGreaterThan(libraryScroll.bounds.height,380,"DJ library grows into the remaining workspace height")
|
||||
XCTAssertGreaterThan(libraryScroll.bounds.height,250,"The resizable DJ library retains a useful track viewport")
|
||||
let libraryFrame = libraryScroll.convert(libraryScroll.bounds,to:host)
|
||||
if host.isFlipped { XCTAssertGreaterThan(libraryFrame.maxY,host.bounds.maxY-50,"The library fills the bottom of the workspace") }
|
||||
else { XCTAssertLessThan(libraryFrame.minY,host.bounds.minY+50,"The library fills the bottom of the workspace") }
|
||||
if let rep = host.bitmapImageRepForCachingDisplay(in:host.bounds) { host.cacheDisplay(in:host.bounds,to:rep);try XCTUnwrap(rep.representation(using:.png,properties:[:])).write(to:URL(fileURLWithPath:"/private/tmp/kjmix-xml-mappings/dj-tab.png")) }
|
||||
try await selectTab(0)
|
||||
if let rep = host.bitmapImageRepForCachingDisplay(in:host.bounds) { host.cacheDisplay(in:host.bounds,to:rep);try XCTUnwrap(rep.representation(using:.png,properties:[:])).write(to:URL(fileURLWithPath:"/private/tmp/kjmix-xml-mappings/karaoke-tab.png")) }
|
||||
@@ -3189,3 +3192,57 @@ extension KJamsCloneTests {
|
||||
|
||||
|
||||
}
|
||||
|
||||
extension KJamsCloneTests {
|
||||
func testDJCollectionsCombineSearchRatingsAndPlaylistOrder() {
|
||||
let tracks = [
|
||||
Song(id:1,title:"Track 10",audio:"/music/10.mp3",cdg:nil,rating:5,plays:0,artist:"Northbound",album:"Night"),
|
||||
Song(id:2,title:"Track 2",audio:"/music/2.mp3",cdg:nil,rating:0,plays:0,artist:"Mira Vale",album:"Night"),
|
||||
Song(id:3,title:"Track 1",audio:"/music/1.mp3",cdg:nil,rating:4,plays:0,artist:"")
|
||||
]
|
||||
XCTAssertEqual(DJLibraryBrowser.rows(tracks,collection:.all,favourites:[]).map(\.id),[3,2,1],"Titles use natural numeric ordering")
|
||||
XCTAssertEqual(DJLibraryBrowser.rows(tracks,collection:.rated,favourites:[],query:"Northbound").map(\.id),[1])
|
||||
XCTAssertEqual(DJLibraryBrowser.rows(tracks,collection:.favourites,favourites:[2],query:"Night").map(\.id),[2])
|
||||
XCTAssertEqual(DJLibraryBrowser.rows(tracks,collection:.missingArtist,favourites:[]).map(\.id),[3])
|
||||
XCTAssertEqual(DJLibraryBrowser.rows(tracks,collection:.unrated,favourites:[]).map(\.id),[2])
|
||||
XCTAssertEqual(DJLibraryBrowser.rows(tracks,collection:.all,favourites:[],playlist:[2,1,99,3],sort:.source).map(\.id),[2,1,3],"Playlist order is retained; missing rows are ignored")
|
||||
XCTAssertEqual(DJLibraryBrowser.rows(tracks,collection:.all,favourites:[],sort:.rating,ascending:false).map(\.id),[1,3,2])
|
||||
XCTAssertEqual(DJLibraryBrowser.rows(Array(tracks.reversed()),collection:.all,favourites:[],sort:.source).map(\.id),[1,2,3],"Import order follows stable database IDs, not the prior display sort")
|
||||
}
|
||||
@MainActor func testRedesignedDJWorkspaceAtCompactAndWideSizes() async throws {
|
||||
let root = FileManager.default.temporaryDirectory.appendingPathComponent("KJMix-DJ-Design-"+UUID().uuidString)
|
||||
try FileManager.default.createDirectory(at:root,withIntermediateDirectories:true)
|
||||
let system = DJSystem(storageURL:root.appendingPathComponent("Library"))
|
||||
defer { system.a.player.stop();system.b.player.stop();system.preview.stop() }
|
||||
let library = try XCTUnwrap(system.library)
|
||||
let fixture = try XCTUnwrap(Bundle(for:Self.self).resourceURL?.appendingPathComponent("Fixtures/Demo.mp3"))
|
||||
let titles = ["Night Transit","Glass City","After Hours","Satellite","Deep Blue","Into the Light","Parallel Lines","Last Train"]
|
||||
for (index,title) in titles.enumerated() {
|
||||
let url = root.appendingPathComponent("Track-\(index).mp3");try FileManager.default.copyItem(at:fixture,to:url)
|
||||
let id = try library.add(title:title,audio:url.path,cdg:nil,artist:index.isMultiple(of:2) ? "Northbound" : "Mira Vale",album:"Night Sessions",duration:180+Double(index*12))
|
||||
try library.rate(id,index.isMultiple(of:3) ? 5 : 3)
|
||||
}
|
||||
try system.refresh();system.createPlaylist("Opening Set");system.createPlaylist("Late Night")
|
||||
if let list = system.playlists.first { for song in system.songs.prefix(3) { system.addToPlaylist(list.id,song:song.id) } }
|
||||
system.toggleFavourite(try XCTUnwrap(system.songs.first?.id))
|
||||
system.load(system.songs[0],into:"A");system.load(system.songs[1],into:"B")
|
||||
system.a.bpm = 120;system.a.bpmConfirmed = true;system.b.bpm = 124;system.b.bpmConfirmed = true
|
||||
for _ in 0..<100 where system.a.player.waveformLoading || system.b.player.waveformLoading { try await Task.sleep(nanoseconds:20_000_000) }
|
||||
for size in [CGSize(width:1320,height:900),CGSize(width:1060,height:760)] {
|
||||
let view = NSHostingView(rootView:DJConsole(system:system).frame(width:size.width,height:size.height).preferredColorScheme(.dark))
|
||||
view.frame = NSRect(origin:.zero,size:size)
|
||||
let window = NSWindow(contentRect:view.frame,styleMask:[.borderless],backing:.buffered,defer:false)
|
||||
window.contentView = view;window.appearance = NSAppearance(named:.darkAqua);window.setFrameOrigin(NSPoint(x:-10000,y:-10000));window.orderFront(nil)
|
||||
try await Task.sleep(nanoseconds:250_000_000);view.layoutSubtreeIfNeeded()
|
||||
let rep = try XCTUnwrap(view.bitmapImageRepForCachingDisplay(in:view.bounds));view.cacheDisplay(in:view.bounds,to:rep)
|
||||
let png = try XCTUnwrap(rep.representation(using:.png,properties:[:]))
|
||||
let path = root.appendingPathComponent("DJ-Studio-\(Int(size.width)).png");try png.write(to:path)
|
||||
print("DJ_DESIGN_CAPTURE \(path.path)")
|
||||
XCTContext.runActivity(named:"DJ Studio \(Int(size.width)) layout") { activity in
|
||||
let capture = XCTAttachment(data:png,uniformTypeIdentifier:"public.png");capture.lifetime = .keepAlways;activity.add(capture)
|
||||
}
|
||||
XCTAssertFalse(system.a.player.playing);XCTAssertFalse(system.b.player.playing)
|
||||
window.orderOut(nil);window.contentView = nil
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user