fix: review fixes — culture-invariant formatting, sealed config, threshold boundary

- Use CultureInfo.InvariantCulture in CoordinateFormatter, SpeedClassifier,
  and CincinnatiPreambleWriter to prevent locale-dependent G-code output
- Make CincinnatiPostConfig sealed per spec
- Fix SpeedClassifier.Classify threshold to >= (matching spec)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-03-22 23:45:22 -04:00
parent ca8a0942ab
commit 8efdc8720c
5 changed files with 8 additions and 6 deletions
@@ -88,7 +88,7 @@ namespace OpenNest.Posts.Cincinnati
/// Configuration for Cincinnati post processor. /// Configuration for Cincinnati post processor.
/// Defines machine-specific parameters, output format, and cutting strategies. /// Defines machine-specific parameters, output format, and cutting strategies.
/// </summary> /// </summary>
public class CincinnatiPostConfig public sealed class CincinnatiPostConfig
{ {
/// <summary> /// <summary>
/// Gets or sets the configuration name/identifier. /// Gets or sets the configuration name/identifier.
@@ -24,7 +24,7 @@ public sealed class CincinnatiPreambleWriter
{ {
w.WriteLine(CoordinateFormatter.Comment($"NEST {nestName}")); w.WriteLine(CoordinateFormatter.Comment($"NEST {nestName}"));
w.WriteLine(CoordinateFormatter.Comment($"CONFIGURATION - {_config.ConfigurationName}")); w.WriteLine(CoordinateFormatter.Comment($"CONFIGURATION - {_config.ConfigurationName}"));
w.WriteLine(CoordinateFormatter.Comment(DateTime.Now.ToString("MM-dd-yyyy hh:mm:ss tt"))); w.WriteLine(CoordinateFormatter.Comment(DateTime.Now.ToString("MM-dd-yyyy hh:mm:ss tt", System.Globalization.CultureInfo.InvariantCulture)));
if (!string.IsNullOrEmpty(materialDescription)) if (!string.IsNullOrEmpty(materialDescription))
w.WriteLine(CoordinateFormatter.Comment($"Material = {materialDescription}")); w.WriteLine(CoordinateFormatter.Comment($"Material = {materialDescription}"));
@@ -13,7 +13,8 @@ namespace OpenNest.Posts.Cincinnati
public string FormatCoord(double value) public string FormatCoord(double value)
{ {
return System.Math.Round(value, _accuracy).ToString(_format); return System.Math.Round(value, _accuracy)
.ToString(_format, System.Globalization.CultureInfo.InvariantCulture);
} }
public static string Comment(string text) => $"( {text} )"; public static string Comment(string text) => $"( {text} )";
+2 -2
View File
@@ -8,7 +8,7 @@ namespace OpenNest.Posts.Cincinnati
public string Classify(double contourLength, double sheetDiagonal) public string Classify(double contourLength, double sheetDiagonal)
{ {
var ratio = contourLength / sheetDiagonal; var ratio = contourLength / sheetDiagonal;
if (ratio > FastThreshold) return "FAST"; if (ratio >= FastThreshold) return "FAST";
if (ratio <= SlowThreshold) return "SLOW"; if (ratio <= SlowThreshold) return "SLOW";
return "MEDIUM"; return "MEDIUM";
} }
@@ -22,7 +22,7 @@ namespace OpenNest.Posts.Cincinnati
{ {
// Cincinnati convention: no leading zero for values < 1 (e.g., ".8702" not "0.8702") // Cincinnati convention: no leading zero for values < 1 (e.g., ".8702" not "0.8702")
var rounded = System.Math.Round(value, 4); var rounded = System.Math.Round(value, 4);
var str = rounded.ToString("0.####"); var str = rounded.ToString("0.####", System.Globalization.CultureInfo.InvariantCulture);
if (rounded > 0 && rounded < 1 && str.StartsWith("0.")) if (rounded > 0 && rounded < 1 && str.StartsWith("0."))
return str.Substring(1); return str.Substring(1);
return str; return str;
@@ -6,7 +6,8 @@ public class SpeedClassifierTests
{ {
[Theory] [Theory]
[InlineData(20.0, 10.0, "FAST")] [InlineData(20.0, 10.0, "FAST")]
[InlineData(5.0, 10.0, "MEDIUM")] [InlineData(5.0, 10.0, "FAST")]
[InlineData(4.9, 10.0, "MEDIUM")]
[InlineData(0.5, 10.0, "SLOW")] [InlineData(0.5, 10.0, "SLOW")]
public void Classify_ReturnsExpectedClass(double contourLength, double sheetDiagonal, string expected) public void Classify_ReturnsExpectedClass(double contourLength, double sheetDiagonal, string expected)
{ {