@@ -202,6 +202,135 @@ describe('speech synthesize command', () => {
202202 console . log = originalLog ;
203203 }
204204 } ) ;
205+
206+ it ( '--pronunciation uses the API-compatible request shape' , async ( ) => {
207+ const config = {
208+ apiKey : 'test-key' ,
209+ region : 'global' as const ,
210+ baseUrl : 'https://api.mmx.io' ,
211+ output : 'json' as const ,
212+ timeout : 10 ,
213+ verbose : false ,
214+ quiet : false ,
215+ noColor : true ,
216+ yes : false ,
217+ dryRun : true ,
218+ nonInteractive : true ,
219+ async : false ,
220+ } ;
221+
222+ const originalLog = console . log ;
223+ let output = '' ;
224+ console . log = ( msg : string ) => { output += msg ; } ;
225+
226+ try {
227+ await synthesizeCommand . execute ( config , {
228+ text : '我要去重庆出差。' ,
229+ pronunciation : [
230+ '重/(chong2)' ,
231+ '行长/(hang2)(zhang3)' ,
232+ ] ,
233+ quiet : false ,
234+ verbose : false ,
235+ noColor : true ,
236+ yes : false ,
237+ dryRun : true ,
238+ help : false ,
239+ nonInteractive : true ,
240+ async : false ,
241+ } ) ;
242+
243+ const parsed = JSON . parse ( output ) ;
244+
245+ // Object with a tone string array (not the old array-of-objects shape),
246+ // preserving each value verbatim — including multi-character words.
247+ expect ( Array . isArray ( parsed . request . pronunciation_dict ) ) . toBe ( false ) ;
248+ expect ( parsed . request . pronunciation_dict ) . toEqual ( {
249+ tone : [
250+ '重/(chong2)' ,
251+ '行长/(hang2)(zhang3)' ,
252+ ] ,
253+ } ) ;
254+ } finally {
255+ console . log = originalLog ;
256+ }
257+ } ) ;
258+
259+ it ( '--pronunciation with a single value serializes under tone' , async ( ) => {
260+ const config = {
261+ apiKey : 'test-key' ,
262+ region : 'global' as const ,
263+ baseUrl : 'https://api.mmx.io' ,
264+ output : 'json' as const ,
265+ timeout : 10 ,
266+ verbose : false ,
267+ quiet : false ,
268+ noColor : true ,
269+ yes : false ,
270+ dryRun : true ,
271+ nonInteractive : true ,
272+ async : false ,
273+ } ;
274+
275+ const originalLog = console . log ;
276+ let output = '' ;
277+ console . log = ( msg : string ) => { output += msg ; } ;
278+
279+ try {
280+ await synthesizeCommand . execute ( config , {
281+ text : '我要去重庆出差。' ,
282+ pronunciation : [ '重/(chong2)' ] ,
283+ quiet : false ,
284+ verbose : false ,
285+ noColor : true ,
286+ yes : false ,
287+ dryRun : true ,
288+ help : false ,
289+ nonInteractive : true ,
290+ async : false ,
291+ } ) ;
292+
293+ const parsed = JSON . parse ( output ) ;
294+
295+ expect ( parsed . request . pronunciation_dict ) . toEqual ( {
296+ tone : [ '重/(chong2)' ] ,
297+ } ) ;
298+ } finally {
299+ console . log = originalLog ;
300+ }
301+ } ) ;
302+
303+ it ( '--pronunciation rejects malformed values without a separator' , async ( ) => {
304+ const config = {
305+ apiKey : 'test-key' ,
306+ region : 'global' as const ,
307+ baseUrl : 'https://api.mmx.io' ,
308+ output : 'json' as const ,
309+ timeout : 10 ,
310+ verbose : false ,
311+ quiet : false ,
312+ noColor : true ,
313+ yes : false ,
314+ dryRun : true ,
315+ nonInteractive : true ,
316+ async : false ,
317+ } ;
318+
319+ await expect (
320+ synthesizeCommand . execute ( config , {
321+ text : 'Hello' ,
322+ pronunciation : [ 'chong2' ] ,
323+ quiet : false ,
324+ verbose : false ,
325+ noColor : true ,
326+ yes : false ,
327+ dryRun : true ,
328+ help : false ,
329+ nonInteractive : true ,
330+ async : false ,
331+ } ) ,
332+ ) . rejects . toThrow ( 'Invalid --pronunciation value "chong2"' ) ;
333+ } ) ;
205334} ) ;
206335
207336describe ( 'speech synthesize format validation' , ( ) => {
0 commit comments