add end to end hygiene test
This commit is contained in:
parent
48b422cba4
commit
550fa4fd88
1 changed files with 64 additions and 0 deletions
|
|
@ -1633,3 +1633,67 @@ test "findPriceDateMismatches: duplicate HEAD identity collapses to one entry" {
|
|||
try std.testing.expectApproxEqAbs(@as(f64, 150), mismatches.items[0].old_price, 0.01);
|
||||
try std.testing.expectApproxEqAbs(@as(f64, 160), mismatches.items[0].new_price, 0.01);
|
||||
}
|
||||
|
||||
test "runHygieneCheck: Section 6 flags an un-opted-in symbol's split, not an opted-in one" {
|
||||
const allocator = std.testing.allocator;
|
||||
const io = std.testing.io;
|
||||
var tmp = std.testing.tmpDir(.{});
|
||||
defer tmp.cleanup();
|
||||
|
||||
// NVDA: held across its 2024 split, NOT opted in -> should flag.
|
||||
// AMZN: held across its 2022 split, opted in via metadata -> should not.
|
||||
try tmp.dir.writeFile(io, .{
|
||||
.sub_path = "portfolio.srf",
|
||||
.data =
|
||||
\\#!srfv1
|
||||
\\symbol::NVDA,shares:num:100,open_date::2020-01-01,open_price:num:40.00,account::Sample Brokerage
|
||||
\\symbol::AMZN,shares:num:30,open_date::2019-01-01,open_price:num:90.00,account::Sample Brokerage
|
||||
\\
|
||||
,
|
||||
});
|
||||
// accounts.srf must exist and parse (an empty map is fine).
|
||||
try tmp.dir.writeFile(io, .{ .sub_path = "accounts.srf", .data = "#!srfv1\n" });
|
||||
// Per-symbol opt-in: AMZN yes, NVDA absent (not opted in).
|
||||
try tmp.dir.writeFile(io, .{
|
||||
.sub_path = "metadata.srf",
|
||||
.data = "#!srfv1\nsymbol::AMZN,splits_current_through::2024-01-01\n",
|
||||
});
|
||||
|
||||
var path_buf: [std.fs.max_path_bytes]u8 = undefined;
|
||||
const dir_len = try tmp.dir.realPathFile(io, ".", &path_buf);
|
||||
const dir = path_buf[0..dir_len];
|
||||
|
||||
// Seed the split cache: NVDA 10:1 (2024-06-10), AMZN 20:1 (2022-06-06).
|
||||
var store = zfin.cache.Store.init(io, allocator, dir);
|
||||
var nvda = [_]zfin.Split{.{ .date = zfin.Date.fromYmd(2024, 6, 10), .numerator = 10, .denominator = 1 }};
|
||||
store.write(zfin.Split, "NVDA", nvda[0..], .{ .seconds = zfin.cache.Ttl.splits });
|
||||
var amzn = [_]zfin.Split{.{ .date = zfin.Date.fromYmd(2022, 6, 6), .numerator = 20, .denominator = 1 }};
|
||||
store.write(zfin.Split, "AMZN", amzn[0..], .{ .seconds = zfin.cache.Ttl.splits });
|
||||
|
||||
// No API keys / no server -> hermetic (fetches can't reach a network).
|
||||
var svc = zfin.DataService.init(io, allocator, .{ .cache_dir = dir });
|
||||
defer svc.deinit();
|
||||
|
||||
var env = try std.testing.environ.createMap(allocator);
|
||||
defer env.deinit();
|
||||
|
||||
const pf_path = try std.fs.path.join(allocator, &.{ dir, "portfolio.srf" });
|
||||
defer allocator.free(pf_path);
|
||||
|
||||
var aw: std.Io.Writer.Allocating = .init(allocator);
|
||||
defer aw.deinit();
|
||||
|
||||
try runHygieneCheck(io, allocator, &env, &svc, pf_path, 3, false, zfin.Date.fromYmd(2026, 1, 1), 1_767_225_600, false, .never, &aw.writer);
|
||||
|
||||
const output = aw.written();
|
||||
try std.testing.expect(std.mem.indexOf(u8, output, "Portfolio hygiene") != null);
|
||||
|
||||
// Assert against Section 6 specifically (it's the last section, so
|
||||
// slice from its header to end) - robust even if NVDA/AMZN surface
|
||||
// in an earlier section. The un-opted-in NVDA is listed; the
|
||||
// opted-in AMZN is not.
|
||||
const sec6_start = std.mem.indexOf(u8, output, "Unhandled stock splits") orelse return error.Section6Missing;
|
||||
const sec6 = output[sec6_start..];
|
||||
try std.testing.expect(std.mem.indexOf(u8, sec6, "NVDA") != null);
|
||||
try std.testing.expect(std.mem.indexOf(u8, sec6, "AMZN") == null);
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue