Skip to content

Commit a548ea3

Browse files
EAGzzyCSLquanru
andauthored
fix(shared): fix getGlobalConfig (#1043)
* fix(shared): fix getGlobalConfig * test(shared): add tests for overrideConfig * fix(shared): fix ut * fix(shared): fix lint --------- Co-authored-by: quanruzhuoxiu <[email protected]>
1 parent 99cb310 commit a548ea3

File tree

3 files changed

+233
-5
lines changed

3 files changed

+233
-5
lines changed

packages/core/tests/unit-test/env.test.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ describe('env', () => {
1919

2020
// clean up before each test
2121
beforeEach(() => {
22+
globalThis.midsceneGlobalConfigOverride = null;
2223
// reset to empty object, avoid interference between tests
2324
overrideAIConfig({}, false);
2425
});

packages/shared/src/env.ts

Lines changed: 25 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,9 @@
11
declare global {
22
var midsceneGlobalConfig: Partial<ReturnType<typeof allConfigFromEnv>> | null;
3+
var midsceneGlobalConfigOverride: {
4+
newConfig?: Partial<ReturnType<typeof allConfigFromEnv>>;
5+
extendMode?: boolean;
6+
} | null;
37
}
48

59
// config keys
@@ -139,6 +143,16 @@ const getGlobalConfig = () => {
139143
if (!globalThis.midsceneGlobalConfig) {
140144
globalThis.midsceneGlobalConfig = allConfigFromEnv();
141145
}
146+
const envConfig = allConfigFromEnv();
147+
if (globalThis.midsceneGlobalConfigOverride) {
148+
const { newConfig, extendMode } = globalThis.midsceneGlobalConfigOverride;
149+
globalThis.midsceneGlobalConfig = extendMode
150+
? { ...envConfig, ...newConfig }
151+
: { ...newConfig };
152+
} else {
153+
globalThis.midsceneGlobalConfig = envConfig;
154+
}
155+
142156
return globalThis.midsceneGlobalConfig;
143157
};
144158

@@ -277,10 +291,17 @@ export const overrideAIConfig = (
277291
}
278292
}
279293

280-
const currentConfig = getGlobalConfig();
281-
globalThis.midsceneGlobalConfig = extendMode
282-
? { ...currentConfig, ...newConfig }
283-
: { ...newConfig };
294+
const savedNewConfig = extendMode
295+
? {
296+
...globalThis.midsceneGlobalConfigOverride?.newConfig,
297+
...newConfig,
298+
}
299+
: newConfig;
300+
301+
globalThis.midsceneGlobalConfigOverride = {
302+
newConfig: savedNewConfig,
303+
extendMode,
304+
};
284305
};
285306

286307
export const getPreferredLanguage = () => {

packages/shared/tests/unit-test/env.test.ts

Lines changed: 207 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,28 @@
1-
import { afterAll, describe, expect, it, vi } from 'vitest';
21
import {
2+
afterAll,
3+
afterEach,
4+
beforeEach,
5+
describe,
6+
expect,
7+
it,
8+
vi,
9+
} from 'vitest';
10+
import {
11+
MIDSCENE_DEBUG_MODE,
12+
MIDSCENE_MODEL_NAME,
313
MIDSCENE_USE_DOUBAO_VISION,
14+
getAIConfig,
415
overrideAIConfig,
516
vlLocateMode,
617
} from '../../src/env';
718

819
describe('env', () => {
20+
beforeEach(() => {
21+
// Clean up global config before each test
22+
globalThis.midsceneGlobalConfig = null;
23+
globalThis.midsceneGlobalConfigOverride = null;
24+
});
25+
926
afterAll(() => {
1027
// Reset process.env before each test
1128
vi.resetModules();
@@ -28,4 +45,193 @@ describe('env', () => {
2845
const vlMode = vlLocateMode();
2946
expect(vlMode).toBe('doubao-vision');
3047
});
48+
49+
describe('getGlobalConfig with override', () => {
50+
beforeEach(() => {
51+
// Clean up global state
52+
globalThis.midsceneGlobalConfig = null;
53+
globalThis.midsceneGlobalConfigOverride = null;
54+
55+
// Mock process.env
56+
vi.stubEnv(MIDSCENE_MODEL_NAME, 'original-model');
57+
vi.stubEnv(MIDSCENE_DEBUG_MODE, 'true');
58+
});
59+
60+
afterEach(() => {
61+
vi.unstubAllEnvs();
62+
});
63+
64+
it('should return env config when no override is set', () => {
65+
const config1 = getAIConfig(MIDSCENE_MODEL_NAME);
66+
expect(config1).toBe('original-model');
67+
68+
const config2 = getAIConfig(MIDSCENE_DEBUG_MODE);
69+
expect(config2).toBe('true');
70+
});
71+
72+
it('should override config with new values in replace mode', () => {
73+
overrideAIConfig(
74+
{
75+
[MIDSCENE_MODEL_NAME]: 'overridden-model',
76+
},
77+
false,
78+
);
79+
80+
const config1 = getAIConfig(MIDSCENE_MODEL_NAME);
81+
expect(config1).toBe('overridden-model');
82+
83+
// In replace mode, non-overridden values should be undefined
84+
const config2 = getAIConfig(MIDSCENE_DEBUG_MODE);
85+
expect(config2).toBeUndefined();
86+
});
87+
88+
it('should extend config with new values in extend mode', () => {
89+
overrideAIConfig(
90+
{
91+
[MIDSCENE_MODEL_NAME]: 'overridden-model',
92+
},
93+
true,
94+
);
95+
96+
const config1 = getAIConfig(MIDSCENE_MODEL_NAME);
97+
expect(config1).toBe('overridden-model');
98+
99+
// In extend mode, non-overridden values should keep their env values
100+
const config2 = getAIConfig(MIDSCENE_DEBUG_MODE);
101+
expect(config2).toBe('true');
102+
});
103+
104+
it('should handle multiple overrides correctly', () => {
105+
// First override
106+
overrideAIConfig(
107+
{
108+
[MIDSCENE_MODEL_NAME]: 'first-override',
109+
},
110+
false,
111+
);
112+
113+
let config = getAIConfig(MIDSCENE_MODEL_NAME);
114+
expect(config).toBe('first-override');
115+
116+
// Second override should replace the first
117+
overrideAIConfig(
118+
{
119+
[MIDSCENE_MODEL_NAME]: 'second-override',
120+
[MIDSCENE_DEBUG_MODE]: 'false',
121+
},
122+
true,
123+
);
124+
125+
config = getAIConfig(MIDSCENE_MODEL_NAME);
126+
expect(config).toBe('second-override');
127+
128+
const debugConfig = getAIConfig(MIDSCENE_DEBUG_MODE);
129+
expect(debugConfig).toBe('false');
130+
});
131+
132+
it('should always use fresh env values when override is set', () => {
133+
// Initial config access
134+
const initialConfig = getAIConfig(MIDSCENE_MODEL_NAME);
135+
expect(initialConfig).toBe('original-model');
136+
137+
// Change env value
138+
vi.stubEnv(MIDSCENE_MODEL_NAME, 'updated-model');
139+
140+
// Override with extend mode should use the new env value
141+
overrideAIConfig(
142+
{
143+
[MIDSCENE_DEBUG_MODE]: 'overridden',
144+
},
145+
true,
146+
);
147+
148+
const config = getAIConfig(MIDSCENE_MODEL_NAME);
149+
expect(config).toBe('updated-model');
150+
});
151+
152+
it('should handle clearing the override', () => {
153+
overrideAIConfig(
154+
{
155+
[MIDSCENE_MODEL_NAME]: 'overridden',
156+
},
157+
false,
158+
);
159+
160+
let config = getAIConfig(MIDSCENE_MODEL_NAME);
161+
expect(config).toBe('overridden');
162+
163+
// Clear the override
164+
globalThis.midsceneGlobalConfigOverride = null;
165+
166+
// Should return to env values
167+
config = getAIConfig(MIDSCENE_MODEL_NAME);
168+
expect(config).toBe('original-model');
169+
});
170+
171+
it('should allow overrideAIConfig to work regardless of when it is called (timing independence)', () => {
172+
// IMPORTANT: This test verifies the core fix - that overrideAIConfig no longer needs
173+
// to be called before getAIConfig to take effect
174+
175+
// Step 1: Call getAIConfig first (this would have caused issues in the old implementation)
176+
const configBeforeOverride = getAIConfig(MIDSCENE_MODEL_NAME);
177+
expect(configBeforeOverride).toBe('original-model');
178+
179+
// Step 2: Now call overrideAIConfig AFTER getAIConfig has been called
180+
overrideAIConfig(
181+
{
182+
[MIDSCENE_MODEL_NAME]: 'late-override',
183+
},
184+
false,
185+
);
186+
187+
// Step 3: The override should still take effect immediately
188+
const configAfterOverride = getAIConfig(MIDSCENE_MODEL_NAME);
189+
expect(configAfterOverride).toBe('late-override');
190+
191+
// Step 4: Test extend mode also works with late override
192+
overrideAIConfig(
193+
{
194+
[MIDSCENE_MODEL_NAME]: 'late-extend-override',
195+
},
196+
true,
197+
);
198+
199+
const configAfterExtend = getAIConfig(MIDSCENE_MODEL_NAME);
200+
expect(configAfterExtend).toBe('late-extend-override');
201+
const debugConfig = getAIConfig(MIDSCENE_DEBUG_MODE);
202+
expect(debugConfig).toBe('true'); // Should preserve env value in extend mode
203+
});
204+
205+
it('should recalculate config on every getAIConfig call when override is present', () => {
206+
// This test ensures that config is calculated fresh each time, not cached
207+
208+
// Set initial override
209+
overrideAIConfig(
210+
{
211+
[MIDSCENE_MODEL_NAME]: 'override-1',
212+
},
213+
true,
214+
);
215+
216+
expect(getAIConfig(MIDSCENE_MODEL_NAME)).toBe('override-1');
217+
218+
// Change env value (simulating runtime env change)
219+
vi.stubEnv(MIDSCENE_DEBUG_MODE, 'changed-env');
220+
221+
// Even though we didn't touch the override, the env change should be reflected
222+
expect(getAIConfig(MIDSCENE_DEBUG_MODE)).toBe('changed-env');
223+
224+
// Change override
225+
overrideAIConfig(
226+
{
227+
[MIDSCENE_MODEL_NAME]: 'override-2',
228+
[MIDSCENE_DEBUG_MODE]: 'override-debug',
229+
},
230+
true,
231+
);
232+
233+
expect(getAIConfig(MIDSCENE_MODEL_NAME)).toBe('override-2');
234+
expect(getAIConfig(MIDSCENE_DEBUG_MODE)).toBe('override-debug');
235+
});
236+
});
31237
});

0 commit comments

Comments
 (0)