journal/Journal.SmokeTests/Program.ParserTests.cs
Jacob Schmidt 0d77300c22 feat: Project Journal backend monorepo
Monorepo with centralized build props, npm workspaces, LlamaSharp AI,
SQLite/SQLCipher storage, Svelte frontend, and unified smoke tests.

Co-Authored-By: Oz <oz-agent@warp.dev>
2026-03-02 20:56:26 -06:00

154 lines
5.6 KiB
C#

internal static partial class Program
{
static Task TestParserExtractsBoldDateAsync()
{
var content = """
---
type: journal
---
**Date:** 2026-02-22
## Summary
hello
""";
var entry = JournalParser.ParseJournalContent(content, "2026-02-01");
Assert(entry.Date == "2026-02-22", "Parser should read date from **Date:** marker.");
return Task.CompletedTask;
}
static Task TestParserExtractsPlainDateAsync()
{
var content = """
Date: 2026-02-23
## Summary
hello
""";
var entry = JournalParser.ParseJournalContent(content, "2026-02-01");
Assert(entry.Date == "2026-02-23", "Parser should read date from Date: marker.");
return Task.CompletedTask;
}
static Task TestParserFallsBackToFileStemAsync()
{
var content = """
## Summary
no explicit date
""";
var entry = JournalParser.ParseJournalContent(content, "2026-02-24");
Assert(entry.Date == "2026-02-24", "Parser should fall back to file stem when no date marker is present.");
return Task.CompletedTask;
}
static Task TestParserCapturesSectionsAsync()
{
var content = """
Date: 2026-02-25
## Summary
line one
line two
### Events / Triggers - Work
trigger line
## reflection notes
anchor line
""";
var entry = JournalParser.ParseJournalContent(content, "2026-02-01");
Assert(entry.Sections.ContainsKey("Summary"), "Parser should capture Summary section.");
Assert(entry.Sections.ContainsKey("Events / Triggers"), "Parser should capture Events / Triggers section.");
Assert(entry.Sections.ContainsKey("Reflection"), "Parser should match canonical section title by substring.");
Assert(entry.GetSection("Summary").Contains("line one"), "Summary section content mismatch.");
Assert(entry.GetSection("Events / Triggers").Contains("trigger line"), "Events / Triggers section content mismatch.");
Assert(entry.GetSection("Reflection").Contains("anchor line"), "Reflection section content mismatch.");
return Task.CompletedTask;
}
static Task TestParserIgnoresNonCanonicalHeadersAsync()
{
var content = """
## Summary
keep this
## Totally Custom Header
should not be captured
### Events / Triggers
keep this too
""";
var entry = JournalParser.ParseJournalContent(content, "2026-02-01");
Assert(entry.GetSection("Summary").Contains("keep this"), "Summary section should be captured.");
Assert(!entry.GetSection("Summary").Contains("should not be captured"), "Non-canonical section content should not bleed into previous section.");
Assert(entry.GetSection("Events / Triggers").Contains("keep this too"), "Canonical section after custom header should be captured.");
return Task.CompletedTask;
}
static Task TestParserCapturesCheckboxStatesAsync()
{
var content = """
## Summary
- [x] took medication
- [ ] drank water
* [X] wrote reflection
## Events / Triggers
- [ ] talked to manager
""";
var entry = JournalParser.ParseJournalContent(content, "2026-02-01");
Assert(entry.GetCheckboxState("Summary", "took medication") is true, "Expected checked state for '- [x]' checkbox.");
Assert(entry.GetCheckboxState("Summary", "drank water") is false, "Expected unchecked state for '- [ ]' checkbox.");
Assert(entry.GetCheckboxState("Summary", "wrote reflection") is true, "Expected checked state for '* [X]' checkbox.");
Assert(entry.GetCheckboxState("Events / Triggers", "talked to manager") is false, "Expected unchecked state in Events / Triggers section.");
Assert(entry.GetCheckboxState("Summary", "missing item") is null, "Missing checkbox text should return null.");
return Task.CompletedTask;
}
static Task TestParserCapturesMultilineFragmentsAsync()
{
var content = """
Date: 2026-02-26
## Summary
text
!TRIGGER @2026-02-26T10:15:00Z #stress #body
first line
second line
!NOTE #daily
short note
""";
var entry = JournalParser.ParseJournalContent(content, "2026-02-01");
Assert(entry.Fragments.Count == 2, "Expected two parsed fragments.");
Assert(entry.Fragments[0].Type == "!TRIGGER", "First fragment type mismatch.");
Assert(entry.Fragments[0].Description == "first line\nsecond line", "First fragment multiline description mismatch.");
Assert(entry.Fragments[0].Tags.Count == 2, "First fragment tag count mismatch.");
Assert(entry.Fragments[0].Tags[0] == "stress" && entry.Fragments[0].Tags[1] == "body", "First fragment tags mismatch.");
Assert(entry.Fragments[1].Type == "!NOTE", "Second fragment type mismatch.");
Assert(entry.Fragments[1].Description == "short note", "Second fragment description mismatch.");
Assert(entry.Fragments[1].Tags.Count == 1 && entry.Fragments[1].Tags[0] == "daily", "Second fragment tags mismatch.");
return Task.CompletedTask;
}
static Task TestParserFragmentBoundaryBehaviorAsync()
{
var content = """
!TRIGGER #a
line one
!NOTE this starts another fragment header
line two
""";
var fragments = JournalParser.ParseFragments(content);
Assert(fragments.Count == 1, "Expected one parsed fragment because second boundary line is not a valid fragment header.");
Assert(fragments[0].Description == "line one", "First fragment boundary capture mismatch.");
return Task.CompletedTask;
}
}