mirror of
https://github.com/openclaw/openclaw.git
synced 2026-03-12 07:20:45 +00:00
test: add talk config contract fixtures
This commit is contained in:
@@ -0,0 +1,76 @@
|
||||
package ai.openclaw.app.voice
|
||||
|
||||
import java.io.File
|
||||
import kotlinx.serialization.SerialName
|
||||
import kotlinx.serialization.Serializable
|
||||
import kotlinx.serialization.json.Json
|
||||
import kotlinx.serialization.json.JsonObject
|
||||
import kotlinx.serialization.json.JsonPrimitive
|
||||
import org.junit.Assert.assertEquals
|
||||
import org.junit.Assert.assertNotNull
|
||||
import org.junit.Assert.assertNull
|
||||
import org.junit.Test
|
||||
|
||||
@Serializable
|
||||
private data class TalkConfigContractFixture(
|
||||
@SerialName("selectionCases") val selectionCases: List<SelectionCase>,
|
||||
) {
|
||||
@Serializable
|
||||
data class SelectionCase(
|
||||
val id: String,
|
||||
val defaultProvider: String,
|
||||
val payloadValid: Boolean,
|
||||
val expectedSelection: ExpectedSelection? = null,
|
||||
val talk: JsonObject,
|
||||
)
|
||||
|
||||
@Serializable
|
||||
data class ExpectedSelection(
|
||||
val provider: String,
|
||||
val normalizedPayload: Boolean,
|
||||
val voiceId: String? = null,
|
||||
)
|
||||
}
|
||||
|
||||
class TalkModeConfigContractTest {
|
||||
private val json = Json { ignoreUnknownKeys = true }
|
||||
|
||||
@Test
|
||||
fun selectionFixtures() {
|
||||
for (fixture in loadFixtures().selectionCases) {
|
||||
val selection = TalkModeManager.selectTalkProviderConfig(fixture.talk)
|
||||
val expected = fixture.expectedSelection
|
||||
if (expected == null) {
|
||||
assertNull(fixture.id, selection)
|
||||
continue
|
||||
}
|
||||
assertNotNull(fixture.id, selection)
|
||||
assertEquals(fixture.id, expected.provider, selection?.provider)
|
||||
assertEquals(fixture.id, expected.normalizedPayload, selection?.normalizedPayload)
|
||||
assertEquals(
|
||||
fixture.id,
|
||||
expected.voiceId,
|
||||
(selection?.config?.get("voiceId") as? JsonPrimitive)?.content,
|
||||
)
|
||||
assertEquals(fixture.id, true, fixture.payloadValid)
|
||||
}
|
||||
}
|
||||
|
||||
private fun loadFixtures(): TalkConfigContractFixture {
|
||||
val fixturePath = findFixtureFile()
|
||||
return json.decodeFromString(File(fixturePath).readText())
|
||||
}
|
||||
|
||||
private fun findFixtureFile(): String {
|
||||
val startDir = System.getProperty("user.dir") ?: error("user.dir unavailable")
|
||||
var current = File(startDir).absoluteFile
|
||||
while (true) {
|
||||
val candidate = File(current, "test-fixtures/talk-config-contract.json")
|
||||
if (candidate.exists()) {
|
||||
return candidate.absolutePath
|
||||
}
|
||||
current = current.parentFile ?: break
|
||||
}
|
||||
error("talk-config-contract.json not found from $startDir")
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,60 @@
|
||||
import Foundation
|
||||
import OpenClawKit
|
||||
import Testing
|
||||
|
||||
private struct TalkConfigContractFixture: Decodable {
|
||||
let selectionCases: [SelectionCase]
|
||||
|
||||
struct SelectionCase: Decodable {
|
||||
let id: String
|
||||
let defaultProvider: String
|
||||
let payloadValid: Bool
|
||||
let expectedSelection: ExpectedSelection?
|
||||
let talk: [String: AnyCodable]
|
||||
}
|
||||
|
||||
struct ExpectedSelection: Decodable {
|
||||
let provider: String
|
||||
let normalizedPayload: Bool
|
||||
let voiceId: String?
|
||||
}
|
||||
}
|
||||
|
||||
private enum TalkConfigContractFixtureLoader {
|
||||
static func load() throws -> TalkConfigContractFixture {
|
||||
let fixtureURL = try self.findFixtureURL(startingAt: URL(fileURLWithPath: #filePath))
|
||||
let data = try Data(contentsOf: fixtureURL)
|
||||
return try JSONDecoder().decode(TalkConfigContractFixture.self, from: data)
|
||||
}
|
||||
|
||||
private static func findFixtureURL(startingAt fileURL: URL) throws -> URL {
|
||||
var directory = fileURL.deletingLastPathComponent()
|
||||
while directory.path != "/" {
|
||||
let candidate = directory.appendingPathComponent("test-fixtures/talk-config-contract.json")
|
||||
if FileManager.default.fileExists(atPath: candidate.path) {
|
||||
return candidate
|
||||
}
|
||||
directory.deleteLastPathComponent()
|
||||
}
|
||||
throw NSError(domain: "TalkConfigContractFixtureLoader", code: 1)
|
||||
}
|
||||
}
|
||||
|
||||
struct TalkConfigContractTests {
|
||||
@Test func selectionFixtures() throws {
|
||||
for fixture in try TalkConfigContractFixtureLoader.load().selectionCases {
|
||||
let selection = TalkConfigParsing.selectProviderConfig(
|
||||
fixture.talk,
|
||||
defaultProvider: fixture.defaultProvider)
|
||||
if let expected = fixture.expectedSelection {
|
||||
#expect(selection != nil)
|
||||
#expect(selection?.provider == expected.provider)
|
||||
#expect(selection?.normalizedPayload == expected.normalizedPayload)
|
||||
#expect(selection?.config["voiceId"]?.stringValue == expected.voiceId)
|
||||
} else {
|
||||
#expect(selection == nil)
|
||||
}
|
||||
#expect(fixture.payloadValid == (selection != nil))
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user