Files
OpenNest/OpenNest.WinForms.Tests/ArchUnitsTests.cs
T
aj fc53c7732e fix(ui): format stock sizes invariantly and bound validation notices
Address Task 3b quality review:
- FormatSize now emits invariant decimal notation so a comma-decimal
  locale cannot produce stock text its own invariant parser rejects.
- Validation notices embed a bounded single-line preview instead of the
  full cell value.
- Documented GetPlateOptions' all-or-nothing throwing contract.
- STA test helpers run the worker as a background thread with a
  diagnostic timeout message; added a de-DE fractional stock round-trip
  regression.
2026-09-29 23:29:20 -04:00

67 lines
2.3 KiB
C#

using System.Drawing;
using System.Globalization;
using System.Reflection;
using System.Runtime.ExceptionServices;
using System.Text.RegularExpressions;
using System.Windows.Forms;
namespace OpenNest.WinForms.Tests;
public class ArchUnitsTests
{
[Fact]
public void ArchitecturalRegexHasExplicitTimeout()
{
var regex = Assert.IsType<Regex>(typeof(ArchUnits)
.GetField("UnitRegex", BindingFlags.Static | BindingFlags.NonPublic)!.GetValue(null));
Assert.Equal(TimeSpan.FromMilliseconds(250), regex.MatchTimeout);
Assert.Equal(RegexOptions.None, regex.Options);
}
[Theory]
[InlineData("5' 6.5\"", 66.5)]
[InlineData("2 feet 3 1/2 inches", 27.5)]
[InlineData("1-1/2\"", 1.5)]
[InlineData("48", 48)]
[InlineData("", 0)]
public void OrdinaryArchitecturalInputsKeepTheirMeaning(string input, double expected)
{
var original = CultureInfo.CurrentCulture;
try
{
CultureInfo.CurrentCulture = CultureInfo.InvariantCulture;
Assert.Equal(expected, ArchUnits.ParseToInches(input));
}
finally { CultureInfo.CurrentCulture = original; }
}
[Fact]
public void InvalidFieldIsRedAndNaNAndCorrectionRestoresIt() => RunSta(() =>
{
using var field = new TextBox { Text = "invalid dimension" };
Assert.True(double.IsNaN(ArchUnits.GetLengthInches(field)));
Assert.Equal(Color.Red, field.ForeColor);
field.Text = "12\"";
Assert.Equal(12, ArchUnits.GetLengthInches(field));
Assert.Equal(SystemColors.WindowText, field.ForeColor);
});
// Actual timeout execution is covered by the shared Regex mechanism in FractionTests;
// these desktop tests deliberately avoid timing-sensitive oversized-input fixtures.
internal static void RunSta(Action action)
{
Exception? error = null;
var thread = new Thread(() =>
{
try { action(); }
catch (Exception ex) { error = ex; }
})
{ IsBackground = true };
thread.SetApartmentState(ApartmentState.STA);
thread.Start();
Assert.True(thread.Join(TimeSpan.FromSeconds(15)), "The STA test did not complete.");
if (error != null)
ExceptionDispatchInfo.Capture(error).Throw();
}
}