97 lines
3.8 KiB
Swift
97 lines
3.8 KiB
Swift
import MusicAssistantCore
|
|
import XCTest
|
|
|
|
final class AIServiceTests: XCTestCase {
|
|
func testProviderIndependentServiceGeneratesStructuredProjectResult() async throws {
|
|
let service = MockAIService()
|
|
let request = SongProjectGenerationRequest(
|
|
context: AIRequestContext(
|
|
userInstruction: "Write a hopeful cinematic pop song.",
|
|
conversation: [
|
|
AIConversationMessage(role: .user, content: "Use piano and violin.")
|
|
],
|
|
localeIdentifier: "en_US"
|
|
),
|
|
discussionMode: .discuss
|
|
)
|
|
|
|
let result = try await service.generateSongProject(from: request)
|
|
|
|
XCTAssertEqual(result.project.title, "Generated Song")
|
|
XCTAssertEqual(result.project.idea, request.context.userInstruction)
|
|
XCTAssertEqual(result.project.conversationMode, .discuss)
|
|
XCTAssertEqual(result.notes, ["Generated by a provider-independent mock."])
|
|
XCTAssertEqual(result.followUpQuestions, ["Should the chorus be bigger?"])
|
|
}
|
|
|
|
func testProviderIndependentServiceRevisesLyricsWithStructuredResult() async throws {
|
|
let service = MockAIService()
|
|
let project = SongProject(title: "Lyric Project", idea: "Improve words")
|
|
let sourceLyrics = Lyrics(text: "rough draft")
|
|
let request = LyricsRevisionRequest(
|
|
context: AIRequestContext(userInstruction: "Make it stronger."),
|
|
project: project,
|
|
sourceLyrics: sourceLyrics,
|
|
mode: .improve
|
|
)
|
|
|
|
let result = try await service.reviseLyrics(from: request)
|
|
|
|
XCTAssertEqual(result.lyrics.text, "rough draft\nMake it stronger.")
|
|
XCTAssertEqual(result.notes, ["improve"])
|
|
}
|
|
|
|
func testProviderIndependentServiceProposesScopedProjectUpdates() async throws {
|
|
let service = MockAIService()
|
|
let project = SongProject(title: "Scoped Project", idea: "Add tempo")
|
|
let request = SongProjectUpdateRequest(
|
|
context: AIRequestContext(userInstruction: "Set tempo manually."),
|
|
project: project,
|
|
allowedScopes: [.musicalParameters]
|
|
)
|
|
|
|
let result = try await service.proposeProjectUpdate(from: request)
|
|
|
|
XCTAssertEqual(result.project.bpm, ManualAutoValue(mode: .manual, value: 96))
|
|
XCTAssertEqual(result.changedScopes, [.musicalParameters])
|
|
XCTAssertEqual(result.notes, ["Updated only requested scopes."])
|
|
}
|
|
}
|
|
|
|
private struct MockAIService: AIService {
|
|
func generateSongProject(from request: SongProjectGenerationRequest) async throws -> SongProjectGenerationResult {
|
|
SongProjectGenerationResult(
|
|
project: SongProject(
|
|
title: "Generated Song",
|
|
idea: request.context.userInstruction,
|
|
conversationMode: request.discussionMode
|
|
),
|
|
notes: ["Generated by a provider-independent mock."],
|
|
followUpQuestions: ["Should the chorus be bigger?"]
|
|
)
|
|
}
|
|
|
|
func reviseLyrics(from request: LyricsRevisionRequest) async throws -> LyricsRevisionResult {
|
|
LyricsRevisionResult(
|
|
lyrics: Lyrics(text: "\(request.sourceLyrics.text)\n\(request.context.userInstruction)"),
|
|
notes: [request.mode.rawValue]
|
|
)
|
|
}
|
|
|
|
func proposeProjectUpdate(from request: SongProjectUpdateRequest) async throws -> SongProjectUpdateResult {
|
|
var project = request.project
|
|
var changedScopes: [SongProjectUpdateScope] = []
|
|
|
|
if request.allowedScopes.contains(.musicalParameters) {
|
|
project.setBPMManually(96)
|
|
changedScopes.append(.musicalParameters)
|
|
}
|
|
|
|
return SongProjectUpdateResult(
|
|
project: project,
|
|
changedScopes: changedScopes,
|
|
notes: ["Updated only requested scopes."]
|
|
)
|
|
}
|
|
}
|