You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
82 lines
3.8 KiB
82 lines
3.8 KiB
import Foundation
|
|
import Testing
|
|
@testable import Music
|
|
|
|
// Verifies the pure single/multi-track edit logic: extraction, change detection,
|
|
// shared-vs-mixed across many tracks, and applying only edited fields.
|
|
struct EditableTrackFieldsTests {
|
|
@Test func initCopiesEditableValues() {
|
|
// Step 1: build fields from a fixture track.
|
|
let t = Track.fixture(title: "A", artist: "B", album: "C", year: 2001, rating: 3)
|
|
let f = EditableTrackFields(from: t)
|
|
// Step 2: editable values match.
|
|
#expect(f.title == "A"); #expect(f.artist == "B")
|
|
#expect(f.album == "C"); #expect(f.year == 2001); #expect(f.rating == 3)
|
|
}
|
|
|
|
@Test func changedFieldsDetectsOnlyDifferences() {
|
|
// Step 1: two field sets differing only in genre + bpm.
|
|
let a = EditableTrackFields(from: .fixture(genre: "Rock", bpm: 120))
|
|
var b = a; b.genre = "Jazz"; b.bpm = 90
|
|
// Step 2: change set is exactly {genre, bpm}.
|
|
#expect(a.changedFields(to: b) == [.genre, .bpm])
|
|
}
|
|
|
|
@Test func sharedMarksDifferingFieldsMixed() {
|
|
// Step 1: two tracks share artist but differ in genre.
|
|
let t1 = Track.fixture(artist: "Same", genre: "Rock")
|
|
let t2 = Track.fixture(artist: "Same", genre: "Pop")
|
|
// Step 2: shared() returns common artist and flags genre as mixed.
|
|
let (values, mixed) = EditableTrackFields.shared(across: [t1, t2])
|
|
#expect(values.artist == "Same")
|
|
#expect(mixed.contains(.genre))
|
|
#expect(!mixed.contains(.artist))
|
|
}
|
|
|
|
@Test func sharedAcrossThreeTracksAccumulatesMixed() {
|
|
// Step 1: three tracks all share the same album, but title differs on the
|
|
// third track and genre differs on the second — so both title and
|
|
// genre must end up "mixed", while album stays shared.
|
|
let t1 = Track.fixture(title: "Same", album: "One Album", genre: "Rock")
|
|
let t2 = Track.fixture(title: "Same", album: "One Album", genre: "Pop")
|
|
let t3 = Track.fixture(title: "Different", album: "One Album", genre: "Rock")
|
|
// Step 2: shared() over all three.
|
|
let (values, mixed) = EditableTrackFields.shared(across: [t1, t2, t3])
|
|
// Step 3: album is shared (not mixed); title + genre are mixed.
|
|
#expect(values.album == "One Album")
|
|
#expect(!mixed.contains(.album))
|
|
#expect(mixed.contains(.title))
|
|
#expect(mixed.contains(.genre))
|
|
}
|
|
|
|
@Test func applyOnlyWritesEditedFields() {
|
|
// Step 1: a track and a fields object that changes album only.
|
|
let t = Track.fixture(album: "Old", genre: "Rock")
|
|
var f = EditableTrackFields(from: t); f.album = "New"; f.genre = "IGNORED"
|
|
// Step 2: applying with editing={.album} changes album, leaves genre.
|
|
let out = f.apply(editing: [.album], to: t)
|
|
#expect(out.album == "New")
|
|
#expect(out.genre == "Rock")
|
|
}
|
|
|
|
@Test func applyEmptyEditSetReturnsUnchanged() {
|
|
let t = Track.fixture(title: "Keep")
|
|
let f = EditableTrackFields(from: t)
|
|
#expect(f.apply(editing: [], to: t) == t)
|
|
}
|
|
|
|
@Test func dateAddedIsEditable() {
|
|
// Step 1: a track with a known dateAdded; init copies it.
|
|
let original = Date(timeIntervalSince1970: 1_000_000)
|
|
let t = Track.fixture(dateAdded: original)
|
|
var f = EditableTrackFields(from: t)
|
|
#expect(f.dateAdded == original)
|
|
// Step 2: changing dateAdded is detected as the only changed field.
|
|
let newDate = Date(timeIntervalSince1970: 2_000_000)
|
|
f.dateAdded = newDate
|
|
#expect(EditableTrackFields(from: t).changedFields(to: f) == [.dateAdded])
|
|
// Step 3: applying with editing={.dateAdded} writes the new date onto the track.
|
|
let out = f.apply(editing: [.dateAdded], to: t)
|
|
#expect(out.dateAdded == newDate)
|
|
}
|
|
}
|
|
|