|
| 1 | +package cache |
| 2 | + |
| 3 | +import ( |
| 4 | + "testing" |
| 5 | +) |
| 6 | + |
| 7 | +// testStore returns a Store built from representative sample data. |
| 8 | +func testStore() *Store { |
| 9 | + corps := []*CorpInfo{ |
| 10 | + {CorpCode: "00126380", CorpName: "삼성전자", StockCode: "005930"}, |
| 11 | + {CorpCode: "01153956", CorpName: "컬리"}, |
| 12 | + {CorpCode: "01494172", CorpName: "컬리넥스트마일"}, |
| 13 | + {CorpCode: "01547845", CorpName: "당근마켓"}, |
| 14 | + {CorpCode: "01717824", CorpName: "당근페이"}, |
| 15 | + {CorpCode: "01138364", CorpName: "더핑크퐁컴퍼니", StockCode: "403850"}, |
| 16 | + {CorpCode: "00293886", CorpName: "카카오"}, |
| 17 | + {CorpCode: "00000002", CorpName: "카카오뱅크"}, |
| 18 | + {CorpCode: "00000003", CorpName: "카카오페이"}, |
| 19 | + {CorpCode: "01154811", CorpName: "주식회사 오늘의집"}, |
| 20 | + } |
| 21 | + return buildStore(corps) |
| 22 | +} |
| 23 | + |
| 24 | +func corpNames(corps []*CorpInfo) []string { |
| 25 | + out := make([]string, len(corps)) |
| 26 | + for i, c := range corps { |
| 27 | + out[i] = c.CorpName |
| 28 | + } |
| 29 | + return out |
| 30 | +} |
| 31 | + |
| 32 | +// --- exact match tests --- |
| 33 | + |
| 34 | +func TestSearch_ExactStockCode(t *testing.T) { |
| 35 | + s := testStore() |
| 36 | + results := s.Search("005930") |
| 37 | + if len(results) != 1 || results[0].CorpName != "삼성전자" { |
| 38 | + t.Fatalf("종목코드 완전일치 실패: got %v", corpNames(results)) |
| 39 | + } |
| 40 | +} |
| 41 | + |
| 42 | +func TestSearch_ExactCorpCode(t *testing.T) { |
| 43 | + s := testStore() |
| 44 | + results := s.Search("00126380") |
| 45 | + if len(results) != 1 || results[0].CorpName != "삼성전자" { |
| 46 | + t.Fatalf("법인코드 완전일치 실패: got %v", corpNames(results)) |
| 47 | + } |
| 48 | +} |
| 49 | + |
| 50 | +func TestSearch_ExactName(t *testing.T) { |
| 51 | + s := testStore() |
| 52 | + results := s.Search("삼성전자") |
| 53 | + if len(results) != 1 || results[0].CorpName != "삼성전자" { |
| 54 | + t.Fatalf("이름 완전일치 실패: got %v", corpNames(results)) |
| 55 | + } |
| 56 | +} |
| 57 | + |
| 58 | +// --- substring tests --- |
| 59 | + |
| 60 | +func TestSearch_Substring_당근(t *testing.T) { |
| 61 | + s := testStore() |
| 62 | + results := s.Search("당근") |
| 63 | + if len(results) != 2 { |
| 64 | + t.Fatalf("'당근' substring 검색: 2건 기대, got %d %v", len(results), corpNames(results)) |
| 65 | + } |
| 66 | +} |
| 67 | + |
| 68 | +func TestSearch_Substring_카카오(t *testing.T) { |
| 69 | + // "카카오" 이름 완전일치가 존재하므로 정확히 1건만 반환 (substring 전에 리턴) |
| 70 | + s := testStore() |
| 71 | + results := s.Search("카카오") |
| 72 | + if len(results) != 1 || results[0].CorpName != "카카오" { |
| 73 | + t.Fatalf("'카카오' 이름 완전일치: 1건 기대, got %d %v", len(results), corpNames(results)) |
| 74 | + } |
| 75 | +} |
| 76 | + |
| 77 | +func TestSearch_Substring_카카오계열(t *testing.T) { |
| 78 | + // "카카오뱅" 처럼 완전일치 없는 쿼리는 substring 으로 카카오뱅크를 찾음 |
| 79 | + s := testStore() |
| 80 | + results := s.Search("카카오뱅") |
| 81 | + if len(results) != 1 || results[0].CorpName != "카카오뱅크" { |
| 82 | + t.Fatalf("'카카오뱅' substring 검색: 카카오뱅크 기대, got %v", corpNames(results)) |
| 83 | + } |
| 84 | +} |
| 85 | + |
| 86 | +func TestSearch_Substring_핑크퐁(t *testing.T) { |
| 87 | + s := testStore() |
| 88 | + results := s.Search("핑크퐁") |
| 89 | + if len(results) != 1 || results[0].CorpName != "더핑크퐁컴퍼니" { |
| 90 | + t.Fatalf("'핑크퐁' substring 검색 실패: got %v", corpNames(results)) |
| 91 | + } |
| 92 | +} |
| 93 | + |
| 94 | +// --- fuzzy tests --- |
| 95 | + |
| 96 | +func TestSearch_Fuzzy_마켓컬리(t *testing.T) { |
| 97 | + s := testStore() |
| 98 | + results := s.Search("마켓컬리") |
| 99 | + if len(results) == 0 { |
| 100 | + t.Fatal("'마켓컬리' fuzzy 검색: 결과 없음 (기대: '컬리' 포함)") |
| 101 | + } |
| 102 | + found := false |
| 103 | + for _, r := range results { |
| 104 | + if r.CorpName == "컬리" { |
| 105 | + found = true |
| 106 | + } |
| 107 | + } |
| 108 | + if !found { |
| 109 | + t.Fatalf("'마켓컬리' fuzzy 결과에 '컬리' 없음: got %v", corpNames(results)) |
| 110 | + } |
| 111 | + t.Logf("'마켓컬리' fuzzy 결과: %v", corpNames(results)) |
| 112 | +} |
| 113 | + |
| 114 | +func TestSearch_Fuzzy_오늘의집(t *testing.T) { |
| 115 | + // "오늘의집" → substring 으로도 찾힘, fuzzy 로도 찾혀야 함 |
| 116 | + s := testStore() |
| 117 | + results := s.Search("오늘의집") |
| 118 | + if len(results) == 0 { |
| 119 | + t.Fatal("'오늘의집' 검색: 결과 없음") |
| 120 | + } |
| 121 | + found := false |
| 122 | + for _, r := range results { |
| 123 | + if r.CorpName == "주식회사 오늘의집" { |
| 124 | + found = true |
| 125 | + } |
| 126 | + } |
| 127 | + if !found { |
| 128 | + t.Fatalf("'오늘의집' 결과에 '주식회사 오늘의집' 없음: got %v", corpNames(results)) |
| 129 | + } |
| 130 | +} |
| 131 | + |
| 132 | +func TestSearch_NoResult_완전엉뚱한검색어(t *testing.T) { |
| 133 | + s := testStore() |
| 134 | + results := s.Search("xyzxyz없는기업명zyx") |
| 135 | + if len(results) != 0 { |
| 136 | + t.Logf("'xyzxyz없는기업명zyx' 검색 결과 (fuzzy 허용): %v", corpNames(results)) |
| 137 | + } |
| 138 | +} |
| 139 | + |
| 140 | +// --- bigramSim unit tests --- |
| 141 | + |
| 142 | +func TestBigramSim_완전동일(t *testing.T) { |
| 143 | + score := bigramSim("삼성전자", "삼성전자") |
| 144 | + if score != 1.0 { |
| 145 | + t.Fatalf("동일 문자열 bigramSim: 1.0 기대, got %f", score) |
| 146 | + } |
| 147 | +} |
| 148 | + |
| 149 | +func TestBigramSim_부분겹침(t *testing.T) { |
| 150 | + // "마켓컬리" bigrams: [마켓, 켓컬, 컬리] |
| 151 | + // "컬리" bigrams: [컬리] → 1 match / 3 query bigrams = 0.333 |
| 152 | + score := bigramSim("마켓컬리", "컬리") |
| 153 | + if score < 0.3 { |
| 154 | + t.Fatalf("'마켓컬리' vs '컬리': 0.3 이상 기대, got %f", score) |
| 155 | + } |
| 156 | +} |
| 157 | + |
| 158 | +func TestBigramSim_핑크퐁(t *testing.T) { |
| 159 | + // "핑크퐁" bigrams: [핑크, 크퐁] |
| 160 | + // "더핑크퐁컴퍼니" bigrams: [더핑, 핑크, 크퐁, 퐁컴, 컴퍼, 퍼니] → 2 match / 2 = 1.0 |
| 161 | + score := bigramSim("핑크퐁", "더핑크퐁컴퍼니") |
| 162 | + if score != 1.0 { |
| 163 | + t.Fatalf("'핑크퐁' vs '더핑크퐁컴퍼니': 1.0 기대, got %f", score) |
| 164 | + } |
| 165 | +} |
| 166 | + |
| 167 | +func TestBigramSim_단일문자(t *testing.T) { |
| 168 | + // 단일 rune은 bigram 없음 → 0 |
| 169 | + score := bigramSim("가", "가나다라") |
| 170 | + if score != 0 { |
| 171 | + t.Fatalf("단일 문자 bigramSim: 0 기대, got %f", score) |
| 172 | + } |
| 173 | +} |
0 commit comments