|
| 1 | +// AgentContextStalenessTests — the staleness-nudge feature (port of the TS |
| 2 | +// agent-context-staleness wiring). |
| 3 | +// |
| 4 | +// Three things are exercised: |
| 5 | +// 1. The stamp — `dotnet meta agent-docs` writes a `generatedBy` into the manifest. |
| 6 | +// 2. The pure decision — AgentContextScaffold.AgentContextStaleness(manifest, current): |
| 7 | +// null manifest -> null (no agent context here) |
| 8 | +// manifest.GeneratedBy == cur -> null (in sync; exact equality on purpose) |
| 9 | +// differs / null GeneratedBy -> a one-line nudge naming both versions + agent-docs |
| 10 | +// 3. The version source — the installed-assembly version is read, never hardcoded. |
| 11 | + |
| 12 | +using System.Text.Json; |
| 13 | +using MetaObjects.AgentContext; |
| 14 | +using MetaObjects.Cli; |
| 15 | +using Xunit; |
| 16 | + |
| 17 | +namespace MetaObjects.Cli.Tests; |
| 18 | + |
| 19 | +public sealed class AgentContextStalenessTests |
| 20 | +{ |
| 21 | + // ---- 1. the stamp ------------------------------------------------------- |
| 22 | + |
| 23 | + [Fact] |
| 24 | + public void AgentDocs_stamps_generatedBy_into_the_manifest() |
| 25 | + { |
| 26 | + var tmp = Path.Combine(Path.GetTempPath(), "meta-stale-" + Guid.NewGuid().ToString("N")); |
| 27 | + Directory.CreateDirectory(tmp); |
| 28 | + try |
| 29 | + { |
| 30 | + // A *.csproj triggers the csharp-server stack auto-detection. |
| 31 | + File.WriteAllText(Path.Combine(tmp, "App.csproj"), "<Project />"); |
| 32 | + |
| 33 | + var exit = AgentDocsCommand.Run(new[] { "--out", tmp }); |
| 34 | + Assert.Equal(0, exit); |
| 35 | + |
| 36 | + var manifestPath = Path.Combine(tmp, AgentContextScaffold.ManifestPath); |
| 37 | + Assert.True(File.Exists(manifestPath), "manifest was not written"); |
| 38 | + |
| 39 | + using var doc = JsonDocument.Parse(File.ReadAllText(manifestPath)); |
| 40 | + Assert.True(doc.RootElement.TryGetProperty("generatedBy", out var gb), |
| 41 | + "manifest is missing the generatedBy property"); |
| 42 | + var stamped = gb.GetString(); |
| 43 | + Assert.False(string.IsNullOrEmpty(stamped)); |
| 44 | + // It must be the live installed version, not a literal. |
| 45 | + Assert.Equal(AgentContextStalenessCheck.CurrentVersion(), stamped); |
| 46 | + } |
| 47 | + finally |
| 48 | + { |
| 49 | + try { Directory.Delete(tmp, recursive: true); } catch { } |
| 50 | + } |
| 51 | + } |
| 52 | + |
| 53 | + // ---- 2. the pure decision ---------------------------------------------- |
| 54 | + |
| 55 | + [Fact] |
| 56 | + public void Null_manifest_is_not_stale() |
| 57 | + { |
| 58 | + Assert.Null(AgentContextScaffold.AgentContextStaleness(null, "1.2.3")); |
| 59 | + } |
| 60 | + |
| 61 | + [Fact] |
| 62 | + public void Matching_generatedBy_is_not_stale() |
| 63 | + { |
| 64 | + var m = ManifestWith("1.2.3"); |
| 65 | + Assert.Null(AgentContextScaffold.AgentContextStaleness(m, "1.2.3")); |
| 66 | + } |
| 67 | + |
| 68 | + [Fact] |
| 69 | + public void Differing_generatedBy_nudges_naming_both_versions() |
| 70 | + { |
| 71 | + var m = ManifestWith("1.0.0"); |
| 72 | + var msg = AgentContextScaffold.AgentContextStaleness(m, "2.0.0"); |
| 73 | + Assert.NotNull(msg); |
| 74 | + Assert.Contains("1.0.0", msg); |
| 75 | + Assert.Contains("2.0.0", msg); |
| 76 | + Assert.Contains("dotnet meta agent-docs", msg); |
| 77 | + } |
| 78 | + |
| 79 | + [Fact] |
| 80 | + public void Null_generatedBy_nudges_with_older_phrasing() |
| 81 | + { |
| 82 | + var m = ManifestWith(null); |
| 83 | + var msg = AgentContextScaffold.AgentContextStaleness(m, "2.0.0"); |
| 84 | + Assert.NotNull(msg); |
| 85 | + Assert.Contains("an older MetaObjects", msg); |
| 86 | + Assert.Contains("2.0.0", msg); |
| 87 | + Assert.Contains("dotnet meta agent-docs", msg); |
| 88 | + } |
| 89 | + |
| 90 | + // Even a prerelease/build-metadata difference nudges (exact equality, not semver). |
| 91 | + [Fact] |
| 92 | + public void Any_drift_nudges_no_semver_parsing() |
| 93 | + { |
| 94 | + var m = ManifestWith("1.2.3"); |
| 95 | + Assert.NotNull(AgentContextScaffold.AgentContextStaleness(m, "1.2.3-rc.1")); |
| 96 | + } |
| 97 | + |
| 98 | + // ---- 3. version source -------------------------------------------------- |
| 99 | + |
| 100 | + [Fact] |
| 101 | + public void CurrentVersion_reads_a_nonempty_value_from_the_assembly() |
| 102 | + { |
| 103 | + var v = AgentContextStalenessCheck.CurrentVersion(); |
| 104 | + Assert.False(string.IsNullOrEmpty(v)); |
| 105 | + } |
| 106 | + |
| 107 | + // ---- helper ------------------------------------------------------------- |
| 108 | + |
| 109 | + private static AgentContextScaffold.Manifest ManifestWith(string? generatedBy) => |
| 110 | + new(1, generatedBy, Array.Empty<string>(), Array.Empty<string>(), |
| 111 | + new Dictionary<string, string>()); |
| 112 | +} |
0 commit comments