TestHelpers.swift 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778
  1. import AVFoundation
  2. import Foundation
  3. /// Helpers for creating test audio files and SwiftData contexts.
  4. enum TestHelpers {
  5. /// Create a short sine wave WAV file for testing.
  6. static func createTestAudioFile(
  7. name: String = "test_audio",
  8. duration: TimeInterval = 2.0,
  9. sampleRate: Double = 44100,
  10. frequency: Double = 440,
  11. in directory: URL? = nil
  12. ) throws -> URL {
  13. let dir = directory ?? FileManager.default.temporaryDirectory
  14. .appendingPathComponent("MixBoardTests/\(UUID().uuidString)", isDirectory: true)
  15. try FileManager.default.createDirectory(at: dir, withIntermediateDirectories: true)
  16. let url = dir.appendingPathComponent("\(name)_\(UUID().uuidString.prefix(8)).wav")
  17. let channels: AVAudioChannelCount = 2
  18. // Use standard format which AVAudioFile handles correctly
  19. guard let format = AVAudioFormat(standardFormatWithSampleRate: sampleRate, channels: channels) else {
  20. throw NSError(domain: "TestHelpers", code: 1, userInfo: [NSLocalizedDescriptionKey: "Failed to create format"])
  21. }
  22. let file = try AVAudioFile(forWriting: url, settings: format.settings)
  23. let frameCount = AVAudioFrameCount(duration * sampleRate)
  24. guard let buffer = AVAudioPCMBuffer(pcmFormat: file.processingFormat, frameCapacity: frameCount) else {
  25. throw NSError(domain: "TestHelpers", code: 1, userInfo: [NSLocalizedDescriptionKey: "Failed to create buffer"])
  26. }
  27. buffer.frameLength = frameCount
  28. if let channelData = buffer.floatChannelData {
  29. for frame in 0..<Int(frameCount) {
  30. let value = Float(sin(2.0 * .pi * frequency * Double(frame) / sampleRate))
  31. for ch in 0..<Int(channels) {
  32. channelData[ch][frame] = value * 0.5
  33. }
  34. }
  35. }
  36. try file.write(from: buffer)
  37. return url
  38. }
  39. /// Create multiple test audio files with different "metadata".
  40. static func createTestAudioFiles(count: Int, duration: TimeInterval = 1.0) throws -> [URL] {
  41. let frequencies = [261.63, 293.66, 329.63, 349.23, 392.00, 440.00, 493.88, 523.25]
  42. var urls: [URL] = []
  43. for i in 0..<count {
  44. let freq = frequencies[i % frequencies.count]
  45. let url = try createTestAudioFile(
  46. name: "test_track_\(i + 1)",
  47. duration: duration,
  48. frequency: freq
  49. )
  50. urls.append(url)
  51. }
  52. return urls
  53. }
  54. /// Clean up test files.
  55. static func cleanupTestFiles() {
  56. let dir = FileManager.default.temporaryDirectory
  57. .appendingPathComponent("MixBoardTests", isDirectory: true)
  58. try? FileManager.default.removeItem(at: dir)
  59. }
  60. /// Get the test files directory.
  61. static var testDirectory: URL {
  62. FileManager.default.temporaryDirectory
  63. .appendingPathComponent("MixBoardTests", isDirectory: true)
  64. }
  65. }