Add comprehensive test coverage for many controls (#737)
Co-authored-by: rabbitism <14807942+rabbitism@users.noreply.github.com> Co-authored-by: Copilot <198982749+Copilot@users.noreply.github.com>
This commit is contained in:
@@ -0,0 +1,334 @@
|
||||
using Avalonia.Controls;
|
||||
using Avalonia.Headless.XUnit;
|
||||
using Avalonia.Input;
|
||||
using Avalonia.Threading;
|
||||
using Ursa.Controls;
|
||||
|
||||
namespace HeadlessTest.Ursa.Controls.NumericUpDownTests;
|
||||
|
||||
public class NumericUpDownBaseTests
|
||||
{
|
||||
[AvaloniaFact]
|
||||
public void NumericIntUpDown_Should_Initialize_With_Default_Values()
|
||||
{
|
||||
var window = new Window();
|
||||
var numericUpDown = new NumericIntUpDown();
|
||||
window.Content = numericUpDown;
|
||||
window.Show();
|
||||
|
||||
Assert.Null(numericUpDown.Value);
|
||||
Assert.Equal(int.MaxValue, numericUpDown.Maximum);
|
||||
Assert.Equal(int.MinValue, numericUpDown.Minimum);
|
||||
Assert.Equal(1, numericUpDown.Step);
|
||||
Assert.True(numericUpDown.AllowSpin);
|
||||
Assert.False(numericUpDown.IsReadOnly);
|
||||
}
|
||||
|
||||
[AvaloniaFact]
|
||||
public void NumericIntUpDown_Should_Set_And_Get_Value()
|
||||
{
|
||||
var window = new Window();
|
||||
var numericUpDown = new NumericIntUpDown();
|
||||
window.Content = numericUpDown;
|
||||
window.Show();
|
||||
|
||||
numericUpDown.Value = 42;
|
||||
Assert.Equal(42, numericUpDown.Value);
|
||||
|
||||
numericUpDown.Value = null;
|
||||
Assert.Null(numericUpDown.Value);
|
||||
}
|
||||
|
||||
[AvaloniaFact]
|
||||
public void NumericIntUpDown_Should_Clamp_Value_To_Range()
|
||||
{
|
||||
var window = new Window();
|
||||
var numericUpDown = new NumericIntUpDown
|
||||
{
|
||||
Minimum = 0,
|
||||
Maximum = 100
|
||||
};
|
||||
window.Content = numericUpDown;
|
||||
window.Show();
|
||||
|
||||
// Test value above maximum
|
||||
numericUpDown.Value = 150;
|
||||
Assert.Equal(100, numericUpDown.Value);
|
||||
|
||||
// Test value below minimum
|
||||
numericUpDown.Value = -50;
|
||||
Assert.Equal(0, numericUpDown.Value);
|
||||
|
||||
// Test value within range
|
||||
numericUpDown.Value = 50;
|
||||
Assert.Equal(50, numericUpDown.Value);
|
||||
}
|
||||
|
||||
[AvaloniaFact]
|
||||
public void NumericIntUpDown_Should_Increase_Value_By_Step()
|
||||
{
|
||||
var window = new Window();
|
||||
var numericUpDown = new NumericIntUpDown
|
||||
{
|
||||
Value = 10,
|
||||
Step = 5,
|
||||
Maximum = 100
|
||||
};
|
||||
window.Content = numericUpDown;
|
||||
window.Show();
|
||||
|
||||
// Test increase
|
||||
numericUpDown.Value = 10;
|
||||
var method = typeof(NumericIntUpDown).GetMethod("Increase", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance);
|
||||
method?.Invoke(numericUpDown, null);
|
||||
|
||||
Assert.Equal(15, numericUpDown.Value);
|
||||
}
|
||||
|
||||
[AvaloniaFact]
|
||||
public void NumericIntUpDown_Should_Decrease_Value_By_Step()
|
||||
{
|
||||
var window = new Window();
|
||||
var numericUpDown = new NumericIntUpDown
|
||||
{
|
||||
Value = 10,
|
||||
Step = 5,
|
||||
Minimum = 0
|
||||
};
|
||||
window.Content = numericUpDown;
|
||||
window.Show();
|
||||
|
||||
// Test decrease
|
||||
var method = typeof(NumericIntUpDown).GetMethod("Decrease", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance);
|
||||
method?.Invoke(numericUpDown, null);
|
||||
|
||||
Assert.Equal(5, numericUpDown.Value);
|
||||
}
|
||||
|
||||
[AvaloniaFact]
|
||||
public void NumericIntUpDown_Should_Not_Exceed_Maximum_When_Increasing()
|
||||
{
|
||||
var window = new Window();
|
||||
var numericUpDown = new NumericIntUpDown
|
||||
{
|
||||
Value = 95,
|
||||
Step = 10,
|
||||
Maximum = 100
|
||||
};
|
||||
window.Content = numericUpDown;
|
||||
window.Show();
|
||||
|
||||
var method = typeof(NumericIntUpDown).GetMethod("Increase", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance);
|
||||
method?.Invoke(numericUpDown, null);
|
||||
|
||||
Assert.Equal(100, numericUpDown.Value);
|
||||
}
|
||||
|
||||
[AvaloniaFact]
|
||||
public void NumericIntUpDown_Should_Not_Go_Below_Minimum_When_Decreasing()
|
||||
{
|
||||
var window = new Window();
|
||||
var numericUpDown = new NumericIntUpDown
|
||||
{
|
||||
Value = 5,
|
||||
Step = 10,
|
||||
Minimum = 0
|
||||
};
|
||||
window.Content = numericUpDown;
|
||||
window.Show();
|
||||
|
||||
var method = typeof(NumericIntUpDown).GetMethod("Decrease", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance);
|
||||
method?.Invoke(numericUpDown, null);
|
||||
|
||||
Assert.Equal(0, numericUpDown.Value);
|
||||
}
|
||||
|
||||
[AvaloniaFact]
|
||||
public void NumericIntUpDown_Should_Fire_ValueChanged_Event()
|
||||
{
|
||||
var window = new Window();
|
||||
var numericUpDown = new NumericIntUpDown();
|
||||
window.Content = numericUpDown;
|
||||
window.Show();
|
||||
|
||||
int? oldValue = null;
|
||||
int? newValue = null;
|
||||
bool eventFired = false;
|
||||
|
||||
numericUpDown.ValueChanged += (sender, e) =>
|
||||
{
|
||||
oldValue = e.OldValue;
|
||||
newValue = e.NewValue;
|
||||
eventFired = true;
|
||||
};
|
||||
|
||||
numericUpDown.Value = 42;
|
||||
|
||||
Assert.True(eventFired);
|
||||
Assert.Null(oldValue);
|
||||
Assert.Equal(42, newValue);
|
||||
}
|
||||
|
||||
[AvaloniaFact]
|
||||
public void NumericIntUpDown_Should_Handle_Null_Value()
|
||||
{
|
||||
var window = new Window();
|
||||
var numericUpDown = new NumericIntUpDown();
|
||||
window.Content = numericUpDown;
|
||||
window.Show();
|
||||
|
||||
numericUpDown.Value = null;
|
||||
Assert.Null(numericUpDown.Value);
|
||||
|
||||
// Test increasing from null should use minimum or zero
|
||||
var method = typeof(NumericIntUpDown).GetMethod("Increase", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance);
|
||||
method?.Invoke(numericUpDown, null);
|
||||
|
||||
// Should go to minimum value (int.MinValue) or zero depending on implementation
|
||||
Assert.NotNull(numericUpDown.Value);
|
||||
}
|
||||
|
||||
[AvaloniaFact]
|
||||
public void NumericIntUpDown_Should_Clear_Value()
|
||||
{
|
||||
var window = new Window();
|
||||
var numericUpDown = new NumericIntUpDown
|
||||
{
|
||||
Value = 42
|
||||
};
|
||||
window.Content = numericUpDown;
|
||||
window.Show();
|
||||
|
||||
numericUpDown.Clear();
|
||||
Assert.Null(numericUpDown.Value);
|
||||
}
|
||||
|
||||
[AvaloniaFact]
|
||||
public void NumericIntUpDown_Should_Respect_ReadOnly_Property()
|
||||
{
|
||||
var window = new Window();
|
||||
var numericUpDown = new NumericIntUpDown
|
||||
{
|
||||
Value = 10,
|
||||
IsReadOnly = true
|
||||
};
|
||||
window.Content = numericUpDown;
|
||||
window.Show();
|
||||
|
||||
// When read-only, increase/decrease should not work
|
||||
var initialValue = numericUpDown.Value;
|
||||
var increaseMethod = typeof(NumericIntUpDown).GetMethod("Increase", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance);
|
||||
increaseMethod?.Invoke(numericUpDown, null);
|
||||
|
||||
Assert.Equal(initialValue, numericUpDown.Value);
|
||||
}
|
||||
|
||||
[AvaloniaFact]
|
||||
public void NumericIntUpDown_Should_Coerce_Maximum_Below_Minimum()
|
||||
{
|
||||
var window = new Window();
|
||||
var numericUpDown = new NumericIntUpDown
|
||||
{
|
||||
Minimum = 100
|
||||
};
|
||||
window.Content = numericUpDown;
|
||||
window.Show();
|
||||
|
||||
// Setting maximum below minimum should coerce maximum to minimum
|
||||
numericUpDown.Maximum = 50;
|
||||
Assert.Equal(100, numericUpDown.Maximum);
|
||||
}
|
||||
|
||||
[AvaloniaFact]
|
||||
public void NumericIntUpDown_Should_Coerce_Minimum_Above_Maximum()
|
||||
{
|
||||
var window = new Window();
|
||||
var numericUpDown = new NumericIntUpDown
|
||||
{
|
||||
Maximum = 50
|
||||
};
|
||||
window.Content = numericUpDown;
|
||||
window.Show();
|
||||
|
||||
// Setting minimum above maximum should coerce minimum to maximum
|
||||
numericUpDown.Minimum = 100;
|
||||
Assert.Equal(50, numericUpDown.Minimum);
|
||||
}
|
||||
|
||||
[AvaloniaFact]
|
||||
public void NumericIntUpDown_Should_Parse_Text_Input()
|
||||
{
|
||||
var window = new Window();
|
||||
var numericUpDown = new NumericIntUpDown();
|
||||
window.Content = numericUpDown;
|
||||
window.Show();
|
||||
|
||||
// Test parsing valid integer
|
||||
var parseMethod = typeof(NumericIntUpDown).GetMethod("ParseText", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance);
|
||||
Assert.NotNull(parseMethod);
|
||||
|
||||
var parameters = new object[] { "123", 0 };
|
||||
var result = (bool)parseMethod.Invoke(numericUpDown, parameters);
|
||||
var parsedValue = (int)parameters[1];
|
||||
|
||||
Assert.True(result);
|
||||
Assert.Equal(123, parsedValue);
|
||||
}
|
||||
|
||||
[AvaloniaFact]
|
||||
public void NumericIntUpDown_Should_Handle_Invalid_Text_Input()
|
||||
{
|
||||
var window = new Window();
|
||||
var numericUpDown = new NumericIntUpDown();
|
||||
window.Content = numericUpDown;
|
||||
window.Show();
|
||||
|
||||
// Test parsing invalid text
|
||||
var parseMethod = typeof(NumericIntUpDown).GetMethod("ParseText", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance);
|
||||
Assert.NotNull(parseMethod);
|
||||
|
||||
var parameters = new object[] { "invalid", 0 };
|
||||
var result = (bool)parseMethod.Invoke(numericUpDown, parameters);
|
||||
|
||||
Assert.False(result);
|
||||
}
|
||||
|
||||
[AvaloniaFact]
|
||||
public void NumericIntUpDown_Should_Format_Value_To_String()
|
||||
{
|
||||
var window = new Window();
|
||||
var numericUpDown = new NumericIntUpDown();
|
||||
window.Content = numericUpDown;
|
||||
window.Show();
|
||||
|
||||
// Test value formatting
|
||||
var formatMethod = typeof(NumericIntUpDown).GetMethod("ValueToString", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance);
|
||||
Assert.NotNull(formatMethod);
|
||||
|
||||
var result = (string?)formatMethod.Invoke(numericUpDown, new object?[] { 123 });
|
||||
Assert.Equal("123", result);
|
||||
|
||||
// Test null value formatting
|
||||
result = (string?)formatMethod.Invoke(numericUpDown, new object?[] { null });
|
||||
Assert.Null(result);
|
||||
}
|
||||
|
||||
[AvaloniaFact]
|
||||
public void NumericIntUpDown_Should_Handle_Format_String()
|
||||
{
|
||||
var window = new Window();
|
||||
var numericUpDown = new NumericIntUpDown
|
||||
{
|
||||
FormatString = "D5", // Format with leading zeros
|
||||
Value = 42
|
||||
};
|
||||
window.Content = numericUpDown;
|
||||
window.Show();
|
||||
|
||||
var formatMethod = typeof(NumericIntUpDown).GetMethod("ValueToString", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance);
|
||||
Assert.NotNull(formatMethod);
|
||||
|
||||
var result = (string?)formatMethod.Invoke(numericUpDown, new object?[] { 42 });
|
||||
Assert.Equal("00042", result);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,447 @@
|
||||
using Avalonia.Controls;
|
||||
using Avalonia.Headless.XUnit;
|
||||
using Avalonia.Threading;
|
||||
using Ursa.Controls;
|
||||
|
||||
namespace HeadlessTest.Ursa.Controls.NumericUpDownTests;
|
||||
|
||||
/// <summary>
|
||||
/// Simplified and focused tests for NumericUpDown controls that cover core functionality
|
||||
/// </summary>
|
||||
public class NumericUpDownCoreTests
|
||||
{
|
||||
[AvaloniaFact]
|
||||
public void NumericIntUpDown_Should_Initialize_Correctly()
|
||||
{
|
||||
var window = new Window();
|
||||
var numericUpDown = new NumericIntUpDown();
|
||||
window.Content = numericUpDown;
|
||||
window.Show();
|
||||
|
||||
Dispatcher.UIThread.RunJobs();
|
||||
|
||||
// Test default values
|
||||
Assert.Null(numericUpDown.Value);
|
||||
Assert.Equal(int.MaxValue, numericUpDown.Maximum);
|
||||
Assert.Equal(int.MinValue, numericUpDown.Minimum);
|
||||
Assert.Equal(1, numericUpDown.Step);
|
||||
Assert.True(numericUpDown.AllowSpin);
|
||||
Assert.False(numericUpDown.IsReadOnly);
|
||||
}
|
||||
|
||||
[AvaloniaFact]
|
||||
public void NumericIntUpDown_Should_Set_And_Get_Value()
|
||||
{
|
||||
var window = new Window();
|
||||
var numericUpDown = new NumericIntUpDown();
|
||||
window.Content = numericUpDown;
|
||||
window.Show();
|
||||
|
||||
Dispatcher.UIThread.RunJobs();
|
||||
|
||||
// Test setting a value
|
||||
numericUpDown.Value = 42;
|
||||
Assert.Equal(42, numericUpDown.Value);
|
||||
|
||||
// Test setting null
|
||||
numericUpDown.Value = null;
|
||||
Assert.Null(numericUpDown.Value);
|
||||
}
|
||||
|
||||
[AvaloniaFact]
|
||||
public void NumericIntUpDown_Should_Fire_ValueChanged_Event()
|
||||
{
|
||||
var window = new Window();
|
||||
var numericUpDown = new NumericIntUpDown();
|
||||
window.Content = numericUpDown;
|
||||
window.Show();
|
||||
|
||||
Dispatcher.UIThread.RunJobs();
|
||||
|
||||
int? oldVal = null;
|
||||
int? newVal = null;
|
||||
bool eventFired = false;
|
||||
|
||||
numericUpDown.ValueChanged += (sender, e) =>
|
||||
{
|
||||
oldVal = e.OldValue;
|
||||
newVal = e.NewValue;
|
||||
eventFired = true;
|
||||
};
|
||||
|
||||
numericUpDown.Value = 42;
|
||||
Dispatcher.UIThread.RunJobs();
|
||||
|
||||
Assert.True(eventFired);
|
||||
Assert.Null(oldVal);
|
||||
Assert.Equal(42, newVal);
|
||||
}
|
||||
|
||||
[AvaloniaFact]
|
||||
public void NumericIntUpDown_Should_Clear_Value()
|
||||
{
|
||||
var window = new Window();
|
||||
var numericUpDown = new NumericIntUpDown
|
||||
{
|
||||
Value = 42
|
||||
};
|
||||
window.Content = numericUpDown;
|
||||
window.Show();
|
||||
|
||||
Dispatcher.UIThread.RunJobs();
|
||||
|
||||
Assert.Equal(42, numericUpDown.Value);
|
||||
|
||||
numericUpDown.Clear();
|
||||
Dispatcher.UIThread.RunJobs();
|
||||
|
||||
Assert.Null(numericUpDown.Value);
|
||||
}
|
||||
|
||||
[AvaloniaFact]
|
||||
public void NumericIntUpDown_Should_Handle_EmptyInputValue()
|
||||
{
|
||||
var window = new Window();
|
||||
var numericUpDown = new NumericIntUpDown
|
||||
{
|
||||
EmptyInputValue = 0
|
||||
};
|
||||
window.Content = numericUpDown;
|
||||
window.Show();
|
||||
|
||||
Dispatcher.UIThread.RunJobs();
|
||||
|
||||
numericUpDown.Value = 42;
|
||||
numericUpDown.Clear();
|
||||
Dispatcher.UIThread.RunJobs();
|
||||
|
||||
// After clear with EmptyInputValue set, should use that value
|
||||
Assert.Equal(0, numericUpDown.Value);
|
||||
}
|
||||
|
||||
[AvaloniaFact]
|
||||
public void NumericDoubleUpDown_Should_Handle_Decimal_Values()
|
||||
{
|
||||
var window = new Window();
|
||||
var numericUpDown = new NumericDoubleUpDown();
|
||||
window.Content = numericUpDown;
|
||||
window.Show();
|
||||
|
||||
Dispatcher.UIThread.RunJobs();
|
||||
|
||||
numericUpDown.Value = 3.14159;
|
||||
Assert.Equal(3.14159, numericUpDown.Value);
|
||||
|
||||
numericUpDown.Value = -2.5;
|
||||
Assert.Equal(-2.5, numericUpDown.Value);
|
||||
}
|
||||
|
||||
[AvaloniaFact]
|
||||
public void NumericByteUpDown_Should_Handle_Byte_Range()
|
||||
{
|
||||
var window = new Window();
|
||||
var numericUpDown = new NumericByteUpDown();
|
||||
window.Content = numericUpDown;
|
||||
window.Show();
|
||||
|
||||
Dispatcher.UIThread.RunJobs();
|
||||
|
||||
// Test valid byte values
|
||||
numericUpDown.Value = 255;
|
||||
Assert.Equal((byte)255, numericUpDown.Value);
|
||||
|
||||
numericUpDown.Value = 0;
|
||||
Assert.Equal((byte)0, numericUpDown.Value);
|
||||
|
||||
numericUpDown.Value = 128;
|
||||
Assert.Equal((byte)128, numericUpDown.Value);
|
||||
}
|
||||
|
||||
[AvaloniaFact]
|
||||
public void NumericSByteUpDown_Should_Handle_Signed_Range()
|
||||
{
|
||||
var window = new Window();
|
||||
var numericUpDown = new NumericSByteUpDown();
|
||||
window.Content = numericUpDown;
|
||||
window.Show();
|
||||
|
||||
Dispatcher.UIThread.RunJobs();
|
||||
|
||||
numericUpDown.Value = -128;
|
||||
Assert.Equal((sbyte)(-128), numericUpDown.Value);
|
||||
|
||||
numericUpDown.Value = 127;
|
||||
Assert.Equal((sbyte)127, numericUpDown.Value);
|
||||
|
||||
numericUpDown.Value = 0;
|
||||
Assert.Equal((sbyte)0, numericUpDown.Value);
|
||||
}
|
||||
|
||||
[AvaloniaFact]
|
||||
public void NumericDecimalUpDown_Should_Handle_High_Precision()
|
||||
{
|
||||
var window = new Window();
|
||||
var numericUpDown = new NumericDecimalUpDown();
|
||||
window.Content = numericUpDown;
|
||||
window.Show();
|
||||
|
||||
Dispatcher.UIThread.RunJobs();
|
||||
|
||||
var preciseValue = 123.456789123456789m;
|
||||
numericUpDown.Value = preciseValue;
|
||||
Assert.Equal(preciseValue, numericUpDown.Value);
|
||||
}
|
||||
|
||||
[AvaloniaFact]
|
||||
public void NumericFloatUpDown_Should_Handle_Float_Values()
|
||||
{
|
||||
var window = new Window();
|
||||
var numericUpDown = new NumericFloatUpDown();
|
||||
window.Content = numericUpDown;
|
||||
window.Show();
|
||||
|
||||
Dispatcher.UIThread.RunJobs();
|
||||
|
||||
var floatValue = 3.14159f;
|
||||
numericUpDown.Value = floatValue;
|
||||
Assert.Equal(floatValue, numericUpDown.Value);
|
||||
}
|
||||
|
||||
[AvaloniaFact]
|
||||
public void NumericLongUpDown_Should_Handle_Large_Values()
|
||||
{
|
||||
var window = new Window();
|
||||
var numericUpDown = new NumericLongUpDown();
|
||||
window.Content = numericUpDown;
|
||||
window.Show();
|
||||
|
||||
Dispatcher.UIThread.RunJobs();
|
||||
|
||||
var largeValue = 9223372036854775807L; // long.MaxValue
|
||||
numericUpDown.Value = largeValue;
|
||||
Assert.Equal(largeValue, numericUpDown.Value);
|
||||
}
|
||||
|
||||
[AvaloniaFact]
|
||||
public void NumericULongUpDown_Should_Handle_Large_Unsigned_Values()
|
||||
{
|
||||
var window = new Window();
|
||||
var numericUpDown = new NumericULongUpDown();
|
||||
window.Content = numericUpDown;
|
||||
window.Show();
|
||||
|
||||
Dispatcher.UIThread.RunJobs();
|
||||
|
||||
var largeValue = 18446744073709551615UL; // ulong.MaxValue
|
||||
numericUpDown.Value = largeValue;
|
||||
Assert.Equal(largeValue, numericUpDown.Value);
|
||||
}
|
||||
|
||||
[AvaloniaFact]
|
||||
public void NumericUpDown_Should_Handle_Min_Max_Properties()
|
||||
{
|
||||
var window = new Window();
|
||||
var numericUpDown = new NumericIntUpDown
|
||||
{
|
||||
Minimum = 0,
|
||||
Maximum = 100
|
||||
};
|
||||
window.Content = numericUpDown;
|
||||
window.Show();
|
||||
|
||||
Dispatcher.UIThread.RunJobs();
|
||||
|
||||
Assert.Equal(0, numericUpDown.Minimum);
|
||||
Assert.Equal(100, numericUpDown.Maximum);
|
||||
|
||||
// Test within range
|
||||
numericUpDown.Value = 50;
|
||||
Assert.Equal(50, numericUpDown.Value);
|
||||
}
|
||||
|
||||
[AvaloniaFact]
|
||||
public void NumericUpDown_Should_Handle_Step_Property()
|
||||
{
|
||||
var window = new Window();
|
||||
var numericUpDown = new NumericIntUpDown
|
||||
{
|
||||
Step = 5
|
||||
};
|
||||
window.Content = numericUpDown;
|
||||
window.Show();
|
||||
|
||||
Dispatcher.UIThread.RunJobs();
|
||||
|
||||
Assert.Equal(5, numericUpDown.Step);
|
||||
}
|
||||
|
||||
[AvaloniaFact]
|
||||
public void NumericUpDown_Should_Handle_UI_Properties()
|
||||
{
|
||||
var window = new Window();
|
||||
var numericUpDown = new NumericIntUpDown
|
||||
{
|
||||
AllowSpin = false,
|
||||
ShowButtonSpinner = false,
|
||||
AllowDrag = true,
|
||||
IsReadOnly = true,
|
||||
Watermark = "Enter number"
|
||||
};
|
||||
window.Content = numericUpDown;
|
||||
window.Show();
|
||||
|
||||
Dispatcher.UIThread.RunJobs();
|
||||
|
||||
Assert.False(numericUpDown.AllowSpin);
|
||||
Assert.False(numericUpDown.ShowButtonSpinner);
|
||||
Assert.True(numericUpDown.AllowDrag);
|
||||
Assert.True(numericUpDown.IsReadOnly);
|
||||
Assert.Equal("Enter number", numericUpDown.Watermark);
|
||||
}
|
||||
|
||||
[AvaloniaFact]
|
||||
public void NumericUpDown_Should_Handle_Content_Properties()
|
||||
{
|
||||
var window = new Window();
|
||||
var numericUpDown = new NumericIntUpDown();
|
||||
window.Content = numericUpDown;
|
||||
window.Show();
|
||||
|
||||
Dispatcher.UIThread.RunJobs();
|
||||
|
||||
var leftContent = new TextBlock { Text = "Left" };
|
||||
var rightContent = new TextBlock { Text = "Right" };
|
||||
|
||||
numericUpDown.InnerLeftContent = leftContent;
|
||||
numericUpDown.InnerRightContent = rightContent;
|
||||
|
||||
Assert.Equal(leftContent, numericUpDown.InnerLeftContent);
|
||||
Assert.Equal(rightContent, numericUpDown.InnerRightContent);
|
||||
}
|
||||
|
||||
[AvaloniaFact]
|
||||
public void NumericUpDown_Should_Handle_Format_Properties()
|
||||
{
|
||||
var window = new Window();
|
||||
var numericUpDown = new NumericIntUpDown
|
||||
{
|
||||
FormatString = "D5"
|
||||
};
|
||||
window.Content = numericUpDown;
|
||||
window.Show();
|
||||
|
||||
Dispatcher.UIThread.RunJobs();
|
||||
|
||||
Assert.Equal("D5", numericUpDown.FormatString);
|
||||
Assert.NotNull(numericUpDown.NumberFormat);
|
||||
}
|
||||
|
||||
[AvaloniaTheory]
|
||||
[InlineData(typeof(NumericIntUpDown))]
|
||||
[InlineData(typeof(NumericUIntUpDown))]
|
||||
[InlineData(typeof(NumericDoubleUpDown))]
|
||||
[InlineData(typeof(NumericByteUpDown))]
|
||||
[InlineData(typeof(NumericSByteUpDown))]
|
||||
[InlineData(typeof(NumericShortUpDown))]
|
||||
[InlineData(typeof(NumericUShortUpDown))]
|
||||
[InlineData(typeof(NumericLongUpDown))]
|
||||
[InlineData(typeof(NumericULongUpDown))]
|
||||
[InlineData(typeof(NumericFloatUpDown))]
|
||||
[InlineData(typeof(NumericDecimalUpDown))]
|
||||
public void All_NumericUpDown_Types_Should_Instantiate_Successfully(Type numericUpDownType)
|
||||
{
|
||||
var window = new Window();
|
||||
var numericUpDown = Activator.CreateInstance(numericUpDownType);
|
||||
Assert.NotNull(numericUpDown);
|
||||
|
||||
window.Content = (Control)numericUpDown!;
|
||||
window.Show();
|
||||
|
||||
Dispatcher.UIThread.RunJobs();
|
||||
|
||||
// If we reach here without exception, instantiation was successful
|
||||
Assert.True(true);
|
||||
}
|
||||
|
||||
[AvaloniaTheory]
|
||||
[InlineData(typeof(NumericIntUpDown))]
|
||||
[InlineData(typeof(NumericUIntUpDown))]
|
||||
[InlineData(typeof(NumericDoubleUpDown))]
|
||||
[InlineData(typeof(NumericByteUpDown))]
|
||||
[InlineData(typeof(NumericSByteUpDown))]
|
||||
[InlineData(typeof(NumericShortUpDown))]
|
||||
[InlineData(typeof(NumericUShortUpDown))]
|
||||
[InlineData(typeof(NumericLongUpDown))]
|
||||
[InlineData(typeof(NumericULongUpDown))]
|
||||
[InlineData(typeof(NumericFloatUpDown))]
|
||||
[InlineData(typeof(NumericDecimalUpDown))]
|
||||
public void All_NumericUpDown_Types_Should_Support_Clear(Type numericUpDownType)
|
||||
{
|
||||
var window = new Window();
|
||||
var numericUpDown = Activator.CreateInstance(numericUpDownType);
|
||||
Assert.NotNull(numericUpDown);
|
||||
|
||||
window.Content = (Control)numericUpDown!;
|
||||
window.Show();
|
||||
|
||||
Dispatcher.UIThread.RunJobs();
|
||||
|
||||
// Test that Clear method exists and can be called
|
||||
var clearMethod = numericUpDownType.GetMethod("Clear");
|
||||
Assert.NotNull(clearMethod);
|
||||
|
||||
// Should not throw
|
||||
clearMethod.Invoke(numericUpDown, null);
|
||||
Dispatcher.UIThread.RunJobs();
|
||||
}
|
||||
|
||||
[AvaloniaFact]
|
||||
public void NumericUpDown_Should_Parse_Text_Input()
|
||||
{
|
||||
var window = new Window();
|
||||
var numericUpDown = new NumericIntUpDown();
|
||||
window.Content = numericUpDown;
|
||||
window.Show();
|
||||
|
||||
Dispatcher.UIThread.RunJobs();
|
||||
|
||||
// Test that ParseText method exists and works
|
||||
var parseMethod = typeof(NumericIntUpDown).GetMethod("ParseText",
|
||||
System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance);
|
||||
Assert.NotNull(parseMethod);
|
||||
|
||||
var parameters = new object[] { "123", 0 };
|
||||
var result = (bool)parseMethod.Invoke(numericUpDown, parameters)!;
|
||||
var parsedValue = (int)parameters[1];
|
||||
|
||||
Assert.True(result);
|
||||
Assert.Equal(123, parsedValue);
|
||||
|
||||
// Test invalid input
|
||||
parameters = new object[] { "invalid", 0 };
|
||||
result = (bool)parseMethod.Invoke(numericUpDown, parameters)!;
|
||||
Assert.False(result);
|
||||
}
|
||||
|
||||
[AvaloniaFact]
|
||||
public void NumericUpDown_Should_Format_Values()
|
||||
{
|
||||
var window = new Window();
|
||||
var numericUpDown = new NumericIntUpDown();
|
||||
window.Content = numericUpDown;
|
||||
window.Show();
|
||||
|
||||
Dispatcher.UIThread.RunJobs();
|
||||
|
||||
// Test ValueToString method
|
||||
var formatMethod = typeof(NumericIntUpDown).GetMethod("ValueToString",
|
||||
System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance);
|
||||
Assert.NotNull(formatMethod);
|
||||
|
||||
var result = (string?)formatMethod.Invoke(numericUpDown, new object?[] { 123 });
|
||||
Assert.Equal("123", result);
|
||||
|
||||
result = (string?)formatMethod.Invoke(numericUpDown, new object?[] { null });
|
||||
Assert.Null(result);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,455 @@
|
||||
using Avalonia.Controls;
|
||||
using Avalonia.Headless.XUnit;
|
||||
using Avalonia.Threading;
|
||||
using Ursa.Controls;
|
||||
|
||||
namespace HeadlessTest.Ursa.Controls.NumericUpDownTests;
|
||||
|
||||
/// <summary>
|
||||
/// Final comprehensive test suite for all NumericUpDown classes following existing test patterns
|
||||
/// </summary>
|
||||
public class NumericUpDownFinalTests
|
||||
{
|
||||
[AvaloniaFact]
|
||||
public void NumericIntUpDown_Should_Initialize_And_Work()
|
||||
{
|
||||
var window = new Window();
|
||||
var numericUpDown = new NumericIntUpDown();
|
||||
window.Content = numericUpDown;
|
||||
window.Show();
|
||||
|
||||
// Test initialization
|
||||
Assert.Null(numericUpDown.Value);
|
||||
Assert.Equal(int.MaxValue, numericUpDown.Maximum);
|
||||
Assert.Equal(int.MinValue, numericUpDown.Minimum);
|
||||
Assert.Equal(1, numericUpDown.Step);
|
||||
|
||||
// Test value setting
|
||||
numericUpDown.Value = 42;
|
||||
Assert.Equal(42, numericUpDown.Value);
|
||||
|
||||
// Test clear
|
||||
numericUpDown.Clear();
|
||||
Assert.Null(numericUpDown.Value);
|
||||
}
|
||||
|
||||
[AvaloniaFact]
|
||||
public void NumericUIntUpDown_Should_Initialize_And_Work()
|
||||
{
|
||||
var window = new Window();
|
||||
var numericUpDown = new NumericUIntUpDown();
|
||||
window.Content = numericUpDown;
|
||||
window.Show();
|
||||
|
||||
Assert.Null(numericUpDown.Value);
|
||||
Assert.Equal(uint.MaxValue, numericUpDown.Maximum);
|
||||
Assert.Equal(uint.MinValue, numericUpDown.Minimum);
|
||||
Assert.Equal(1u, numericUpDown.Step);
|
||||
|
||||
numericUpDown.Value = 42u;
|
||||
Assert.Equal(42u, numericUpDown.Value);
|
||||
|
||||
numericUpDown.Clear();
|
||||
Assert.Null(numericUpDown.Value);
|
||||
}
|
||||
|
||||
[AvaloniaFact]
|
||||
public void NumericDoubleUpDown_Should_Initialize_And_Work()
|
||||
{
|
||||
var window = new Window();
|
||||
var numericUpDown = new NumericDoubleUpDown();
|
||||
window.Content = numericUpDown;
|
||||
window.Show();
|
||||
|
||||
Assert.Null(numericUpDown.Value);
|
||||
Assert.Equal(double.MaxValue, numericUpDown.Maximum);
|
||||
Assert.Equal(double.MinValue, numericUpDown.Minimum);
|
||||
Assert.Equal(1.0, numericUpDown.Step);
|
||||
|
||||
numericUpDown.Value = 3.14159;
|
||||
Assert.Equal(3.14159, numericUpDown.Value);
|
||||
|
||||
numericUpDown.Clear();
|
||||
Assert.Null(numericUpDown.Value);
|
||||
}
|
||||
|
||||
[AvaloniaFact]
|
||||
public void NumericByteUpDown_Should_Initialize_And_Work()
|
||||
{
|
||||
var window = new Window();
|
||||
var numericUpDown = new NumericByteUpDown();
|
||||
window.Content = numericUpDown;
|
||||
window.Show();
|
||||
|
||||
Assert.Null(numericUpDown.Value);
|
||||
Assert.Equal(byte.MaxValue, numericUpDown.Maximum);
|
||||
Assert.Equal(byte.MinValue, numericUpDown.Minimum);
|
||||
Assert.Equal((byte)1, numericUpDown.Step);
|
||||
|
||||
numericUpDown.Value = 255;
|
||||
Assert.Equal((byte)255, numericUpDown.Value);
|
||||
|
||||
numericUpDown.Clear();
|
||||
Assert.Null(numericUpDown.Value);
|
||||
}
|
||||
|
||||
[AvaloniaFact]
|
||||
public void NumericSByteUpDown_Should_Initialize_And_Work()
|
||||
{
|
||||
var window = new Window();
|
||||
var numericUpDown = new NumericSByteUpDown();
|
||||
window.Content = numericUpDown;
|
||||
window.Show();
|
||||
|
||||
Assert.Null(numericUpDown.Value);
|
||||
Assert.Equal(sbyte.MaxValue, numericUpDown.Maximum);
|
||||
Assert.Equal(sbyte.MinValue, numericUpDown.Minimum);
|
||||
Assert.Equal((sbyte)1, numericUpDown.Step);
|
||||
|
||||
numericUpDown.Value = -50;
|
||||
Assert.Equal((sbyte)(-50), numericUpDown.Value);
|
||||
|
||||
numericUpDown.Clear();
|
||||
Assert.Null(numericUpDown.Value);
|
||||
}
|
||||
|
||||
[AvaloniaFact]
|
||||
public void NumericShortUpDown_Should_Initialize_And_Work()
|
||||
{
|
||||
var window = new Window();
|
||||
var numericUpDown = new NumericShortUpDown();
|
||||
window.Content = numericUpDown;
|
||||
window.Show();
|
||||
|
||||
Assert.Null(numericUpDown.Value);
|
||||
Assert.Equal(short.MaxValue, numericUpDown.Maximum);
|
||||
Assert.Equal(short.MinValue, numericUpDown.Minimum);
|
||||
Assert.Equal((short)1, numericUpDown.Step);
|
||||
|
||||
numericUpDown.Value = 1000;
|
||||
Assert.Equal((short)1000, numericUpDown.Value);
|
||||
|
||||
numericUpDown.Clear();
|
||||
Assert.Null(numericUpDown.Value);
|
||||
}
|
||||
|
||||
[AvaloniaFact]
|
||||
public void NumericUShortUpDown_Should_Initialize_And_Work()
|
||||
{
|
||||
var window = new Window();
|
||||
var numericUpDown = new NumericUShortUpDown();
|
||||
window.Content = numericUpDown;
|
||||
window.Show();
|
||||
|
||||
Assert.Null(numericUpDown.Value);
|
||||
Assert.Equal(ushort.MaxValue, numericUpDown.Maximum);
|
||||
Assert.Equal(ushort.MinValue, numericUpDown.Minimum);
|
||||
Assert.Equal((ushort)1, numericUpDown.Step);
|
||||
|
||||
numericUpDown.Value = 2000;
|
||||
Assert.Equal((ushort)2000, numericUpDown.Value);
|
||||
|
||||
numericUpDown.Clear();
|
||||
Assert.Null(numericUpDown.Value);
|
||||
}
|
||||
|
||||
[AvaloniaFact]
|
||||
public void NumericLongUpDown_Should_Initialize_And_Work()
|
||||
{
|
||||
var window = new Window();
|
||||
var numericUpDown = new NumericLongUpDown();
|
||||
window.Content = numericUpDown;
|
||||
window.Show();
|
||||
|
||||
Assert.Null(numericUpDown.Value);
|
||||
Assert.Equal(long.MaxValue, numericUpDown.Maximum);
|
||||
Assert.Equal(long.MinValue, numericUpDown.Minimum);
|
||||
Assert.Equal(1L, numericUpDown.Step);
|
||||
|
||||
numericUpDown.Value = 9223372036854775806L;
|
||||
Assert.Equal(9223372036854775806L, numericUpDown.Value);
|
||||
|
||||
numericUpDown.Clear();
|
||||
Assert.Null(numericUpDown.Value);
|
||||
}
|
||||
|
||||
[AvaloniaFact]
|
||||
public void NumericULongUpDown_Should_Initialize_And_Work()
|
||||
{
|
||||
var window = new Window();
|
||||
var numericUpDown = new NumericULongUpDown();
|
||||
window.Content = numericUpDown;
|
||||
window.Show();
|
||||
|
||||
Assert.Null(numericUpDown.Value);
|
||||
Assert.Equal(ulong.MaxValue, numericUpDown.Maximum);
|
||||
Assert.Equal(ulong.MinValue, numericUpDown.Minimum);
|
||||
Assert.Equal(1UL, numericUpDown.Step);
|
||||
|
||||
numericUpDown.Value = 18446744073709551614UL;
|
||||
Assert.Equal(18446744073709551614UL, numericUpDown.Value);
|
||||
|
||||
numericUpDown.Clear();
|
||||
Assert.Null(numericUpDown.Value);
|
||||
}
|
||||
|
||||
[AvaloniaFact]
|
||||
public void NumericFloatUpDown_Should_Initialize_And_Work()
|
||||
{
|
||||
var window = new Window();
|
||||
var numericUpDown = new NumericFloatUpDown();
|
||||
window.Content = numericUpDown;
|
||||
window.Show();
|
||||
|
||||
Assert.Null(numericUpDown.Value);
|
||||
Assert.Equal(float.MaxValue, numericUpDown.Maximum);
|
||||
Assert.Equal(float.MinValue, numericUpDown.Minimum);
|
||||
Assert.Equal(1.0f, numericUpDown.Step);
|
||||
|
||||
numericUpDown.Value = 3.14159f;
|
||||
Assert.Equal(3.14159f, numericUpDown.Value);
|
||||
|
||||
numericUpDown.Clear();
|
||||
Assert.Null(numericUpDown.Value);
|
||||
}
|
||||
|
||||
[AvaloniaFact]
|
||||
public void NumericDecimalUpDown_Should_Initialize_And_Work()
|
||||
{
|
||||
var window = new Window();
|
||||
var numericUpDown = new NumericDecimalUpDown();
|
||||
window.Content = numericUpDown;
|
||||
window.Show();
|
||||
|
||||
Assert.Null(numericUpDown.Value);
|
||||
Assert.Equal(decimal.MaxValue, numericUpDown.Maximum);
|
||||
Assert.Equal(decimal.MinValue, numericUpDown.Minimum);
|
||||
Assert.Equal(1m, numericUpDown.Step);
|
||||
|
||||
numericUpDown.Value = 123.456789123456789m;
|
||||
Assert.Equal(123.456789123456789m, numericUpDown.Value);
|
||||
|
||||
numericUpDown.Clear();
|
||||
Assert.Null(numericUpDown.Value);
|
||||
}
|
||||
|
||||
[AvaloniaFact]
|
||||
public void NumericIntUpDown_Should_Fire_ValueChanged_Event()
|
||||
{
|
||||
var window = new Window();
|
||||
var numericUpDown = new NumericIntUpDown();
|
||||
window.Content = numericUpDown;
|
||||
window.Show();
|
||||
|
||||
int? oldValue = null;
|
||||
int? newValue = null;
|
||||
bool eventFired = false;
|
||||
|
||||
numericUpDown.ValueChanged += (sender, e) =>
|
||||
{
|
||||
oldValue = e.OldValue;
|
||||
newValue = e.NewValue;
|
||||
eventFired = true;
|
||||
};
|
||||
|
||||
numericUpDown.Value = 42;
|
||||
|
||||
Assert.True(eventFired);
|
||||
Assert.Null(oldValue);
|
||||
Assert.Equal(42, newValue);
|
||||
}
|
||||
|
||||
[AvaloniaFact]
|
||||
public void NumericIntUpDown_Should_Handle_Min_Max_Properties()
|
||||
{
|
||||
var window = new Window();
|
||||
var numericUpDown = new NumericIntUpDown
|
||||
{
|
||||
Minimum = 0,
|
||||
Maximum = 100
|
||||
};
|
||||
window.Content = numericUpDown;
|
||||
window.Show();
|
||||
|
||||
Assert.Equal(0, numericUpDown.Minimum);
|
||||
Assert.Equal(100, numericUpDown.Maximum);
|
||||
|
||||
// Test setting value within range
|
||||
numericUpDown.Value = 50;
|
||||
Assert.Equal(50, numericUpDown.Value);
|
||||
}
|
||||
|
||||
[AvaloniaFact]
|
||||
public void NumericIntUpDown_Should_Handle_EmptyInputValue()
|
||||
{
|
||||
var window = new Window();
|
||||
var numericUpDown = new NumericIntUpDown
|
||||
{
|
||||
EmptyInputValue = 0
|
||||
};
|
||||
window.Content = numericUpDown;
|
||||
window.Show();
|
||||
|
||||
numericUpDown.Value = 42;
|
||||
numericUpDown.Clear();
|
||||
|
||||
// After clear with EmptyInputValue set, should use that value
|
||||
Assert.Equal(0, numericUpDown.Value);
|
||||
}
|
||||
|
||||
[AvaloniaFact]
|
||||
public void NumericIntUpDown_Should_Handle_UI_Properties()
|
||||
{
|
||||
var window = new Window();
|
||||
var numericUpDown = new NumericIntUpDown
|
||||
{
|
||||
AllowSpin = false,
|
||||
ShowButtonSpinner = false,
|
||||
AllowDrag = true,
|
||||
IsReadOnly = true,
|
||||
Watermark = "Enter number"
|
||||
};
|
||||
window.Content = numericUpDown;
|
||||
window.Show();
|
||||
|
||||
Assert.False(numericUpDown.AllowSpin);
|
||||
Assert.False(numericUpDown.ShowButtonSpinner);
|
||||
Assert.True(numericUpDown.AllowDrag);
|
||||
Assert.True(numericUpDown.IsReadOnly);
|
||||
Assert.Equal("Enter number", numericUpDown.Watermark);
|
||||
}
|
||||
|
||||
[AvaloniaFact]
|
||||
public void NumericIntUpDown_Should_Handle_Content_Properties()
|
||||
{
|
||||
var window = new Window();
|
||||
var numericUpDown = new NumericIntUpDown();
|
||||
window.Content = numericUpDown;
|
||||
window.Show();
|
||||
|
||||
var leftContent = new TextBlock { Text = "Left" };
|
||||
var rightContent = new TextBlock { Text = "Right" };
|
||||
|
||||
numericUpDown.InnerLeftContent = leftContent;
|
||||
numericUpDown.InnerRightContent = rightContent;
|
||||
|
||||
Assert.Equal(leftContent, numericUpDown.InnerLeftContent);
|
||||
Assert.Equal(rightContent, numericUpDown.InnerRightContent);
|
||||
}
|
||||
|
||||
[AvaloniaFact]
|
||||
public void NumericIntUpDown_Should_Handle_Format_Properties()
|
||||
{
|
||||
var window = new Window();
|
||||
var numericUpDown = new NumericIntUpDown
|
||||
{
|
||||
FormatString = "D5"
|
||||
};
|
||||
window.Content = numericUpDown;
|
||||
window.Show();
|
||||
|
||||
Assert.Equal("D5", numericUpDown.FormatString);
|
||||
Assert.NotNull(numericUpDown.NumberFormat);
|
||||
}
|
||||
|
||||
[AvaloniaFact]
|
||||
public void NumericIntUpDown_Should_Parse_Text_Input()
|
||||
{
|
||||
var window = new Window();
|
||||
var numericUpDown = new NumericIntUpDown();
|
||||
window.Content = numericUpDown;
|
||||
window.Show();
|
||||
|
||||
// Use reflection to test ParseText method
|
||||
var parseMethod = typeof(NumericIntUpDown).GetMethod("ParseText",
|
||||
System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance);
|
||||
Assert.NotNull(parseMethod);
|
||||
|
||||
// Test valid input
|
||||
var parameters = new object[] { "123", 0 };
|
||||
var result = (bool)parseMethod.Invoke(numericUpDown, parameters)!;
|
||||
var parsedValue = (int)parameters[1];
|
||||
|
||||
Assert.True(result);
|
||||
Assert.Equal(123, parsedValue);
|
||||
|
||||
// Test invalid input
|
||||
parameters = new object[] { "invalid", 0 };
|
||||
result = (bool)parseMethod.Invoke(numericUpDown, parameters)!;
|
||||
Assert.False(result);
|
||||
}
|
||||
|
||||
[AvaloniaFact]
|
||||
public void NumericIntUpDown_Should_Format_Values()
|
||||
{
|
||||
var window = new Window();
|
||||
var numericUpDown = new NumericIntUpDown();
|
||||
window.Content = numericUpDown;
|
||||
window.Show();
|
||||
|
||||
// Use reflection to test ValueToString method
|
||||
var formatMethod = typeof(NumericIntUpDown).GetMethod("ValueToString",
|
||||
System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance);
|
||||
Assert.NotNull(formatMethod);
|
||||
|
||||
var result = (string?)formatMethod.Invoke(numericUpDown, new object?[] { 123 });
|
||||
Assert.Equal("123", result);
|
||||
|
||||
result = (string?)formatMethod.Invoke(numericUpDown, new object?[] { null });
|
||||
Assert.Null(result);
|
||||
}
|
||||
|
||||
[AvaloniaFact]
|
||||
public void NumericUpDown_Should_Have_Abstract_Methods()
|
||||
{
|
||||
var window = new Window();
|
||||
var intUpDown = new NumericIntUpDown();
|
||||
|
||||
window.Content = intUpDown;
|
||||
window.Show();
|
||||
|
||||
// Test that concrete implementations have required methods
|
||||
var parseMethod = typeof(NumericIntUpDown).GetMethod("ParseText",
|
||||
System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance);
|
||||
Assert.NotNull(parseMethod);
|
||||
|
||||
var formatMethod = typeof(NumericIntUpDown).GetMethod("ValueToString",
|
||||
System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance);
|
||||
Assert.NotNull(formatMethod);
|
||||
|
||||
// Test Zero property exists (use specific binding flags to avoid ambiguity)
|
||||
var zeroProperty = typeof(NumericIntUpDown).GetProperty("Zero",
|
||||
System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.DeclaredOnly);
|
||||
if (zeroProperty != null)
|
||||
{
|
||||
var zeroValue = zeroProperty.GetValue(intUpDown);
|
||||
Assert.Equal(0, zeroValue);
|
||||
}
|
||||
}
|
||||
|
||||
[AvaloniaFact]
|
||||
public void All_NumericUpDown_Types_Should_Have_Clear_Method()
|
||||
{
|
||||
var window = new Window();
|
||||
|
||||
// Test a few representative types
|
||||
var types = new[]
|
||||
{
|
||||
typeof(NumericIntUpDown),
|
||||
typeof(NumericDoubleUpDown),
|
||||
typeof(NumericDecimalUpDown)
|
||||
};
|
||||
|
||||
foreach (var type in types)
|
||||
{
|
||||
var instance = Activator.CreateInstance(type);
|
||||
Assert.NotNull(instance);
|
||||
|
||||
var clearMethod = type.GetMethod("Clear");
|
||||
Assert.NotNull(clearMethod);
|
||||
|
||||
// Verify Clear method can be called (may not test full functionality due to UI thread requirements)
|
||||
Assert.NotNull(clearMethod.DeclaringType);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,380 @@
|
||||
using Avalonia.Controls;
|
||||
using Avalonia.Headless.XUnit;
|
||||
using Avalonia.Input;
|
||||
using Avalonia.Threading;
|
||||
using Ursa.Controls;
|
||||
using System.Windows.Input;
|
||||
|
||||
namespace HeadlessTest.Ursa.Controls.NumericUpDownTests;
|
||||
|
||||
/// <summary>
|
||||
/// Tests for UI interactions and advanced features of NumericUpDown controls
|
||||
/// </summary>
|
||||
public class NumericUpDownInteractionTests
|
||||
{
|
||||
[AvaloniaFact]
|
||||
public void NumericUpDown_Should_Handle_AllowSpin_Property()
|
||||
{
|
||||
var window = new Window();
|
||||
var numericUpDown = new NumericIntUpDown
|
||||
{
|
||||
Value = 10,
|
||||
AllowSpin = false
|
||||
};
|
||||
window.Content = numericUpDown;
|
||||
window.Show();
|
||||
|
||||
Assert.False(numericUpDown.AllowSpin);
|
||||
|
||||
// When AllowSpin is false, spinning should be disabled
|
||||
numericUpDown.AllowSpin = true;
|
||||
Assert.True(numericUpDown.AllowSpin);
|
||||
}
|
||||
|
||||
[AvaloniaFact]
|
||||
public void NumericUpDown_Should_Handle_ShowButtonSpinner_Property()
|
||||
{
|
||||
var window = new Window();
|
||||
var numericUpDown = new NumericIntUpDown
|
||||
{
|
||||
ShowButtonSpinner = false
|
||||
};
|
||||
window.Content = numericUpDown;
|
||||
window.Show();
|
||||
|
||||
Assert.False(numericUpDown.ShowButtonSpinner);
|
||||
|
||||
numericUpDown.ShowButtonSpinner = true;
|
||||
Assert.True(numericUpDown.ShowButtonSpinner);
|
||||
}
|
||||
|
||||
[AvaloniaFact]
|
||||
public void NumericUpDown_Should_Handle_AllowDrag_Property()
|
||||
{
|
||||
var window = new Window();
|
||||
var numericUpDown = new NumericIntUpDown
|
||||
{
|
||||
AllowDrag = true
|
||||
};
|
||||
window.Content = numericUpDown;
|
||||
window.Show();
|
||||
|
||||
Assert.True(numericUpDown.AllowDrag);
|
||||
|
||||
numericUpDown.AllowDrag = false;
|
||||
Assert.False(numericUpDown.AllowDrag);
|
||||
}
|
||||
|
||||
[AvaloniaFact]
|
||||
public void NumericUpDown_Should_Handle_Watermark_Property()
|
||||
{
|
||||
var window = new Window();
|
||||
var numericUpDown = new NumericIntUpDown
|
||||
{
|
||||
Watermark = "Enter a number"
|
||||
};
|
||||
window.Content = numericUpDown;
|
||||
window.Show();
|
||||
|
||||
Assert.Equal("Enter a number", numericUpDown.Watermark);
|
||||
|
||||
numericUpDown.Watermark = "Different placeholder";
|
||||
Assert.Equal("Different placeholder", numericUpDown.Watermark);
|
||||
}
|
||||
|
||||
[AvaloniaFact]
|
||||
public void NumericUpDown_Should_Handle_InnerContent_Properties()
|
||||
{
|
||||
var window = new Window();
|
||||
var numericUpDown = new NumericIntUpDown();
|
||||
window.Content = numericUpDown;
|
||||
window.Show();
|
||||
|
||||
var leftContent = new TextBlock { Text = "Left" };
|
||||
var rightContent = new TextBlock { Text = "Right" };
|
||||
|
||||
numericUpDown.InnerLeftContent = leftContent;
|
||||
numericUpDown.InnerRightContent = rightContent;
|
||||
|
||||
Assert.Equal(leftContent, numericUpDown.InnerLeftContent);
|
||||
Assert.Equal(rightContent, numericUpDown.InnerRightContent);
|
||||
}
|
||||
|
||||
[AvaloniaFact]
|
||||
public void NumericUpDown_Should_Handle_EmptyInputValue_Property()
|
||||
{
|
||||
var window = new Window();
|
||||
var numericUpDown = new NumericIntUpDown
|
||||
{
|
||||
EmptyInputValue = 0
|
||||
};
|
||||
window.Content = numericUpDown;
|
||||
window.Show();
|
||||
|
||||
Assert.Equal(0, numericUpDown.EmptyInputValue);
|
||||
|
||||
// When value is cleared, it should use EmptyInputValue
|
||||
numericUpDown.Value = 42;
|
||||
numericUpDown.Clear();
|
||||
|
||||
// After clear, value should be EmptyInputValue
|
||||
Assert.Equal(0, numericUpDown.Value);
|
||||
}
|
||||
|
||||
[AvaloniaFact]
|
||||
public void NumericUpDown_Should_Fire_Spinned_Event()
|
||||
{
|
||||
var window = new Window();
|
||||
var numericUpDown = new NumericIntUpDown
|
||||
{
|
||||
Value = 10,
|
||||
Step = 5
|
||||
};
|
||||
window.Content = numericUpDown;
|
||||
window.Show();
|
||||
|
||||
bool spinnedEventFired = false;
|
||||
SpinDirection? spinnedDirection = null;
|
||||
|
||||
numericUpDown.Spinned += (sender, e) =>
|
||||
{
|
||||
spinnedEventFired = true;
|
||||
spinnedDirection = e.Direction;
|
||||
};
|
||||
|
||||
// Simulate spin increase
|
||||
var increaseMethod = typeof(NumericIntUpDown).GetMethod("Increase", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance);
|
||||
increaseMethod?.Invoke(numericUpDown, null);
|
||||
|
||||
// Note: The Spinned event is typically fired by the ButtonSpinner, not directly by Increase/Decrease
|
||||
// This test verifies the event handler can be attached without errors
|
||||
Assert.False(spinnedEventFired); // Event won't fire from direct method call
|
||||
}
|
||||
|
||||
[AvaloniaFact]
|
||||
public void NumericUpDown_Should_Execute_Command_On_Value_Change()
|
||||
{
|
||||
var window = new Window();
|
||||
var numericUpDown = new NumericIntUpDown();
|
||||
window.Content = numericUpDown;
|
||||
window.Show();
|
||||
|
||||
bool commandExecuted = false;
|
||||
object? commandParameter = null;
|
||||
|
||||
var testCommand = new TestCommand(parameter =>
|
||||
{
|
||||
commandExecuted = true;
|
||||
commandParameter = parameter;
|
||||
});
|
||||
|
||||
numericUpDown.Command = testCommand;
|
||||
numericUpDown.CommandParameter = "test-param";
|
||||
|
||||
// Trigger value change
|
||||
numericUpDown.Value = 42;
|
||||
|
||||
Assert.True(commandExecuted);
|
||||
Assert.Equal("test-param", commandParameter);
|
||||
}
|
||||
|
||||
[AvaloniaFact]
|
||||
public void NumericUpDown_Should_Handle_NumberFormat_Property()
|
||||
{
|
||||
var window = new Window();
|
||||
var numericUpDown = new NumericIntUpDown();
|
||||
window.Content = numericUpDown;
|
||||
window.Show();
|
||||
|
||||
// Test default number format
|
||||
Assert.NotNull(numericUpDown.NumberFormat);
|
||||
|
||||
// Test setting custom number format
|
||||
var customFormat = new System.Globalization.NumberFormatInfo();
|
||||
numericUpDown.NumberFormat = customFormat;
|
||||
Assert.Equal(customFormat, numericUpDown.NumberFormat);
|
||||
}
|
||||
|
||||
[AvaloniaFact]
|
||||
public void NumericUpDown_Should_Handle_ParsingNumberStyle_Property()
|
||||
{
|
||||
var window = new Window();
|
||||
var numericUpDown = new NumericIntUpDown();
|
||||
window.Content = numericUpDown;
|
||||
window.Show();
|
||||
|
||||
// Test default parsing number style
|
||||
Assert.Equal(System.Globalization.NumberStyles.Any, numericUpDown.ParsingNumberStyle);
|
||||
|
||||
// Test setting custom parsing style
|
||||
numericUpDown.ParsingNumberStyle = System.Globalization.NumberStyles.Integer;
|
||||
Assert.Equal(System.Globalization.NumberStyles.Integer, numericUpDown.ParsingNumberStyle);
|
||||
}
|
||||
|
||||
[AvaloniaFact]
|
||||
public void NumericUpDown_Should_Handle_TextConverter_Property()
|
||||
{
|
||||
var window = new Window();
|
||||
var numericUpDown = new NumericIntUpDown();
|
||||
window.Content = numericUpDown;
|
||||
window.Show();
|
||||
|
||||
// Test default text converter
|
||||
Assert.Null(numericUpDown.TextConverter);
|
||||
|
||||
// Test setting custom text converter
|
||||
var customConverter = new TestValueConverter();
|
||||
numericUpDown.TextConverter = customConverter;
|
||||
Assert.Equal(customConverter, numericUpDown.TextConverter);
|
||||
}
|
||||
|
||||
[AvaloniaFact]
|
||||
public void NumericUpDown_Should_Handle_HorizontalContentAlignment_Property()
|
||||
{
|
||||
var window = new Window();
|
||||
var numericUpDown = new NumericIntUpDown();
|
||||
window.Content = numericUpDown;
|
||||
window.Show();
|
||||
|
||||
numericUpDown.HorizontalContentAlignment = Avalonia.Layout.HorizontalAlignment.Center;
|
||||
Assert.Equal(Avalonia.Layout.HorizontalAlignment.Center, numericUpDown.HorizontalContentAlignment);
|
||||
|
||||
numericUpDown.HorizontalContentAlignment = Avalonia.Layout.HorizontalAlignment.Right;
|
||||
Assert.Equal(Avalonia.Layout.HorizontalAlignment.Right, numericUpDown.HorizontalContentAlignment);
|
||||
}
|
||||
|
||||
[AvaloniaFact]
|
||||
public void NumericUpDown_Should_Validate_Input_Text()
|
||||
{
|
||||
var window = new Window();
|
||||
var numericUpDown = new NumericIntUpDown
|
||||
{
|
||||
Minimum = 0,
|
||||
Maximum = 100
|
||||
};
|
||||
window.Content = numericUpDown;
|
||||
window.Show();
|
||||
|
||||
// Test valid text conversion
|
||||
var convertMethod = typeof(NumericIntUpDown).GetMethod("ConvertTextToValue", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance);
|
||||
Assert.NotNull(convertMethod);
|
||||
|
||||
// Test valid input
|
||||
var validResult = convertMethod.Invoke(numericUpDown, new object?[] { "50" });
|
||||
Assert.Equal(50, validResult);
|
||||
|
||||
// Test invalid input should throw or return null
|
||||
try
|
||||
{
|
||||
var invalidResult = convertMethod.Invoke(numericUpDown, new object?[] { "invalid" });
|
||||
// If no exception, result should be null or default
|
||||
Assert.True(invalidResult == null);
|
||||
}
|
||||
catch (System.Reflection.TargetInvocationException ex) when (ex.InnerException is InvalidDataException)
|
||||
{
|
||||
// Expected for invalid input
|
||||
Assert.True(true);
|
||||
}
|
||||
}
|
||||
|
||||
[AvaloniaFact]
|
||||
public void NumericUpDown_Should_Handle_Overflow_Gracefully()
|
||||
{
|
||||
var window = new Window();
|
||||
var numericUpDown = new NumericIntUpDown
|
||||
{
|
||||
Value = int.MaxValue - 1,
|
||||
Step = 10,
|
||||
Maximum = int.MaxValue
|
||||
};
|
||||
window.Content = numericUpDown;
|
||||
window.Show();
|
||||
|
||||
// Test overflow handling in Add method
|
||||
var addMethod = typeof(NumericIntUpDown).GetMethod("Add", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance);
|
||||
Assert.NotNull(addMethod);
|
||||
|
||||
var result = addMethod.Invoke(numericUpDown, new object?[] { int.MaxValue - 1, 10 });
|
||||
|
||||
// The implementation should handle overflow (either clamp to max or use specific overflow logic)
|
||||
Assert.NotNull(result);
|
||||
}
|
||||
|
||||
[AvaloniaFact]
|
||||
public void NumericUpDown_Should_Handle_Focus_Changes()
|
||||
{
|
||||
var window = new Window();
|
||||
var numericUpDown = new NumericIntUpDown
|
||||
{
|
||||
Value = 42
|
||||
};
|
||||
window.Content = numericUpDown;
|
||||
window.Show();
|
||||
|
||||
// Test that the control can receive focus
|
||||
Assert.True(numericUpDown.Focusable);
|
||||
|
||||
// Simulate focus change
|
||||
numericUpDown.Focus();
|
||||
|
||||
// The control should handle focus without throwing exceptions
|
||||
Assert.True(true); // If we get here, no exception was thrown
|
||||
}
|
||||
|
||||
[AvaloniaFact]
|
||||
public void NumericUpDown_Should_Handle_ReadOnly_Mode_Correctly()
|
||||
{
|
||||
var window = new Window();
|
||||
var numericUpDown = new NumericIntUpDown
|
||||
{
|
||||
Value = 10,
|
||||
IsReadOnly = true
|
||||
};
|
||||
window.Content = numericUpDown;
|
||||
window.Show();
|
||||
|
||||
var initialValue = numericUpDown.Value;
|
||||
|
||||
// In read-only mode, value shouldn't change through normal operations
|
||||
var increaseMethod = typeof(NumericIntUpDown).GetMethod("Increase", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance);
|
||||
increaseMethod?.Invoke(numericUpDown, null);
|
||||
|
||||
// Value should not have changed due to read-only mode
|
||||
// Note: The actual behavior depends on the implementation - some might ignore the operation,
|
||||
// others might still change the value but disable UI interactions
|
||||
Assert.NotNull(numericUpDown.Value); // At minimum, should not crash
|
||||
}
|
||||
|
||||
#region Helper Classes
|
||||
private class TestCommand : ICommand
|
||||
{
|
||||
private readonly Action<object?> _execute;
|
||||
|
||||
public TestCommand(Action<object?> execute)
|
||||
{
|
||||
_execute = execute;
|
||||
}
|
||||
|
||||
public bool CanExecute(object? parameter) => true;
|
||||
|
||||
public void Execute(object? parameter) => _execute(parameter);
|
||||
|
||||
public event EventHandler? CanExecuteChanged;
|
||||
}
|
||||
|
||||
private class TestValueConverter : Avalonia.Data.Converters.IValueConverter
|
||||
{
|
||||
public object? Convert(object? value, Type targetType, object? parameter, System.Globalization.CultureInfo culture)
|
||||
{
|
||||
return value?.ToString();
|
||||
}
|
||||
|
||||
public object? ConvertBack(object? value, Type targetType, object? parameter, System.Globalization.CultureInfo culture)
|
||||
{
|
||||
if (value is string str && int.TryParse(str, out var result))
|
||||
return result;
|
||||
return null;
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,501 @@
|
||||
using Avalonia.Controls;
|
||||
using Avalonia.Headless.XUnit;
|
||||
using Ursa.Controls;
|
||||
|
||||
namespace HeadlessTest.Ursa.Controls.NumericUpDownTests;
|
||||
|
||||
/// <summary>
|
||||
/// Tests for all specific numeric type implementations of NumericUpDown
|
||||
/// </summary>
|
||||
public class NumericUpDownTypesTests
|
||||
{
|
||||
#region UInt Tests
|
||||
[AvaloniaFact]
|
||||
public void NumericUIntUpDown_Should_Initialize_With_Correct_Defaults()
|
||||
{
|
||||
var window = new Window();
|
||||
var numericUpDown = new NumericUIntUpDown();
|
||||
window.Content = numericUpDown;
|
||||
window.Show();
|
||||
|
||||
Assert.Null(numericUpDown.Value);
|
||||
Assert.Equal(uint.MaxValue, numericUpDown.Maximum);
|
||||
Assert.Equal(uint.MinValue, numericUpDown.Minimum);
|
||||
Assert.Equal(1u, numericUpDown.Step);
|
||||
}
|
||||
|
||||
[AvaloniaFact]
|
||||
public void NumericUIntUpDown_Should_Handle_Value_Operations()
|
||||
{
|
||||
var window = new Window();
|
||||
var numericUpDown = new NumericUIntUpDown
|
||||
{
|
||||
Value = 10u,
|
||||
Step = 5u,
|
||||
Minimum = 0u,
|
||||
Maximum = 100u
|
||||
};
|
||||
window.Content = numericUpDown;
|
||||
window.Show();
|
||||
|
||||
Assert.Equal(10u, numericUpDown.Value);
|
||||
|
||||
// Test setting value within range
|
||||
numericUpDown.Value = 50u;
|
||||
Assert.Equal(50u, numericUpDown.Value);
|
||||
|
||||
// Test clamping above maximum
|
||||
numericUpDown.Value = 150u;
|
||||
Assert.Equal(100u, numericUpDown.Value);
|
||||
}
|
||||
|
||||
[AvaloniaFact]
|
||||
public void NumericUIntUpDown_Should_Parse_Text_Correctly()
|
||||
{
|
||||
var window = new Window();
|
||||
var numericUpDown = new NumericUIntUpDown();
|
||||
window.Content = numericUpDown;
|
||||
window.Show();
|
||||
|
||||
var parseMethod = typeof(NumericUIntUpDown).GetMethod("ParseText", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance);
|
||||
Assert.NotNull(parseMethod);
|
||||
|
||||
var parameters = new object[] { "123", (uint)0 };
|
||||
var result = (bool)parseMethod.Invoke(numericUpDown, parameters);
|
||||
var parsedValue = (uint)parameters[1];
|
||||
|
||||
Assert.True(result);
|
||||
Assert.Equal(123u, parsedValue);
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region Double Tests
|
||||
[AvaloniaFact]
|
||||
public void NumericDoubleUpDown_Should_Initialize_With_Correct_Defaults()
|
||||
{
|
||||
var window = new Window();
|
||||
var numericUpDown = new NumericDoubleUpDown();
|
||||
window.Content = numericUpDown;
|
||||
window.Show();
|
||||
|
||||
Assert.Null(numericUpDown.Value);
|
||||
Assert.Equal(double.MaxValue, numericUpDown.Maximum);
|
||||
Assert.Equal(double.MinValue, numericUpDown.Minimum);
|
||||
Assert.Equal(1.0, numericUpDown.Step);
|
||||
}
|
||||
|
||||
[AvaloniaFact]
|
||||
public void NumericDoubleUpDown_Should_Handle_Decimal_Values()
|
||||
{
|
||||
var window = new Window();
|
||||
var numericUpDown = new NumericDoubleUpDown
|
||||
{
|
||||
Value = 10.5,
|
||||
Step = 0.1,
|
||||
Minimum = 0.0,
|
||||
Maximum = 100.0
|
||||
};
|
||||
window.Content = numericUpDown;
|
||||
window.Show();
|
||||
|
||||
Assert.Equal(10.5, numericUpDown.Value);
|
||||
|
||||
numericUpDown.Value = 3.14159;
|
||||
Assert.Equal(3.14159, numericUpDown.Value);
|
||||
}
|
||||
|
||||
[AvaloniaFact]
|
||||
public void NumericDoubleUpDown_Should_Parse_Decimal_Text()
|
||||
{
|
||||
var window = new Window();
|
||||
var numericUpDown = new NumericDoubleUpDown();
|
||||
window.Content = numericUpDown;
|
||||
window.Show();
|
||||
|
||||
var parseMethod = typeof(NumericDoubleUpDown).GetMethod("ParseText", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance);
|
||||
Assert.NotNull(parseMethod);
|
||||
|
||||
var parameters = new object[] { "123.456", 0.0 };
|
||||
var result = (bool)parseMethod.Invoke(numericUpDown, parameters);
|
||||
var parsedValue = (double)parameters[1];
|
||||
|
||||
Assert.True(result);
|
||||
Assert.Equal(123.456, parsedValue, precision: 10);
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region Byte Tests
|
||||
[AvaloniaFact]
|
||||
public void NumericByteUpDown_Should_Initialize_With_Correct_Defaults()
|
||||
{
|
||||
var window = new Window();
|
||||
var numericUpDown = new NumericByteUpDown();
|
||||
window.Content = numericUpDown;
|
||||
window.Show();
|
||||
|
||||
Assert.Null(numericUpDown.Value);
|
||||
Assert.Equal(byte.MaxValue, numericUpDown.Maximum);
|
||||
Assert.Equal(byte.MinValue, numericUpDown.Minimum);
|
||||
Assert.Equal((byte)1, numericUpDown.Step);
|
||||
}
|
||||
|
||||
[AvaloniaFact]
|
||||
public void NumericByteUpDown_Should_Respect_Byte_Range()
|
||||
{
|
||||
var window = new Window();
|
||||
var numericUpDown = new NumericByteUpDown();
|
||||
window.Content = numericUpDown;
|
||||
window.Show();
|
||||
|
||||
// Test maximum value
|
||||
numericUpDown.Value = 255;
|
||||
Assert.Equal((byte)255, numericUpDown.Value);
|
||||
|
||||
// Test minimum value
|
||||
numericUpDown.Value = 0;
|
||||
Assert.Equal((byte)0, numericUpDown.Value);
|
||||
|
||||
// Test overflow should clamp to max - test using the Maximum property constraint
|
||||
numericUpDown.Maximum = 200;
|
||||
numericUpDown.Value = 250; // This should be clamped to Maximum
|
||||
Assert.Equal((byte)200, numericUpDown.Value);
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region SByte Tests
|
||||
[AvaloniaFact]
|
||||
public void NumericSByteUpDown_Should_Initialize_With_Correct_Defaults()
|
||||
{
|
||||
var window = new Window();
|
||||
var numericUpDown = new NumericSByteUpDown();
|
||||
window.Content = numericUpDown;
|
||||
window.Show();
|
||||
|
||||
Assert.Null(numericUpDown.Value);
|
||||
Assert.Equal(sbyte.MaxValue, numericUpDown.Maximum);
|
||||
Assert.Equal(sbyte.MinValue, numericUpDown.Minimum);
|
||||
Assert.Equal((sbyte)1, numericUpDown.Step);
|
||||
}
|
||||
|
||||
[AvaloniaFact]
|
||||
public void NumericSByteUpDown_Should_Handle_Negative_Values()
|
||||
{
|
||||
var window = new Window();
|
||||
var numericUpDown = new NumericSByteUpDown();
|
||||
window.Content = numericUpDown;
|
||||
window.Show();
|
||||
|
||||
numericUpDown.Value = -50;
|
||||
Assert.Equal((sbyte)(-50), numericUpDown.Value);
|
||||
|
||||
numericUpDown.Value = 127;
|
||||
Assert.Equal((sbyte)127, numericUpDown.Value);
|
||||
|
||||
numericUpDown.Value = -128;
|
||||
Assert.Equal((sbyte)(-128), numericUpDown.Value);
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region Short Tests
|
||||
[AvaloniaFact]
|
||||
public void NumericShortUpDown_Should_Initialize_With_Correct_Defaults()
|
||||
{
|
||||
var window = new Window();
|
||||
var numericUpDown = new NumericShortUpDown();
|
||||
window.Content = numericUpDown;
|
||||
window.Show();
|
||||
|
||||
Assert.Null(numericUpDown.Value);
|
||||
Assert.Equal(short.MaxValue, numericUpDown.Maximum);
|
||||
Assert.Equal(short.MinValue, numericUpDown.Minimum);
|
||||
Assert.Equal((short)1, numericUpDown.Step);
|
||||
}
|
||||
|
||||
[AvaloniaFact]
|
||||
public void NumericShortUpDown_Should_Handle_Short_Range()
|
||||
{
|
||||
var window = new Window();
|
||||
var numericUpDown = new NumericShortUpDown();
|
||||
window.Content = numericUpDown;
|
||||
window.Show();
|
||||
|
||||
numericUpDown.Value = 32767;
|
||||
Assert.Equal((short)32767, numericUpDown.Value);
|
||||
|
||||
numericUpDown.Value = -32768;
|
||||
Assert.Equal((short)(-32768), numericUpDown.Value);
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region UShort Tests
|
||||
[AvaloniaFact]
|
||||
public void NumericUShortUpDown_Should_Initialize_With_Correct_Defaults()
|
||||
{
|
||||
var window = new Window();
|
||||
var numericUpDown = new NumericUShortUpDown();
|
||||
window.Content = numericUpDown;
|
||||
window.Show();
|
||||
|
||||
Assert.Null(numericUpDown.Value);
|
||||
Assert.Equal(ushort.MaxValue, numericUpDown.Maximum);
|
||||
Assert.Equal(ushort.MinValue, numericUpDown.Minimum);
|
||||
Assert.Equal((ushort)1, numericUpDown.Step);
|
||||
}
|
||||
|
||||
[AvaloniaFact]
|
||||
public void NumericUShortUpDown_Should_Handle_UShort_Range()
|
||||
{
|
||||
var window = new Window();
|
||||
var numericUpDown = new NumericUShortUpDown();
|
||||
window.Content = numericUpDown;
|
||||
window.Show();
|
||||
|
||||
numericUpDown.Value = 65535;
|
||||
Assert.Equal((ushort)65535, numericUpDown.Value);
|
||||
|
||||
numericUpDown.Value = 0;
|
||||
Assert.Equal((ushort)0, numericUpDown.Value);
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region Long Tests
|
||||
[AvaloniaFact]
|
||||
public void NumericLongUpDown_Should_Initialize_With_Correct_Defaults()
|
||||
{
|
||||
var window = new Window();
|
||||
var numericUpDown = new NumericLongUpDown();
|
||||
window.Content = numericUpDown;
|
||||
window.Show();
|
||||
|
||||
Assert.Null(numericUpDown.Value);
|
||||
Assert.Equal(long.MaxValue, numericUpDown.Maximum);
|
||||
Assert.Equal(long.MinValue, numericUpDown.Minimum);
|
||||
Assert.Equal(1L, numericUpDown.Step);
|
||||
}
|
||||
|
||||
[AvaloniaFact]
|
||||
public void NumericLongUpDown_Should_Handle_Large_Values()
|
||||
{
|
||||
var window = new Window();
|
||||
var numericUpDown = new NumericLongUpDown();
|
||||
window.Content = numericUpDown;
|
||||
window.Show();
|
||||
|
||||
var largeValue = 9223372036854775807L; // long.MaxValue
|
||||
numericUpDown.Value = largeValue;
|
||||
Assert.Equal(largeValue, numericUpDown.Value);
|
||||
|
||||
var smallValue = -9223372036854775808L; // long.MinValue
|
||||
numericUpDown.Value = smallValue;
|
||||
Assert.Equal(smallValue, numericUpDown.Value);
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region ULong Tests
|
||||
[AvaloniaFact]
|
||||
public void NumericULongUpDown_Should_Initialize_With_Correct_Defaults()
|
||||
{
|
||||
var window = new Window();
|
||||
var numericUpDown = new NumericULongUpDown();
|
||||
window.Content = numericUpDown;
|
||||
window.Show();
|
||||
|
||||
Assert.Null(numericUpDown.Value);
|
||||
Assert.Equal(ulong.MaxValue, numericUpDown.Maximum);
|
||||
Assert.Equal(ulong.MinValue, numericUpDown.Minimum);
|
||||
Assert.Equal(1UL, numericUpDown.Step);
|
||||
}
|
||||
|
||||
[AvaloniaFact]
|
||||
public void NumericULongUpDown_Should_Handle_Large_Unsigned_Values()
|
||||
{
|
||||
var window = new Window();
|
||||
var numericUpDown = new NumericULongUpDown();
|
||||
window.Content = numericUpDown;
|
||||
window.Show();
|
||||
|
||||
var largeValue = 18446744073709551615UL; // ulong.MaxValue
|
||||
numericUpDown.Value = largeValue;
|
||||
Assert.Equal(largeValue, numericUpDown.Value);
|
||||
|
||||
numericUpDown.Value = 0UL;
|
||||
Assert.Equal(0UL, numericUpDown.Value);
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region Float Tests
|
||||
[AvaloniaFact]
|
||||
public void NumericFloatUpDown_Should_Initialize_With_Correct_Defaults()
|
||||
{
|
||||
var window = new Window();
|
||||
var numericUpDown = new NumericFloatUpDown();
|
||||
window.Content = numericUpDown;
|
||||
window.Show();
|
||||
|
||||
Assert.Null(numericUpDown.Value);
|
||||
Assert.Equal(float.MaxValue, numericUpDown.Maximum);
|
||||
Assert.Equal(float.MinValue, numericUpDown.Minimum);
|
||||
Assert.Equal(1.0f, numericUpDown.Step);
|
||||
}
|
||||
|
||||
[AvaloniaFact]
|
||||
public void NumericFloatUpDown_Should_Handle_Float_Precision()
|
||||
{
|
||||
var window = new Window();
|
||||
var numericUpDown = new NumericFloatUpDown();
|
||||
window.Content = numericUpDown;
|
||||
window.Show();
|
||||
|
||||
var preciseValue = 3.14159f;
|
||||
numericUpDown.Value = preciseValue;
|
||||
Assert.Equal(preciseValue, numericUpDown.Value);
|
||||
|
||||
// Test very small values
|
||||
var smallValue = 0.0001f;
|
||||
numericUpDown.Value = smallValue;
|
||||
Assert.Equal((double)smallValue, (double)numericUpDown.Value!, precision: 4);
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region Decimal Tests
|
||||
[AvaloniaFact]
|
||||
public void NumericDecimalUpDown_Should_Initialize_With_Correct_Defaults()
|
||||
{
|
||||
var window = new Window();
|
||||
var numericUpDown = new NumericDecimalUpDown();
|
||||
window.Content = numericUpDown;
|
||||
window.Show();
|
||||
|
||||
Assert.Null(numericUpDown.Value);
|
||||
Assert.Equal(decimal.MaxValue, numericUpDown.Maximum);
|
||||
Assert.Equal(decimal.MinValue, numericUpDown.Minimum);
|
||||
Assert.Equal(1m, numericUpDown.Step);
|
||||
}
|
||||
|
||||
[AvaloniaFact]
|
||||
public void NumericDecimalUpDown_Should_Handle_High_Precision_Decimals()
|
||||
{
|
||||
var window = new Window();
|
||||
var numericUpDown = new NumericDecimalUpDown();
|
||||
window.Content = numericUpDown;
|
||||
window.Show();
|
||||
|
||||
var preciseValue = 123.456789123456789m;
|
||||
numericUpDown.Value = preciseValue;
|
||||
Assert.Equal(preciseValue, numericUpDown.Value);
|
||||
|
||||
// Test currency-like values
|
||||
var currencyValue = 1234.56m;
|
||||
numericUpDown.Value = currencyValue;
|
||||
Assert.Equal(currencyValue, numericUpDown.Value);
|
||||
}
|
||||
|
||||
[AvaloniaFact]
|
||||
public void NumericDecimalUpDown_Should_Parse_Decimal_Text()
|
||||
{
|
||||
var window = new Window();
|
||||
var numericUpDown = new NumericDecimalUpDown();
|
||||
window.Content = numericUpDown;
|
||||
window.Show();
|
||||
|
||||
var parseMethod = typeof(NumericDecimalUpDown).GetMethod("ParseText", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance);
|
||||
Assert.NotNull(parseMethod);
|
||||
|
||||
var parameters = new object[] { "123.456", 0m };
|
||||
var result = (bool)parseMethod.Invoke(numericUpDown, parameters);
|
||||
var parsedValue = (decimal)parameters[1];
|
||||
|
||||
Assert.True(result);
|
||||
Assert.Equal(123.456m, parsedValue);
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region Cross-Type Validation Tests
|
||||
[AvaloniaTheory]
|
||||
[InlineData(typeof(NumericIntUpDown))]
|
||||
[InlineData(typeof(NumericUIntUpDown))]
|
||||
[InlineData(typeof(NumericDoubleUpDown))]
|
||||
[InlineData(typeof(NumericByteUpDown))]
|
||||
[InlineData(typeof(NumericSByteUpDown))]
|
||||
[InlineData(typeof(NumericShortUpDown))]
|
||||
[InlineData(typeof(NumericUShortUpDown))]
|
||||
[InlineData(typeof(NumericLongUpDown))]
|
||||
[InlineData(typeof(NumericULongUpDown))]
|
||||
[InlineData(typeof(NumericFloatUpDown))]
|
||||
[InlineData(typeof(NumericDecimalUpDown))]
|
||||
public void All_NumericUpDown_Types_Should_Support_Clear_Operation(Type numericUpDownType)
|
||||
{
|
||||
var window = new Window();
|
||||
var numericUpDown = Activator.CreateInstance(numericUpDownType)!;
|
||||
window.Content = (Control)numericUpDown;
|
||||
window.Show();
|
||||
|
||||
// Set a value using reflection (since each type has different value types)
|
||||
var valueProperty = numericUpDownType.GetProperty("Value");
|
||||
Assert.NotNull(valueProperty);
|
||||
|
||||
// Set some non-null value (using appropriate type for each numeric type)
|
||||
object testValue = numericUpDownType.Name switch
|
||||
{
|
||||
nameof(NumericIntUpDown) => 42,
|
||||
nameof(NumericUIntUpDown) => 42u,
|
||||
nameof(NumericDoubleUpDown) => 42.0,
|
||||
nameof(NumericByteUpDown) => (byte)42,
|
||||
nameof(NumericSByteUpDown) => (sbyte)42,
|
||||
nameof(NumericShortUpDown) => (short)42,
|
||||
nameof(NumericUShortUpDown) => (ushort)42,
|
||||
nameof(NumericLongUpDown) => 42L,
|
||||
nameof(NumericULongUpDown) => 42UL,
|
||||
nameof(NumericFloatUpDown) => 42.0f,
|
||||
nameof(NumericDecimalUpDown) => 42m,
|
||||
_ => throw new ArgumentException($"Unknown type: {numericUpDownType.Name}")
|
||||
};
|
||||
|
||||
valueProperty.SetValue(numericUpDown, testValue);
|
||||
Assert.NotNull(valueProperty.GetValue(numericUpDown));
|
||||
|
||||
// Test Clear operation
|
||||
var clearMethod = numericUpDownType.GetMethod("Clear");
|
||||
Assert.NotNull(clearMethod);
|
||||
clearMethod.Invoke(numericUpDown, null);
|
||||
|
||||
// Value should be null after clear (or EmptyInputValue if set)
|
||||
var clearedValue = valueProperty.GetValue(numericUpDown);
|
||||
Assert.True(clearedValue == null || clearedValue.Equals(GetEmptyInputValue(numericUpDown)));
|
||||
}
|
||||
|
||||
private static object? GetEmptyInputValue(object numericUpDown)
|
||||
{
|
||||
var emptyInputValueProperty = numericUpDown.GetType().GetProperty("EmptyInputValue");
|
||||
return emptyInputValueProperty?.GetValue(numericUpDown);
|
||||
}
|
||||
|
||||
[AvaloniaTheory]
|
||||
[InlineData(typeof(NumericIntUpDown))]
|
||||
[InlineData(typeof(NumericUIntUpDown))]
|
||||
[InlineData(typeof(NumericDoubleUpDown))]
|
||||
[InlineData(typeof(NumericByteUpDown))]
|
||||
[InlineData(typeof(NumericSByteUpDown))]
|
||||
[InlineData(typeof(NumericShortUpDown))]
|
||||
[InlineData(typeof(NumericUShortUpDown))]
|
||||
[InlineData(typeof(NumericLongUpDown))]
|
||||
[InlineData(typeof(NumericULongUpDown))]
|
||||
[InlineData(typeof(NumericFloatUpDown))]
|
||||
[InlineData(typeof(NumericDecimalUpDown))]
|
||||
public void All_NumericUpDown_Types_Should_Have_Correct_StyleKeyOverride(Type numericUpDownType)
|
||||
{
|
||||
var window = new Window();
|
||||
var numericUpDown = Activator.CreateInstance(numericUpDownType)!;
|
||||
window.Content = (Control)numericUpDown;
|
||||
window.Show();
|
||||
|
||||
// All specific implementations should use the base NumericUpDown style
|
||||
var styleKeyProperty = numericUpDownType.GetProperty("StyleKeyOverride", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance);
|
||||
if (styleKeyProperty != null)
|
||||
{
|
||||
var styleKey = styleKeyProperty.GetValue(numericUpDown);
|
||||
Assert.Equal(typeof(global::Ursa.Controls.NumericUpDown), styleKey);
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
Reference in New Issue
Block a user