@@ -62,16 +62,31 @@ describe("Command Mentions", () => {
6262 } )
6363
6464 it ( "should handle multiple commands in message" , async ( ) => {
65+ const setupContent = "# Setup Environment\n\nRun the following commands:\n```bash\nnpm install\n```"
66+ const deployContent = "# Deploy Environment\n\nRun the following commands:\n```bash\nnpm run deploy\n```"
67+
6568 mockGetCommand
6669 . mockResolvedValueOnce ( {
6770 name : "setup" ,
68- content : "# Setup instructions" ,
71+ content : setupContent ,
6972 source : "project" ,
7073 filePath : "/project/.roo/commands/setup.md" ,
7174 } )
7275 . mockResolvedValueOnce ( {
7376 name : "deploy" ,
74- content : "# Deploy instructions" ,
77+ content : deployContent ,
78+ source : "project" ,
79+ filePath : "/project/.roo/commands/deploy.md" ,
80+ } )
81+ . mockResolvedValueOnce ( {
82+ name : "setup" ,
83+ content : setupContent ,
84+ source : "project" ,
85+ filePath : "/project/.roo/commands/setup.md" ,
86+ } )
87+ . mockResolvedValueOnce ( {
88+ name : "deploy" ,
89+ content : deployContent ,
7590 source : "project" ,
7691 filePath : "/project/.roo/commands/deploy.md" ,
7792 } )
@@ -82,33 +97,55 @@ describe("Command Mentions", () => {
8297
8398 expect ( mockGetCommand ) . toHaveBeenCalledWith ( "/test/cwd" , "setup" )
8499 expect ( mockGetCommand ) . toHaveBeenCalledWith ( "/test/cwd" , "deploy" )
85- expect ( mockGetCommand ) . toHaveBeenCalledTimes ( 2 ) // Both commands called
100+ expect ( mockGetCommand ) . toHaveBeenCalledTimes ( 2 ) // Each unique command called once (optimized)
86101 expect ( result ) . toContain ( '<command name="setup">' )
87- expect ( result ) . toContain ( "# Setup instructions " )
102+ expect ( result ) . toContain ( "# Setup Environment " )
88103 expect ( result ) . toContain ( '<command name="deploy">' )
89- expect ( result ) . toContain ( "# Deploy instructions " )
104+ expect ( result ) . toContain ( "# Deploy Environment " )
90105 } )
91106
92- it ( "should handle non-existent command gracefully" , async ( ) => {
107+ it ( "should leave non-existent commands unchanged" , async ( ) => {
108+ mockGetCommand . mockReset ( )
93109 mockGetCommand . mockResolvedValue ( undefined )
94110
95111 const input = "/nonexistent command"
96112 const result = await callParseMentions ( input )
97113
98114 expect ( mockGetCommand ) . toHaveBeenCalledWith ( "/test/cwd" , "nonexistent" )
99- expect ( result ) . toContain ( '<command name="nonexistent">' )
100- expect ( result ) . toContain ( "Command 'nonexistent' not found" )
101- expect ( result ) . toContain ( "</command>" )
115+ // The command should remain unchanged in the text
116+ expect ( result ) . toBe ( "/nonexistent command" )
117+ // Should not contain any command tags
118+ expect ( result ) . not . toContain ( '<command name="nonexistent">' )
119+ expect ( result ) . not . toContain ( "Command 'nonexistent' not found" )
102120 } )
103121
104- it ( "should handle command loading errors" , async ( ) => {
122+ it ( "should handle command loading errors during existence check" , async ( ) => {
123+ mockGetCommand . mockReset ( )
105124 mockGetCommand . mockRejectedValue ( new Error ( "Failed to load command" ) )
106125
107126 const input = "/error-command test"
108127 const result = await callParseMentions ( input )
109128
129+ // When getCommand throws an error during existence check,
130+ // the command is treated as non-existent and left unchanged
131+ expect ( result ) . toBe ( "/error-command test" )
132+ expect ( result ) . not . toContain ( '<command name="error-command">' )
133+ } )
134+
135+ it ( "should handle command loading errors during processing" , async ( ) => {
136+ // With optimization, command is loaded once and cached
137+ mockGetCommand . mockResolvedValue ( {
138+ name : "error-command" ,
139+ content : "# Error command" ,
140+ source : "project" ,
141+ filePath : "/project/.roo/commands/error-command.md" ,
142+ } )
143+
144+ const input = "/error-command test"
145+ const result = await callParseMentions ( input )
146+
110147 expect ( result ) . toContain ( '<command name="error-command">' )
111- expect ( result ) . toContain ( "Error loading command" )
148+ expect ( result ) . toContain ( "# Error command" )
112149 expect ( result ) . toContain ( "</command>" )
113150 } )
114151
@@ -246,13 +283,29 @@ npm install
246283 } )
247284
248285 describe ( "command mention text transformation" , ( ) => {
249- it ( "should transform command mentions at start of message" , async ( ) => {
286+ it ( "should transform existing command mentions at start of message" , async ( ) => {
287+ mockGetCommand . mockResolvedValue ( {
288+ name : "setup" ,
289+ content : "# Setup instructions" ,
290+ source : "project" ,
291+ filePath : "/project/.roo/commands/setup.md" ,
292+ } )
293+
250294 const input = "/setup the project"
251295 const result = await callParseMentions ( input )
252296
253297 expect ( result ) . toContain ( "Command 'setup' (see below for command content)" )
254298 } )
255299
300+ it ( "should leave non-existent command mentions unchanged" , async ( ) => {
301+ mockGetCommand . mockResolvedValue ( undefined )
302+
303+ const input = "/nonexistent the project"
304+ const result = await callParseMentions ( input )
305+
306+ expect ( result ) . toBe ( "/nonexistent the project" )
307+ } )
308+
256309 it ( "should process multiple commands in message" , async ( ) => {
257310 mockGetCommand
258311 . mockResolvedValueOnce ( {
0 commit comments