using Application.Helpers; namespace Application.Tests; /// /// $종목 태그 파서 단위 테스트 (d2 §③·§⑤) — 순수 함수, DB 무관. /// 저장 토큰 `$005930(삼성전자)` 에서 6자리 코드 추출·중복 제거·비코드 무시를 검증한다. /// [TestClass] public sealed class StockTagParserTests { [TestMethod] public void Extract_TokenWithName_ReturnsCode() { var codes = StockTagParser.Extract("삼성전자 좋습니다 $005930(삼성전자) 매수"); Assert.AreEqual(1, codes.Count); Assert.AreEqual("005930", codes[0]); } [TestMethod] public void Extract_BareCode_ReturnsCode() { var codes = StockTagParser.Extract("$000660 갑니다"); Assert.AreEqual(1, codes.Count); Assert.AreEqual("000660", codes[0]); } [TestMethod] public void Extract_MultipleCodes_PreservesOrder() { var codes = StockTagParser.Extract("$005930(삼성전자) 와 $000660(SK하이닉스) 비교"); CollectionAssert.AreEqual(new[] { "005930", "000660" }, codes); } [TestMethod] public void Extract_DuplicateCodes_Deduped() { var codes = StockTagParser.Extract("$005930(삼성전자) 언급 후 다시 $005930 언급"); Assert.AreEqual(1, codes.Count); Assert.AreEqual("005930", codes[0]); } [TestMethod] public void Extract_NonSixDigit_Ignored() { // 5자리·7자리·문자 혼합은 종목코드가 아니다. var codes = StockTagParser.Extract("$00593 아님 $0059301 아님 $abcdef 아님 $12 아님"); Assert.AreEqual(0, codes.Count); } [TestMethod] public void Extract_SevenDigitBoundary_NotMatched() { // 6자리 뒤에 숫자가 이어지면 종목코드로 보지 않는다(경계 검사). var codes = StockTagParser.Extract("$0059301"); Assert.AreEqual(0, codes.Count); } [TestMethod] public void Extract_NoDollarSign_Ignored() { var codes = StockTagParser.Extract("005930 은 태그가 아니다"); Assert.AreEqual(0, codes.Count); } [TestMethod] public void Extract_NullOrEmpty_ReturnsEmpty() { Assert.AreEqual(0, StockTagParser.Extract(null).Count); Assert.AreEqual(0, StockTagParser.Extract("").Count); } }