diff --git a/Sources/AngouriMath/Docs/Contributing/Packaging.md b/Sources/AngouriMath/Docs/Contributing/Packaging.md
index fe99ba11f..6effd0769 100644
--- a/Sources/AngouriMath/Docs/Contributing/Packaging.md
+++ b/Sources/AngouriMath/Docs/Contributing/Packaging.md
@@ -144,7 +144,10 @@ typeof(AngouriMath.Entity).Assembly # measured by reflection on the built ne
ANTLR-generated lexer and parser default their error streams to it.) This said 13 until
`System.Text.Json` arrived with `Core/Serialization` — a framework assembly, so no consumer's
restore changed, and nothing noticed for the same reason. `KernelDependenciesTest` is the gate §7
- asked for and now holds both counts.
+ asked for. It asserts the **third-party** set exactly, in both directions, and the framework ones
+ only as a set nothing may exceed — which framework assemblies a build resolves depends on the
+ target framework leg, and `netstandard` appears on the netstandard2.0 one and not on `net10.0`.
+ A leg resolving fewer of them is not a packaging event; one pulling in something new is.
**Twelve capabilities × 68 node types is the reason the kernel is one assembly.** A capability written
as an abstract member of `Entity` cannot be in a different package than `Entity`, whatever anyone
diff --git a/Sources/Tests/UnitTests/Core/KernelDependenciesTest.cs b/Sources/Tests/UnitTests/Core/KernelDependenciesTest.cs
index 77e798044..14d1a18fd 100644
--- a/Sources/Tests/UnitTests/Core/KernelDependenciesTest.cs
+++ b/Sources/Tests/UnitTests/Core/KernelDependenciesTest.cs
@@ -56,6 +56,22 @@ public sealed class KernelDependenciesTest
"Antlr4.Runtime.Standard",
};
+ ///
+ /// Whether a reference is part of the framework rather than something a consumer restores.
+ ///
+ ///
+ /// netstandard is on this list because it is the reference assembly the
+ /// netstandard2.0 leg resolves against, and it appears or does not depending on which leg
+ /// is loaded. The first version of this file asserted an exact set that had been measured
+ /// on one leg, passed locally on net10.0, and failed the C# Test workflow on
+ /// exactly that name. Which framework assemblies appear is a fact about the build leg;
+ /// which third-party ones appear is the packaging decision, and only the second is
+ /// asserted exactly.
+ ///
+ private static bool IsFramework(string name) =>
+ name.StartsWith("System.", System.StringComparison.Ordinal)
+ || name is "System" or "netstandard" or "mscorlib";
+
private static string[] Referenced() =>
typeof(MathS).Assembly
.GetReferencedAssemblies()
@@ -63,53 +79,49 @@ private static string[] Referenced() =>
.OrderBy(name => name, System.StringComparer.Ordinal)
.ToArray();
+ ///
+ /// The framework assemblies seen so far, across the legs this has run on. A superset rather
+ /// than an equality: a leg that resolves fewer of them is not a packaging event, while one
+ /// that pulls in something new — System.Text.Json arriving with
+ /// Core/Serialization is the case in point — is exactly what wants seeing.
+ ///
+ private static readonly string[] Framework =
+ {
+ "System.Collections",
+ "System.Collections.Concurrent",
+ "System.Console",
+ "System.Linq",
+ "System.Linq.Expressions",
+ "System.Memory",
+ "System.Runtime",
+ "System.Runtime.Numerics",
+ "System.Text.Json",
+ "System.Threading",
+ "netstandard",
+ };
+
[Fact]
public void TheKernelReferencesNothingItIsNotRecordedAsReferencing()
{
- var expected = new[]
- {
- "Antlr4.Runtime.Standard",
- "GenericTensor",
- "HonkSharp",
- "Numbers",
- "System.Collections",
- "System.Collections.Concurrent",
- "System.Console",
- "System.Linq",
- "System.Linq.Expressions",
- "System.Memory",
- "System.Runtime",
- "System.Runtime.Numerics",
- "System.Text.Json",
- "System.Threading",
- };
-
- var actual = Referenced();
+ var recorded = Framework.Concat(ThirdParty).ToList();
+ var added = Referenced().Except(recorded).ToList();
- var added = actual.Except(expected).ToList();
Assert.True(added.Count == 0,
$"the kernel references {added.Count} assemblies this list does not record: "
+ string.Join(", ", added)
+ ". Adding one is a packaging decision — see Docs/Contributing/Packaging.md §11 — "
+ "so record it here in the same change that adds it.");
-
- // The other direction, so the list cannot outlive what it describes: a dependency that
- // goes away should be deleted here rather than left asserting nothing.
- var gone = expected.Except(actual).ToList();
- Assert.True(gone.Count == 0,
- $"{gone.Count} assemblies are recorded here and no longer referenced, and should be "
- + "deleted: " + string.Join(", ", gone));
}
///
- /// The number that matters to a consumer, separately from the framework ones, because it
- /// is what a restore actually fetches.
+ /// The set that matters to a consumer, separately from the framework ones, because it is
+ /// what a restore actually fetches. Asserted exactly, in both directions.
///
[Fact]
public void TheThirdPartyDependenciesAreTheFourThatWereAgreed()
{
var actual = Referenced()
- .Where(name => !name.StartsWith("System.", System.StringComparison.Ordinal))
+ .Where(name => !IsFramework(name))
.OrderBy(name => name, System.StringComparer.Ordinal)
.ToArray();