CultMath GLSL tests: overloads compared by signature; the two-file header contract pinned
EveryPublicFunctionIsLowered compares (name, parameter types) after the lowering's own step 3, so a dropped overload such as cultmath_pcg3d(vec2) fails. TwoFileHeaderContract pins distinct guards, the MIT and MPL-2.0 provenance labels, and the MIT file's pointer to CultMath.Phacelle.glsl. GlslLowering exposes step 3 as LowerTypeNames; output unchanged. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
parent
6d0a0c147d
commit
e877b708be
2 changed files with 40 additions and 7 deletions
|
|
@ -73,10 +73,7 @@ internal static class GlslLowering
|
|||
source = Regex.Replace(source, @"(?ms)^\w+ \w+\([^)]*\b(Texture2D|SamplerState)\b[^)]*\)\s*\{.*?^\}[ \t]*$", string.Empty);
|
||||
|
||||
// 3. Type names: floatN, intN, uintN and boolN become vecN, ivecN, uvecN and bvecN.
|
||||
source = Regex.Replace(source, @"\bfloat([234])\b", "vec$1");
|
||||
source = Regex.Replace(source, @"\bint([234])\b", "ivec$1");
|
||||
source = Regex.Replace(source, @"\buint([234])\b", "uvec$1");
|
||||
source = Regex.Replace(source, @"\bbool([234])\b", "bvec$1");
|
||||
source = LowerTypeNames(source);
|
||||
|
||||
// 4. File-scope `static const` becomes `const`.
|
||||
source = Regex.Replace(source, @"(?m)^static const ", "const ");
|
||||
|
|
@ -103,6 +100,15 @@ internal static class GlslLowering
|
|||
return provenance + "\n#ifndef " + guard + "\n#define " + guard + "\n" + source.Trim('\n') + "\n\n#endif\n";
|
||||
}
|
||||
|
||||
/// <summary>Step 3 alone; GlslMirrorTests maps the HLSL signatures with it to compare overloads.</summary>
|
||||
internal static string LowerTypeNames(string source)
|
||||
{
|
||||
source = Regex.Replace(source, @"\bfloat([234])\b", "vec$1");
|
||||
source = Regex.Replace(source, @"\bint([234])\b", "ivec$1");
|
||||
source = Regex.Replace(source, @"\buint([234])\b", "uvec$1");
|
||||
return Regex.Replace(source, @"\bbool([234])\b", "bvec$1");
|
||||
}
|
||||
|
||||
private static readonly Regex Cast = new(@"\((float|int|uint)\)");
|
||||
|
||||
private static string LowerCasts(string source)
|
||||
|
|
|
|||
|
|
@ -61,14 +61,21 @@ public sealed class GlslMirrorTests
|
|||
|
||||
private static readonly Regex Definition = new(@"(?m)^\w+\s+(cultmath_\w+)\s*\(([^)]*)\)");
|
||||
|
||||
// A definition's signature, its name and parameter types, so an overload counts on its own:
|
||||
// "cultmath_pcg3d(vec2)". HLSL type names are mapped by the lowering's own step 3.
|
||||
private static string Signature(Match definition) =>
|
||||
definition.Groups[1].Value + "(" + string.Join(", ", definition.Groups[2].Value
|
||||
.Split(',', StringSplitOptions.TrimEntries | StringSplitOptions.RemoveEmptyEntries)
|
||||
.Select(parameter => GlslLowering.LowerTypeNames(string.Join(' ', Regex.Split(parameter, @"\s+")[..^1])))) + ")";
|
||||
|
||||
[Fact]
|
||||
public void EveryPublicFunctionIsLowered()
|
||||
{
|
||||
var lowered = Lowered;
|
||||
var hlsl = Definition.Matches(Hlsl).Where(m => !Regex.IsMatch(m.Groups[2].Value, @"\b(Texture2D|SamplerState)\b"))
|
||||
.Select(m => m.Groups[1].Value).ToHashSet();
|
||||
var glsl = lowered.SelectMany(output => Definition.Matches(output.Text)).Select(m => m.Groups[1].Value).ToHashSet();
|
||||
Assert.Contains("cultmath_snoise", glsl);
|
||||
.Select(Signature).ToHashSet();
|
||||
var glsl = lowered.SelectMany(output => Definition.Matches(output.Text)).Select(Signature).ToHashSet();
|
||||
Assert.Contains("cultmath_pcg3d(vec2)", glsl);
|
||||
Assert.True(hlsl.SetEquals(glsl), "HLSL only: " + string.Join(", ", hlsl.Except(glsl)) + "; GLSL only: " + string.Join(", ", glsl.Except(hlsl)));
|
||||
|
||||
// The MPL-2.0 code is in its own file and nowhere in the MIT library.
|
||||
|
|
@ -81,6 +88,26 @@ public sealed class GlslMirrorTests
|
|||
}
|
||||
}
|
||||
|
||||
// The two-file contract a consumer relies on when it concatenates CultMath.Phacelle.glsl after
|
||||
// CultMath.glsl: distinct guards (a shared one would hide the second file's body), each provenance
|
||||
// line naming its file's licence, and the MIT file pointing at the one that holds cultmath_phacelle.
|
||||
[Fact]
|
||||
public void TwoFileHeaderContract()
|
||||
{
|
||||
var lowered = Lowered;
|
||||
var guards = lowered.Select(output => Regex.Match(output.Text, @"^[^\n]*\n#ifndef (\w+)\n#define \1\n").Groups[1].Value).ToArray();
|
||||
Assert.All(guards, guard => Assert.NotEqual(string.Empty, guard));
|
||||
Assert.Equal(guards.Length, guards.Distinct().Count());
|
||||
|
||||
var library = lowered.Single(output => output.File == "CultMath.glsl").Text.Split('\n')[0];
|
||||
var phacelle = lowered.Single(output => output.File == "CultMath.Phacelle.glsl").Text.Split('\n')[0];
|
||||
Assert.Contains(" MIT.", library);
|
||||
Assert.DoesNotContain("MPL", library);
|
||||
Assert.Contains("cultmath_phacelle is in CultMath.Phacelle.glsl", library);
|
||||
Assert.Contains(" MPL-2.0;", phacelle);
|
||||
Assert.DoesNotContain("MIT", phacelle);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void GoldenFixtureMatchesCSharp()
|
||||
{
|
||||
|
|
|
|||
Loading…
Reference in a new issue