zscripts-token-savers/tests/PlainTextTwins.Tests.ps1
KellyMichels 8689b57a60 docs(changelog): give every shipped release its own section, and generate the twin
The changelog said nothing had been released since 1.0.0. Twenty-two builds
had shipped. Twenty-one entries sat under "## Unreleased" in a file with
exactly two headings, so a reader at any tag found no section for the version
they were holding.

Which release carried which entry is DERIVED, not guessed: for every line in
the region, the commit that introduced it, then the earliest tag containing
that commit. That yields seven releases - .22, .21, .20, .19, .14, .8 and .0.
No entry text changed. A verification pass compares the multiset of
non-heading lines before and after and refuses to write if anything was lost,
gained or duplicated; entries move under their release, so it compares as a
multiset rather than in order.

CHANGELOG.txt was kept BY HAND and drifted the moment the .md was
reorganised, which is the failure the plain-text-twin rule exists to prevent.
readme_txt.py becomes plaintext_twins.py and renders every pair. It also
drops <!-- --> markers, invisible in markdown and stray punctuation in a text
file - that is the whole of README.txt's diff.

The --check that keeps twins honest was never run. readme_txt.py shipped one
and its docstring claimed "the test suite runs --check"; nothing invoked it,
so a twin could disagree with its markdown indefinitely.
tests/PlainTextTwins.Tests.ps1 runs it.

That test skipped on its first run while claiming to pass: -Skip is evaluated
during DISCOVERY, before BeforeAll, so the python lookup left the flag $null.
Resolved in BeforeDiscovery, and when python really is absent the result is
INCONCLUSIVE rather than a green tick for a check that never happened.

Mutation-checked: appending one line to CHANGELOG.txt fails "every twin is in
sync with its markdown", and only that test.

tests: 243 passed, 0 failed, 1 skipped (the no-python reporter, correctly).
2026-08-31 18:18:58 -05:00

69 lines
2.8 KiB
PowerShell

# The .txt twins are generated, and this is what makes that true.
#
# Invoke-Pester .\tests
#
# scripts/plaintext_twins.py has always shipped a --check mode, and its
# docstring claimed "the test suite runs --check". Nothing ran it. So README.txt
# could drift from README.md silently, and CHANGELOG.txt - which no generator
# covered at all - actually did.
#
# A twin that disagrees with the file it mirrors is worse than no twin: it is a
# second document that looks authoritative and is wrong.
# -Skip is evaluated during DISCOVERY, before BeforeAll runs, so a python
# lookup done in BeforeAll leaves the flag $null and the real check silently
# skips - which is how this test first "passed" while verifying nothing.
BeforeDiscovery {
$script:Python = $null
foreach ($candidate in @('python', 'python3', 'py')) {
$cmd = Get-Command $candidate -ErrorAction SilentlyContinue
if ($cmd) { $script:Python = $cmd.Source; break }
}
}
BeforeAll {
$script:RepoRoot = Split-Path -Parent $PSScriptRoot
$script:Generator = Join-Path $script:RepoRoot "scripts\plaintext_twins.py"
$script:Python = $null
foreach ($candidate in @('python', 'python3', 'py')) {
$cmd = Get-Command $candidate -ErrorAction SilentlyContinue
if ($cmd) { $script:Python = $cmd.Source; break }
}
}
Describe "plain-text twins" {
It "the generator is where the tests and the docs say it is" {
Test-Path -LiteralPath $script:Generator | Should -BeTrue
}
It "every .md that owes a twin has one" {
$pairs = Select-String -Path $script:Generator -Pattern '^\s*\("([^"]+\.md)",\s*"([^"]+\.txt)"\),' |
ForEach-Object { [pscustomobject]@{ Md = $_.Matches[0].Groups[1].Value; Txt = $_.Matches[0].Groups[2].Value } }
$pairs.Count | Should -BeGreaterThan 0 -Because "PAIRS in plaintext_twins.py is what this suite checks"
foreach ($p in $pairs) {
Test-Path -LiteralPath (Join-Path $script:RepoRoot $p.Md) | Should -BeTrue -Because "$($p.Md) is listed in PAIRS"
Test-Path -LiteralPath (Join-Path $script:RepoRoot $p.Txt) | Should -BeTrue -Because "$($p.Md) owes a twin at $($p.Txt)"
}
}
It "every twin is in sync with its markdown" -Skip:(-not $script:Python) {
Push-Location $script:RepoRoot
try {
$output = & $script:Python $script:Generator --check 2>&1
$code = $LASTEXITCODE
}
finally { Pop-Location }
$code | Should -Be 0 -Because ($output -join "`n")
}
It "reports the python that was missing rather than passing quietly" -Skip:([bool]$script:Python) {
# Not a pass. If this is the test you are reading, --check never ran:
# install python, or regenerate the twins by hand before shipping.
Set-ItResult -Inconclusive -Because "no python on PATH, so the twins were not verified"
}
}