139 lines
5.3 KiB
Swift
139 lines
5.3 KiB
Swift
import Foundation
|
|
import XCTest
|
|
@testable import TranslatorPlugin
|
|
|
|
@MainActor
|
|
final class OpenAICompatibleConfigurationTests: XCTestCase {
|
|
func testDefaultValues() {
|
|
let configuration = OpenAICompatibleConfiguration()
|
|
|
|
XCTAssertEqual(configuration.baseURL, "https://api.openai.com")
|
|
XCTAssertEqual(configuration.model, "gpt-5.4-mini")
|
|
XCTAssertTrue(configuration.promptTemplate.contains("{{source_language}}"))
|
|
XCTAssertTrue(configuration.promptTemplate.contains("{{target_language}}"))
|
|
XCTAssertTrue(configuration.promptTemplate.contains("{{text}}"))
|
|
}
|
|
|
|
func testEndpointAppendsChatCompletionsPath() throws {
|
|
let configuration = OpenAICompatibleConfiguration(baseURL: "https://api.openai.com")
|
|
|
|
XCTAssertEqual(
|
|
try configuration.endpointURL().absoluteString,
|
|
"https://api.openai.com/v1/chat/completions"
|
|
)
|
|
}
|
|
|
|
func testEndpointDoesNotDuplicateV1Path() throws {
|
|
let configuration = OpenAICompatibleConfiguration(baseURL: "https://gateway.example.com/v1/")
|
|
|
|
XCTAssertEqual(
|
|
try configuration.endpointURL().absoluteString,
|
|
"https://gateway.example.com/v1/chat/completions"
|
|
)
|
|
}
|
|
|
|
func testEndpointKeepsFullChatCompletionsPath() throws {
|
|
let configuration = OpenAICompatibleConfiguration(
|
|
baseURL: "https://gateway.example.com/openai/v1/chat/completions"
|
|
)
|
|
|
|
XCTAssertEqual(
|
|
try configuration.endpointURL().absoluteString,
|
|
"https://gateway.example.com/openai/v1/chat/completions"
|
|
)
|
|
}
|
|
|
|
func testEndpointKeepsProviderSpecificChatCompletionsPath() throws {
|
|
let configuration = OpenAICompatibleConfiguration(
|
|
baseURL: "https://open.bigmodel.cn/api/paas/v4/chat/completions"
|
|
)
|
|
|
|
XCTAssertEqual(
|
|
try configuration.endpointURL().absoluteString,
|
|
"https://open.bigmodel.cn/api/paas/v4/chat/completions"
|
|
)
|
|
}
|
|
|
|
func testPromptTemplateMissingTextIsInvalidWithExactMessage() {
|
|
let configuration = OpenAICompatibleConfiguration(promptTemplate: "翻译 {{source_language}} 到 {{target_language}}")
|
|
|
|
XCTAssertEqual(configuration.validationError?.localizedDescription, "提示词必须包含 {{text}}。")
|
|
}
|
|
|
|
func testBlankBaseURLIsInvalidWithExactMessage() {
|
|
let configuration = OpenAICompatibleConfiguration(baseURL: " \n ")
|
|
|
|
XCTAssertEqual(configuration.validationError?.localizedDescription, "Base URL 不能为空。")
|
|
}
|
|
|
|
func testMissingHostIsInvalidWithExactMessage() {
|
|
let configurations = [
|
|
OpenAICompatibleConfiguration(baseURL: "https:///v1"),
|
|
OpenAICompatibleConfiguration(baseURL: "not-a-url"),
|
|
]
|
|
|
|
for configuration in configurations {
|
|
XCTAssertEqual(configuration.validationError?.localizedDescription, "Base URL 无效。")
|
|
}
|
|
}
|
|
|
|
func testUnsupportedSchemeIsInvalidWithExactMessage() {
|
|
let configuration = OpenAICompatibleConfiguration(baseURL: "ftp://example.com")
|
|
|
|
XCTAssertEqual(configuration.validationError?.localizedDescription, "Base URL 无效。")
|
|
}
|
|
|
|
func testRemoteHTTPBaseURLIsInvalidWithExactMessage() {
|
|
let configuration = OpenAICompatibleConfiguration(baseURL: "http://gateway.example.com")
|
|
|
|
XCTAssertEqual(configuration.validationError?.localizedDescription, "Base URL 无效。")
|
|
}
|
|
|
|
func testLoopbackHTTPBaseURLIsAllowedForLocalGateways() throws {
|
|
let configurations = [
|
|
OpenAICompatibleConfiguration(baseURL: "http://localhost:11434"),
|
|
OpenAICompatibleConfiguration(baseURL: "http://127.0.0.1:11434"),
|
|
OpenAICompatibleConfiguration(baseURL: "http://[::1]:11434"),
|
|
]
|
|
|
|
for configuration in configurations {
|
|
XCTAssertNil(configuration.validationError)
|
|
XCTAssertTrue(try configuration.endpointURL().absoluteString.contains("/v1/chat/completions"))
|
|
}
|
|
}
|
|
|
|
func testWhitespaceOnlyModelIsInvalidWithExactMessage() {
|
|
let configuration = OpenAICompatibleConfiguration(model: " \n\t ")
|
|
|
|
XCTAssertEqual(configuration.validationError?.localizedDescription, "模型不能为空。")
|
|
}
|
|
|
|
func testEndpointThrowsValidationErrorForBlankModel() {
|
|
let configuration = OpenAICompatibleConfiguration(
|
|
baseURL: "https://gateway.example.com",
|
|
model: " \n\t ",
|
|
promptTemplate: "{{text}}"
|
|
)
|
|
|
|
XCTAssertThrowsError(try configuration.endpointURL()) { error in
|
|
XCTAssertEqual(error as? OpenAICompatibleConfigurationError, .blankModel)
|
|
}
|
|
}
|
|
|
|
func testSaveTrimsBaseURLAndModelButPreservesPromptTemplate() {
|
|
let storage = TranslatorInMemoryPluginStorage()
|
|
let promptTemplate = " 翻译:{{text}} "
|
|
let configuration = OpenAICompatibleConfiguration(
|
|
baseURL: " https://gateway.example.com/v1/ ",
|
|
model: " gpt-test ",
|
|
promptTemplate: promptTemplate
|
|
)
|
|
|
|
configuration.save(to: storage)
|
|
|
|
XCTAssertEqual(storage.string(forKey: "translator.openai.base-url"), "https://gateway.example.com/v1/")
|
|
XCTAssertEqual(storage.string(forKey: "translator.openai.model"), "gpt-test")
|
|
XCTAssertEqual(storage.string(forKey: "translator.openai.prompt-template"), promptTemplate)
|
|
}
|
|
}
|