Skip to content

Commit 9493906

Browse files
Expand OpenAI model regression coverage
Add data-driven tests around OpenAI and compat model handling, including GPT-5 token parameter selection, mapped model values, and provider boundary behavior. Also extend predicate and model-name conversion coverage across completion, Claude, OpenRouter, and AI/ML model-key groups so future config and mapping regressions fail deterministically.
1 parent d523354 commit 9493906

File tree

4 files changed

+342
-83
lines changed

4 files changed

+342
-83
lines changed

tests/unit/config/config-predicates.test.mjs

Lines changed: 91 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,11 @@ import { afterEach, beforeEach, describe, test } from 'node:test'
33
import {
44
getNavigatorLanguage,
55
getPreferredLanguageKey,
6+
chatgptApiModelKeys,
7+
gptApiModelKeys,
8+
claudeApiModelKeys,
9+
openRouterApiModelKeys,
10+
aimlApiModelKeys,
611
isUsingAimlApiModel,
712
isUsingAzureOpenAiApiModel,
813
isUsingBingWebModel,
@@ -19,9 +24,28 @@ import {
1924
isUsingMultiModeModel,
2025
isUsingOllamaApiModel,
2126
isUsingOpenAiApiModel,
27+
isUsingGptCompletionApiModel,
2228
isUsingOpenRouterApiModel,
2329
} from '../../../src/config/index.mjs'
2430

31+
const representativeChatgptApiModelNames = [
32+
'chatgptApi4oMini',
33+
'chatgptApi5',
34+
'chatgptApi5_1',
35+
'chatgptApi5_2',
36+
'chatgptApi5_4',
37+
]
38+
const representativeGptCompletionApiModelNames = ['gptApiInstruct']
39+
const representativeClaudeApiModelNames = ['claude37SonnetApi', 'claudeOpus4Api']
40+
const representativeOpenRouterApiModelNames = [
41+
'openRouter_anthropic_claude_sonnet4',
42+
'openRouter_openai_o3',
43+
]
44+
const representativeAimlApiModelNames = [
45+
'aiml_claude_3_7_sonnet_20250219',
46+
'aiml_openai_o3_2025_04_16',
47+
]
48+
2549
const originalNavigatorDescriptor = Object.getOwnPropertyDescriptor(globalThis, 'navigator')
2650

2751
const restoreNavigator = () => {
@@ -63,24 +87,51 @@ test('getNavigatorLanguage treats zh-Hant locale as zhHant', () => {
6387
assert.equal(getNavigatorLanguage(), 'zhHant')
6488
})
6589

66-
test('isUsingChatgptApiModel detects chatgpt API models and excludes custom model', () => {
67-
assert.equal(isUsingChatgptApiModel({ modelName: 'chatgptApi4oMini' }), true)
68-
assert.equal(isUsingChatgptApiModel({ modelName: 'chatgptApi5' }), true)
69-
assert.equal(isUsingChatgptApiModel({ modelName: 'chatgptApi5_1' }), true)
70-
assert.equal(isUsingChatgptApiModel({ modelName: 'chatgptApi5_2' }), true)
71-
assert.equal(isUsingChatgptApiModel({ modelName: 'chatgptApi5_4' }), true)
90+
test('isUsingChatgptApiModel matches representative chatgpt API keys', () => {
91+
for (const modelName of representativeChatgptApiModelNames) {
92+
assert.equal(isUsingChatgptApiModel({ modelName }), true)
93+
}
7294
assert.equal(isUsingChatgptApiModel({ modelName: 'customModel' }), false)
7395
})
7496

75-
test('isUsingOpenAiApiModel accepts both chat and completion API model groups', () => {
76-
assert.equal(isUsingOpenAiApiModel({ modelName: 'chatgptApi4oMini' }), true)
77-
assert.equal(isUsingOpenAiApiModel({ modelName: 'gptApiInstruct' }), true)
97+
test('isUsingChatgptApiModel accepts exported chatgpt API model keys', () => {
98+
for (const modelName of chatgptApiModelKeys) {
99+
assert.equal(isUsingChatgptApiModel({ modelName }), true)
100+
}
78101
})
79102

80-
test('isUsingOpenAiApiModel excludes custom model', () => {
103+
test('isUsingOpenAiApiModel matches representative chat and completion API keys', () => {
104+
for (const modelName of representativeChatgptApiModelNames) {
105+
assert.equal(isUsingOpenAiApiModel({ modelName }), true)
106+
}
107+
for (const modelName of representativeGptCompletionApiModelNames) {
108+
assert.equal(isUsingOpenAiApiModel({ modelName }), true)
109+
}
81110
assert.equal(isUsingOpenAiApiModel({ modelName: 'customModel' }), false)
82111
})
83112

113+
test('isUsingOpenAiApiModel accepts exported chat and completion API model groups', () => {
114+
for (const modelName of chatgptApiModelKeys) {
115+
assert.equal(isUsingOpenAiApiModel({ modelName }), true)
116+
}
117+
for (const modelName of gptApiModelKeys) {
118+
assert.equal(isUsingOpenAiApiModel({ modelName }), true)
119+
}
120+
})
121+
122+
test('isUsingGptCompletionApiModel matches representative completion API keys', () => {
123+
for (const modelName of representativeGptCompletionApiModelNames) {
124+
assert.equal(isUsingGptCompletionApiModel({ modelName }), true)
125+
}
126+
assert.equal(isUsingGptCompletionApiModel({ modelName: 'chatgptApi4oMini' }), false)
127+
})
128+
129+
test('isUsingGptCompletionApiModel accepts exported completion API model keys', () => {
130+
for (const modelName of gptApiModelKeys) {
131+
assert.equal(isUsingGptCompletionApiModel({ modelName }), true)
132+
}
133+
})
134+
84135
test('isUsingCustomModel works with modelName and apiMode forms', () => {
85136
assert.equal(isUsingCustomModel({ modelName: 'customModel' }), true)
86137

@@ -116,12 +167,19 @@ test('isUsingGeminiWebModel detects bard/gemini web models', () => {
116167
assert.equal(isUsingGeminiWebModel({ modelName: 'chatgptFree35' }), false)
117168
})
118169

119-
test('isUsingClaudeApiModel detects Claude API models', () => {
120-
assert.equal(isUsingClaudeApiModel({ modelName: 'claude37SonnetApi' }), true)
121-
assert.equal(isUsingClaudeApiModel({ modelName: 'claudeOpus4Api' }), true)
170+
test('isUsingClaudeApiModel matches representative Claude API keys', () => {
171+
for (const modelName of representativeClaudeApiModelNames) {
172+
assert.equal(isUsingClaudeApiModel({ modelName }), true)
173+
}
122174
assert.equal(isUsingClaudeApiModel({ modelName: 'claude2WebFree' }), false)
123175
})
124176

177+
test('isUsingClaudeApiModel accepts exported Claude API model keys', () => {
178+
for (const modelName of claudeApiModelKeys) {
179+
assert.equal(isUsingClaudeApiModel({ modelName }), true)
180+
}
181+
})
182+
125183
test('isUsingMoonshotApiModel detects moonshot API models', () => {
126184
assert.equal(isUsingMoonshotApiModel({ modelName: 'moonshot_v1_8k' }), true)
127185
assert.equal(isUsingMoonshotApiModel({ modelName: 'moonshot_k2' }), true)
@@ -134,20 +192,32 @@ test('isUsingDeepSeekApiModel detects DeepSeek models', () => {
134192
assert.equal(isUsingDeepSeekApiModel({ modelName: 'chatgptApi4oMini' }), false)
135193
})
136194

137-
test('isUsingOpenRouterApiModel detects OpenRouter models', () => {
138-
assert.equal(
139-
isUsingOpenRouterApiModel({ modelName: 'openRouter_anthropic_claude_sonnet4' }),
140-
true,
141-
)
142-
assert.equal(isUsingOpenRouterApiModel({ modelName: 'openRouter_openai_o3' }), true)
195+
test('isUsingOpenRouterApiModel matches representative OpenRouter API keys', () => {
196+
for (const modelName of representativeOpenRouterApiModelNames) {
197+
assert.equal(isUsingOpenRouterApiModel({ modelName }), true)
198+
}
143199
assert.equal(isUsingOpenRouterApiModel({ modelName: 'chatgptApi4oMini' }), false)
144200
})
145201

146-
test('isUsingAimlApiModel detects AI/ML models', () => {
147-
assert.equal(isUsingAimlApiModel({ modelName: 'aiml_claude_3_7_sonnet_20250219' }), true)
202+
test('isUsingOpenRouterApiModel accepts exported OpenRouter API model keys', () => {
203+
for (const modelName of openRouterApiModelKeys) {
204+
assert.equal(isUsingOpenRouterApiModel({ modelName }), true)
205+
}
206+
})
207+
208+
test('isUsingAimlApiModel matches representative AI/ML API keys', () => {
209+
for (const modelName of representativeAimlApiModelNames) {
210+
assert.equal(isUsingAimlApiModel({ modelName }), true)
211+
}
148212
assert.equal(isUsingAimlApiModel({ modelName: 'chatgptApi4oMini' }), false)
149213
})
150214

215+
test('isUsingAimlApiModel accepts exported AI/ML model keys', () => {
216+
for (const modelName of aimlApiModelKeys) {
217+
assert.equal(isUsingAimlApiModel({ modelName }), true)
218+
}
219+
})
220+
151221
test('isUsingChatGLMApiModel detects ChatGLM models', () => {
152222
assert.equal(isUsingChatGLMApiModel({ modelName: 'chatglmTurbo' }), true)
153223
assert.equal(isUsingChatGLMApiModel({ modelName: 'chatglm4' }), true)

0 commit comments

Comments
 (0)