Migrate three pure-function modules from Elixir to Gleam: - polling_offset: deterministic hash-based polling offset (pure Gleam, no FFI) - changelog_parser: text parsing logic in Gleam, thin Elixir wrapper for File I/O - user_agent_parser: regex-based UA parsing in Gleam with Erlang FFI for atom-keyed map conversion Add gleam_regexp dependency for regex support in Gleam modules. Update all call sites and tests to use Gleam module atoms. Reviewed-on: graham/towerops-web#103
103 lines
2.8 KiB
Elixir
103 lines
2.8 KiB
Elixir
defmodule ToweropsWeb.GleamChangelogParserTest do
|
||
use ExUnit.Case, async: true
|
||
|
||
# Gleam module: :towerops_web@changelog_parser
|
||
|
||
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 = :towerops_web@changelog_parser.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 = :towerops_web@changelog_parser.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 = :towerops_web@changelog_parser.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 = :towerops_web@changelog_parser.parse_content(content)
|
||
|
||
assert [{:changelog_entry, "2026-03-15", {:some, "Release"}, ["Only item"]}] = result
|
||
end
|
||
|
||
test "handles empty content" do
|
||
assert [] = :towerops_web@changelog_parser.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"}, _}] =
|
||
:towerops_web@changelog_parser.parse_content(em_dash)
|
||
|
||
[{:changelog_entry, _, {:some, "En Dash Title"}, _}] =
|
||
:towerops_web@changelog_parser.parse_content(en_dash)
|
||
end
|
||
|
||
test "items before any date header are ignored" do
|
||
content = """
|
||
* Orphan item
|
||
2026-03-15 — Release
|
||
* Proper item
|
||
"""
|
||
|
||
result = :towerops_web@changelog_parser.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 = ToweropsWeb.ChangelogParser.parse()
|
||
|
||
assert [_ | _] = entries
|
||
|
||
first = List.first(entries)
|
||
assert %{date: %Date{}, items: items} = first
|
||
assert is_list(items)
|
||
end
|
||
end
|
||
end
|