@@ -516,6 +516,98 @@ func TestBuilder_NoSymbolsWithoutIntent(t *testing.T) {
516516 }
517517}
518518
519+ // TestSearch_MatchesLabel: query가 label에 매칭되면 결과를 반환한다.
520+ func TestSearch_MatchesLabel (t * testing.T ) {
521+ root := & ragindex.TreeNode {
522+ ID : "root" ,
523+ Label : "Root" ,
524+ Children : []* ragindex.TreeNode {
525+ {
526+ ID : "community:auth" ,
527+ Label : "MCP Server" ,
528+ Summary : "핸들러 레이어" ,
529+ Children : []* ragindex.TreeNode {
530+ {ID : "file:handlers.go" , Label : "handlers.go" , Summary : "MCP 핸들러" },
531+ },
532+ },
533+ {
534+ ID : "community:core" ,
535+ Label : "Core Logic" ,
536+ Summary : "비즈니스 로직" ,
537+ },
538+ },
539+ }
540+
541+ results := ragindex .Search (root , "mcp" , 10 )
542+ if len (results ) != 2 {
543+ t .Fatalf ("expected 2 results (community + file), got %d" , len (results ))
544+ }
545+ }
546+
547+ // TestSearch_CaseInsensitive: 검색은 대소문자를 구분하지 않는다.
548+ func TestSearch_CaseInsensitive (t * testing.T ) {
549+ root := & ragindex.TreeNode {
550+ ID : "root" ,
551+ Label : "Root" ,
552+ Children : []* ragindex.TreeNode {
553+ {ID : "c1" , Label : "Auth Service" , Summary : "JWT 인증" },
554+ },
555+ }
556+ results := ragindex .Search (root , "AUTH" , 10 )
557+ if len (results ) != 1 {
558+ t .Fatalf ("expected 1 result, got %d" , len (results ))
559+ }
560+ }
561+
562+ // TestSearch_MaxResults: maxResults 파라미터가 결과 수를 제한한다.
563+ func TestSearch_MaxResults (t * testing.T ) {
564+ children := make ([]* ragindex.TreeNode , 10 )
565+ for i := range children {
566+ children [i ] = & ragindex.TreeNode {ID : fmt .Sprintf ("c%d" , i ), Label : "test node" , Summary : "test" }
567+ }
568+ root := & ragindex.TreeNode {ID : "root" , Children : children }
569+
570+ results := ragindex .Search (root , "test" , 3 )
571+ if len (results ) != 3 {
572+ t .Fatalf ("expected 3 results (maxResults), got %d" , len (results ))
573+ }
574+ }
575+
576+ // TestSearch_IncludesBreadcrumb: 결과에 Path(breadcrumb)가 포함된다.
577+ func TestSearch_IncludesBreadcrumb (t * testing.T ) {
578+ root := & ragindex.TreeNode {
579+ ID : "root" ,
580+ Label : "Root" ,
581+ Children : []* ragindex.TreeNode {
582+ {
583+ ID : "community:auth" ,
584+ Label : "Auth" ,
585+ Children : []* ragindex.TreeNode {
586+ {ID : "file:login.go" , Label : "login.go" , Summary : "로그인 처리" },
587+ },
588+ },
589+ },
590+ }
591+ results := ragindex .Search (root , "로그인" , 10 )
592+ if len (results ) != 1 {
593+ t .Fatalf ("expected 1 result, got %d" , len (results ))
594+ }
595+ if len (results [0 ].Path ) != 3 {
596+ t .Fatalf ("expected path length 3 (root→auth→file), got %d: %v" , len (results [0 ].Path ), results [0 ].Path )
597+ }
598+ }
599+
600+ // TestSearch_NoMatch: 매칭 없으면 빈 슬라이스 반환.
601+ func TestSearch_NoMatch (t * testing.T ) {
602+ root := & ragindex.TreeNode {ID : "root" , Label : "Root" , Children : []* ragindex.TreeNode {
603+ {ID : "c1" , Label : "Auth" , Summary : "인증" },
604+ }}
605+ results := ragindex .Search (root , "zzznomatch" , 10 )
606+ if len (results ) != 0 {
607+ t .Fatalf ("expected 0 results, got %d" , len (results ))
608+ }
609+ }
610+
519611// TestFindNode: FindNode가 재귀적으로 트리에서 노드를 찾는지 검증한다.
520612func TestFindNode (t * testing.T ) {
521613 root := & ragindex.TreeNode {
0 commit comments