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.
81 lines
3.3 KiB
81 lines
3.3 KiB
import Foundation
|
|
import Testing
|
|
import GRDB
|
|
@testable import Music
|
|
|
|
struct TrackTests {
|
|
// Creates a fresh in-memory database with the tracks table schema.
|
|
// Each test gets its own isolated DatabaseQueue so tests don't share state.
|
|
private static func makeDB() throws -> DatabaseQueue {
|
|
let dbQueue = try DatabaseQueue()
|
|
try dbQueue.write { db in
|
|
try db.create(table: "tracks") { t in
|
|
t.autoIncrementedPrimaryKey("id")
|
|
t.column("fileURL", .text).notNull().unique()
|
|
t.column("title", .text).notNull()
|
|
t.column("artist", .text).notNull()
|
|
t.column("albumArtist", .text).notNull()
|
|
t.column("album", .text).notNull()
|
|
t.column("genre", .text).notNull()
|
|
t.column("year", .integer)
|
|
t.column("trackNumber", .integer)
|
|
t.column("discNumber", .integer)
|
|
t.column("duration", .double).notNull()
|
|
t.column("bpm", .integer)
|
|
t.column("composer", .text).notNull()
|
|
t.column("fileFormat", .text).notNull()
|
|
t.column("bitrate", .integer)
|
|
t.column("sampleRate", .integer)
|
|
t.column("fileSize", .integer).notNull()
|
|
t.column("artworkData", .blob)
|
|
t.column("playCount", .integer).notNull().defaults(to: 0)
|
|
t.column("lastPlayedAt", .datetime)
|
|
t.column("rating", .integer).notNull().defaults(to: 0)
|
|
t.column("dateAdded", .datetime).notNull()
|
|
t.column("dateModified", .datetime).notNull()
|
|
t.column("fileHash", .text).notNull()
|
|
}
|
|
}
|
|
return dbQueue
|
|
}
|
|
|
|
// Verifies that Track can round-trip through GRDB's encoding/decoding,
|
|
// meaning it correctly conforms to FetchableRecord and PersistableRecord.
|
|
@Test func roundTripThroughDatabase() throws {
|
|
let dbQueue = try TrackTests.makeDB()
|
|
try dbQueue.write { db in
|
|
var track = Track.fixture(title: "Bohemian Rhapsody", artist: "Queen")
|
|
try track.insert(db)
|
|
|
|
#expect(track.id != nil)
|
|
|
|
let fetched = try Track.fetchOne(db, key: track.id)
|
|
#expect(fetched?.title == "Bohemian Rhapsody")
|
|
#expect(fetched?.artist == "Queen")
|
|
#expect(fetched?.duration == 210.0)
|
|
}
|
|
}
|
|
|
|
// Verifies that didInsert assigns the auto-incremented ID after insertion.
|
|
@Test func didInsertAssignsId() throws {
|
|
let dbQueue = try TrackTests.makeDB()
|
|
try dbQueue.write { db in
|
|
var track = Track.fixture()
|
|
#expect(track.id == nil)
|
|
try track.insert(db)
|
|
#expect(track.id != nil)
|
|
}
|
|
}
|
|
|
|
// Verifies the fileHash computation produces a deterministic string from size + date.
|
|
@Test func computeHashIsDeterministic() {
|
|
let date = Date(timeIntervalSince1970: 1700000000)
|
|
let hash1 = Track.computeHash(fileSize: 5_000_000, modificationDate: date)
|
|
let hash2 = Track.computeHash(fileSize: 5_000_000, modificationDate: date)
|
|
#expect(hash1 == hash2)
|
|
#expect(hash1 == "5000000_1700000000")
|
|
|
|
let different = Track.computeHash(fileSize: 999, modificationDate: date)
|
|
#expect(different != hash1)
|
|
}
|
|
}
|
|
|