defmodule ToweropsWeb.ChangelogParserTest do use ExUnit.Case, async: true alias ToweropsWeb.ChangelogParser describe "parse_content/1" do test "parses date with title and items" do content = """ 2026-03-15 — New Features * Added dark mode * Improved search """ result = ChangelogParser.parse_content(content) assert [{:changelog_entry, "2026-03-15", {:some, "New Features"}, items}] = result assert items == ["Added dark mode", "Improved search"] end test "parses date without title" do content = """ 2026-03-15 * Bug fix one * Bug fix two """ result = ChangelogParser.parse_content(content) assert [{:changelog_entry, "2026-03-15", :none, items}] = result assert items == ["Bug fix one", "Bug fix two"] end test "parses multiple entries in chronological order" do content = """ 2026-03-15 — Latest * Item A 2026-03-10 — Earlier * Item B * Item C """ result = ChangelogParser.parse_content(content) assert [ {:changelog_entry, "2026-03-15", {:some, "Latest"}, ["Item A"]}, {:changelog_entry, "2026-03-10", {:some, "Earlier"}, ["Item B", "Item C"]} ] = result end test "ignores non-matching lines" do content = """ Some random text 2026-03-15 — Release * Only item More random text """ result = ChangelogParser.parse_content(content) assert [{:changelog_entry, "2026-03-15", {:some, "Release"}, ["Only item"]}] = result end test "handles empty content" do assert [] = ChangelogParser.parse_content("") end test "handles em dash and en dash separators" do em_dash = "2026-03-15 — Em Dash Title\n* Item" en_dash = "2026-03-15 – En Dash Title\n* Item" [{:changelog_entry, _, {:some, "Em Dash Title"}, _}] = ChangelogParser.parse_content(em_dash) [{:changelog_entry, _, {:some, "En Dash Title"}, _}] = ChangelogParser.parse_content(en_dash) end test "items before any date header are ignored" do content = """ * Orphan item 2026-03-15 — Release * Proper item """ result = ChangelogParser.parse_content(content) assert [{:changelog_entry, "2026-03-15", {:some, "Release"}, ["Proper item"]}] = result end end describe "ToweropsWeb.ChangelogParser.parse/0 integration" do test "parses the actual changelog file" do entries = ChangelogParser.parse() assert [_ | _] = entries first = List.first(entries) assert %{date: %Date{}, items: items} = first assert is_list(items) and items != [] end end end