WorldIndexParserTests.cs 2.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263
  1. using Infrastructure.StockData;
  2. namespace Application.Tests;
  3. [TestClass]
  4. public sealed class WorldIndexParserTests
  5. {
  6. [TestMethod]
  7. public void Parse_MapsFields_LowercasesSymbol()
  8. {
  9. // Stooq 라이트 배치(/q/l/?f=sd2t2ohlc&h&e=csv) 표준 응답 — 헤더 + 2행
  10. const string csv = """
  11. Symbol,Date,Time,Open,High,Low,Close
  12. ^SPX,2026-07-07,22:15:00,5100.50,5130.00,5090.10,5125.30
  13. ^NKX,2026-07-07,06:00:00,39000,39250,38900,39180.5
  14. """;
  15. var rows = WorldIndexCsvParser.Parse(csv);
  16. Assert.AreEqual(2, rows.Count);
  17. var spx = rows[0];
  18. Assert.AreEqual("^spx", spx.Symbol, "심볼은 소문자 정규화");
  19. Assert.AreEqual(new DateOnly(2026, 7, 7), spx.TradeDate);
  20. Assert.AreEqual(5100.50m, spx.Open);
  21. Assert.AreEqual(5130.00m, spx.High);
  22. Assert.AreEqual(5090.10m, spx.Low);
  23. Assert.AreEqual(5125.30m, spx.Close);
  24. var nkx = rows[1];
  25. Assert.AreEqual("^nkx", nkx.Symbol);
  26. Assert.AreEqual(39180.5m, nkx.Close);
  27. }
  28. [TestMethod]
  29. public void Parse_MissingClose_SkipsRow_MissingOhlc_FallsBackToClose()
  30. {
  31. // 첫 행: Close 가 N/D → 버림. 둘째 행: OHLC 가 N/D 지만 Close 유효 → OHLC 는 Close 로 보정.
  32. const string csv = """
  33. Symbol,Date,Time,Open,High,Low,Close
  34. ^BAD,N/D,N/D,N/D,N/D,N/D,N/D
  35. ^HSI,2026-07-07,10:00:00,N/D,N/D,N/D,24500.75
  36. """;
  37. var rows = WorldIndexCsvParser.Parse(csv);
  38. Assert.AreEqual(1, rows.Count, "Close 결측(N/D) 행은 제외");
  39. var hsi = rows[0];
  40. Assert.AreEqual("^hsi", hsi.Symbol);
  41. Assert.AreEqual(24500.75m, hsi.Close);
  42. Assert.AreEqual(24500.75m, hsi.Open, "OHLC 결측은 Close 로 보정");
  43. Assert.AreEqual(24500.75m, hsi.High);
  44. Assert.AreEqual(24500.75m, hsi.Low);
  45. }
  46. [TestMethod]
  47. public void Parse_EmptyOrHeaderOnly_ReturnsEmpty()
  48. {
  49. Assert.AreEqual(0, WorldIndexCsvParser.Parse("").Count);
  50. Assert.AreEqual(0, WorldIndexCsvParser.Parse(" ").Count);
  51. Assert.AreEqual(0, WorldIndexCsvParser.Parse("Symbol,Date,Time,Open,High,Low,Close").Count, "헤더만 있으면 0건");
  52. }
  53. }