Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ so moving a project cannot silently retarget a test.
- `test/CodoMetis.ValueRanges.EFCore.PostgreSQL.Tests/` — EF Core SQL translation tests (no database)
- `test/CodoMetis.ValueRanges.EFCore.PostgreSQL.NodaTime.Tests/` — NodaTime EF translation tests (no database)
- `test/CodoMetis.ValueRanges.EFCore.PostgreSQL.IntegrationTests/` — Live PostgreSQL via Testcontainers (needs Docker; Inconclusive without, but hard failure under CI=true). Covers BCL and NodaTime types. Authority on PostgreSQL semantics — run when changing translations or range algebra
- `test/CodoMetis.ValueRanges.Conventions.Tests/` — Repo-level conventions: changelog consistency, packaging metadata, value set contract compliance, EF mapping parity. Everything is discovered (projects by globbing `src/`, types by reflection), so adding a package or a type needs no edit here
- `test/CodoMetis.ValueRanges.Conventions.Tests/` — Repo-level conventions: changelog consistency, packaging metadata, release wiring, the SECURITY.md supported-versions table, value set contract compliance, EF mapping parity. Everything is discovered (projects by globbing `src/`, types by reflection), so adding a package or a type needs no edit here
- `docs/` — Agent docs (read relevant doc before starting work)

## Commands
Expand Down
4 changes: 2 additions & 2 deletions SECURITY.md
Original file line number Diff line number Diff line change
Expand Up @@ -51,8 +51,8 @@ remedy for those is to upgrade.

| Version | Supported |
|---|---|
| 6.1.x | ✅ |
| < 6.1 | ❌ |
| 6.2.x | ✅ |
| < 6.2 | ❌ |

## Where this package sits

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
using System.Text.RegularExpressions;

namespace CodoMetis.ValueRanges.Conventions.Tests;

/// <summary>
/// SECURITY.md promises fixes for "the latest released minor version" and tabulates which line that
/// is. The table is prose: nothing ties it to <c>Directory.Build.props</c>, so a release that bumps
/// the version and forgets the table leaves the policy pointing a reporter at a line that no longer
/// receives fixes. That is not hypothetical — 6.2.0 shipped with the table still saying 6.1.x. A
/// supported-versions table that is wrong is worse than none: it reads as a considered statement.
/// </summary>
[TestClass]
public sealed class SecurityPolicyConventionTests
{
private static FileInfo SecurityPolicy => new(Path.Combine(RepoLayout.Root.FullName, "SECURITY.md"));

/// <summary>"| 6.2.x | ✅ |" — the one line that receives fixes.</summary>
private static readonly Regex SupportedRow =
new(@"^\|\s*(?<major>\d+)\.(?<minor>\d+)\.x\s*\|\s*✅\s*\|", RegexOptions.Multiline);

/// <summary>"| &lt; 6.2 | ❌ |" — everything before it.</summary>
private static readonly Regex UnsupportedRow =
new(@"^\|\s*<\s*(?<major>\d+)\.(?<minor>\d+)\s*\|\s*❌\s*\|", RegexOptions.Multiline);

[TestMethod]
public void SecurityPolicy_Exists()
{
Assert.IsTrue(SecurityPolicy.Exists, $"No SECURITY.md at the repository root ({SecurityPolicy.FullName}).");
}

[TestMethod]
public void TheSupportedVersionsTable_NamesTheShippedMinor()
{
var text = File.ReadAllText(SecurityPolicy.FullName);
var shipped = Version.Parse(RepoLayout.ShippedVersion);
var expected = $"{shipped.Major}.{shipped.Minor}";

var supported = SupportedRow.Matches(text);

Assert.AreEqual(
1, supported.Count,
"SECURITY.md should have exactly one '| x.y.x | ✅ |' row — the policy is that fixes land "
+ "on the latest released minor only, so there is one supported line to name.");

var supportedLine = $"{supported[0].Groups["major"].Value}.{supported[0].Groups["minor"].Value}";

Assert.AreEqual(
expected, supportedLine,
$"SECURITY.md lists {supportedLine}.x as the supported line, but Directory.Build.props ships "
+ $"{shipped}. The table is part of the version bump: a reporter reads it to decide whether "
+ "their version still receives fixes.");

var unsupported = UnsupportedRow.Match(text);

Assert.IsTrue(
unsupported.Success,
"SECURITY.md should have a '| < x.y | ❌ |' row saying that everything before the supported "
+ "line is unmaintained.");

var unsupportedBelow = $"{unsupported.Groups["major"].Value}.{unsupported.Groups["minor"].Value}";

Assert.AreEqual(
expected, unsupportedBelow,
$"SECURITY.md says versions below {unsupportedBelow} are unsupported, but the supported line "
+ $"is {expected}.x — the two rows should meet at the same minor, or a range is left "
+ "described by neither.");
}
}
Loading