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.
 
 
Music/MusicTests/TrackTests.swift

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)
}
}