@@ -1033,6 +1033,63 @@ describe("Rules directory reading", () => {
10331033 expect ( result ) . toContain ( "content of file3" )
10341034 } )
10351035
1036+ it ( "should return files in alphabetical order by filename" , async ( ) => {
1037+ // Simulate .roo/rules directory exists
1038+ statMock . mockResolvedValueOnce ( {
1039+ isDirectory : vi . fn ( ) . mockReturnValue ( true ) ,
1040+ } as any )
1041+
1042+ // Simulate listing files in non-alphabetical order to test sorting
1043+ readdirMock . mockResolvedValueOnce ( [
1044+ { name : "zebra.txt" , isFile : ( ) => true , parentPath : "/fake/path/.roo/rules" } ,
1045+ { name : "alpha.txt" , isFile : ( ) => true , parentPath : "/fake/path/.roo/rules" } ,
1046+ { name : "Beta.txt" , isFile : ( ) => true , parentPath : "/fake/path/.roo/rules" } , // Test case-insensitive sorting
1047+ ] as any )
1048+
1049+ statMock . mockImplementation ( ( path ) => {
1050+ return Promise . resolve ( {
1051+ isFile : vi . fn ( ) . mockReturnValue ( true ) ,
1052+ } ) as any
1053+ } )
1054+
1055+ readFileMock . mockImplementation ( ( filePath : PathLike ) => {
1056+ const pathStr = filePath . toString ( )
1057+ const normalizedPath = pathStr . replace ( / \\ / g, "/" )
1058+ if ( normalizedPath === "/fake/path/.roo/rules/zebra.txt" ) {
1059+ return Promise . resolve ( "zebra content" )
1060+ }
1061+ if ( normalizedPath === "/fake/path/.roo/rules/alpha.txt" ) {
1062+ return Promise . resolve ( "alpha content" )
1063+ }
1064+ if ( normalizedPath === "/fake/path/.roo/rules/Beta.txt" ) {
1065+ return Promise . resolve ( "beta content" )
1066+ }
1067+ return Promise . reject ( { code : "ENOENT" } )
1068+ } )
1069+
1070+ const result = await loadRuleFiles ( "/fake/path" )
1071+
1072+ // Files should appear in alphabetical order: alpha.txt, Beta.txt, zebra.txt
1073+ const alphaIndex = result . indexOf ( "alpha content" )
1074+ const betaIndex = result . indexOf ( "beta content" )
1075+ const zebraIndex = result . indexOf ( "zebra content" )
1076+
1077+ expect ( alphaIndex ) . toBeLessThan ( betaIndex )
1078+ expect ( betaIndex ) . toBeLessThan ( zebraIndex )
1079+
1080+ // Verify the expected file paths are in the result
1081+ const expectedAlphaPath =
1082+ process . platform === "win32" ? "\\fake\\path\\.roo\\rules\\alpha.txt" : "/fake/path/.roo/rules/alpha.txt"
1083+ const expectedBetaPath =
1084+ process . platform === "win32" ? "\\fake\\path\\.roo\\rules\\Beta.txt" : "/fake/path/.roo/rules/Beta.txt"
1085+ const expectedZebraPath =
1086+ process . platform === "win32" ? "\\fake\\path\\.roo\\rules\\zebra.txt" : "/fake/path/.roo/rules/zebra.txt"
1087+
1088+ expect ( result ) . toContain ( `# Rules from ${ expectedAlphaPath } :` )
1089+ expect ( result ) . toContain ( `# Rules from ${ expectedBetaPath } :` )
1090+ expect ( result ) . toContain ( `# Rules from ${ expectedZebraPath } :` )
1091+ } )
1092+
10361093 it ( "should handle empty file list gracefully" , async ( ) => {
10371094 // Simulate .roo/rules directory exists
10381095 statMock . mockResolvedValueOnce ( {
0 commit comments