Skip to content

Commit

Permalink
TimePicker: Handle conversion error (MudBlazor#6947)
Browse files Browse the repository at this point in the history
Co-authored-by: Stefan Jetzer <sj@devigus.com>
  • Loading branch information
Cerberus4444 and Stefan Jetzer authored Jul 12, 2023
1 parent 1f6a74c commit 090c061
Show file tree
Hide file tree
Showing 4 changed files with 65 additions and 25 deletions.
39 changes: 30 additions & 9 deletions src/MudBlazor.UnitTests/Components/TimePickerTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -296,16 +296,16 @@ public void TimeEditModeHours_CheckSelection()
{
var comp = Context.RenderComponent<SimpleTimePickerTest>((Parameter("TimeEditMode", TimeEditMode.OnlyHours)));
var underlyingPicker = comp.FindComponent<MudTimePicker>().Instance;

// click to to open picker
comp.Find("input").Click();

// should be open
comp.WaitForAssertion(() => comp.FindAll("div.mud-picker-open").Count.Should().Be(1));

// click on 13 hour
comp.FindAll("div.mud-picker-stick-outer.mud-hour")[0].Click();

// should be closed
comp.WaitForAssertion(() => comp.FindAll("div.mud-picker-open").Count.Should().Be(0));

Expand All @@ -314,7 +314,7 @@ public void TimeEditModeHours_CheckSelection()

// click to to open picker
comp.Find("input").Click();

// should be open
comp.WaitForAssertion(() => comp.FindAll("div.mud-picker-open").Count.Should().Be(1));

Expand All @@ -328,7 +328,7 @@ public void TimeEditModeHours_CheckSelection()
underlyingPicker.TimeIntermediate.Value.Hours.Should().Be(14);

}

[Test]
public void ChangeToMinutes_FromHours_CheckHoursHidden()
{
Expand Down Expand Up @@ -386,16 +386,37 @@ public void InputStringValues_CheckParsing()
{
var comp = Context.RenderComponent<MudTimePicker>();
var picker = comp.Instance;

// valid time
comp.Find("input").Change("23:02");
picker.TimeIntermediate.Should().Be(new TimeSpan(23, 2, 0));
picker.ConversionError.Should().BeFalse();
picker.ConversionErrorMessage.Should().BeNull();
// empty string equals null TimeSpan?
comp.Find("input").Change("");
picker.TimeIntermediate.Should().BeNull();
picker.Error.Should().BeFalse();
// invalid time
picker.ConversionError.Should().BeFalse();
picker.ConversionErrorMessage.Should().BeNull();
// invalid time (format, AmPm)
comp.Find("input").Change("09:o6 AM");
picker.TimeIntermediate.Should().BeNull();
picker.ConversionError.Should().BeTrue();
picker.ConversionErrorMessage.Should().Be("Not a valid time span");
// invalid time (overflow, AmPm)
comp.Find("input").Change("13:45 AM");
picker.TimeIntermediate.Should().BeNull();
picker.ConversionError.Should().BeTrue();
picker.ConversionErrorMessage.Should().Be("Not a valid time span");
// invalid time (format)
comp.Find("input").Change("2o:32");
picker.TimeIntermediate.Should().BeNull();
picker.ConversionError.Should().BeTrue();
picker.ConversionErrorMessage.Should().Be("Not a valid time span");
// invalid time (overflow)
comp.Find("input").Change("25:06");
picker.TimeIntermediate.Should().BeNull();
picker.ConversionError.Should().BeTrue();
picker.ConversionErrorMessage.Should().Be("Not a valid time span");
}

[Test]
Expand Down Expand Up @@ -632,7 +653,7 @@ public async Task CheckAutoCloseTimePickerTest()
// Select 16 hours
comp.FindAll("div.mud-picker-stick-outer.mud-hour")[3].Click();
picker.TimeIntermediate.Value.Hours.Should().Be(16);

// Select 30 minutes
comp.FindAll("div.mud-minute")[30].Click();
picker.TimeIntermediate.Value.Minutes.Should().Be(30);
Expand Down
14 changes: 9 additions & 5 deletions src/MudBlazor.UnitTests/Utilities/BindingConverterTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -371,23 +371,27 @@ public void BoolConverterTest()
[Test]
public void ErrorCheckingTest()
{
//format exception
// datetime format exception
var dt1 = new DefaultConverter<DateTime>();
dt1.Get("12/34/56").Should().Be(default);
var dtn1 = new DefaultConverter<DateTime?>();
dtn1.Get("12/34/56").Should().Be(null);

// format exception
// timespan format exception
var tm1 = new DefaultConverter<TimeSpan>();
tm1.Get("12:o1").Should().Be(default);
tm1.GetErrorMessage.Should().Be("Not a valid time span");
var tmn1 = new DefaultConverter<TimeSpan?>();
tmn1.Get("12:o1").Should().Be(null);
tmn1.GetErrorMessage.Should().Be("Not a valid time span");

// overflow
// timespan overflow exception
var tm2 = new DefaultConverter<TimeSpan>();
tm2.Get("25:00").Should().Be(default);
var tm2n = new DefaultConverter<TimeSpan?>();
tm2n.Get("25:00").Should().Be(null);
tm2.GetErrorMessage.Should().Be("Not a valid time span");
var tmn2 = new DefaultConverter<TimeSpan?>();
tmn2.Get("25:00").Should().Be(null);
tmn2.GetErrorMessage.Should().Be("Not a valid time span");

// not a valid number
var c1 = new DefaultConverter<sbyte>();
Expand Down
35 changes: 25 additions & 10 deletions src/MudBlazor/Components/TimePicker/MudTimePicker.razor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,6 @@
using System.Threading.Tasks;
using Microsoft.AspNetCore.Components;
using Microsoft.AspNetCore.Components.Web;
using MudBlazor.Extensions;
using MudBlazor.Services;
using MudBlazor.Utilities;

namespace MudBlazor
Expand Down Expand Up @@ -44,18 +42,35 @@ private string OnSet(TimeSpan? timespan)
{
return time.TimeOfDay;
}
else

var m = Regex.Match(value, "AM|PM", RegexOptions.IgnoreCase);
if (m.Success)
{
var m = Regex.Match(value, "AM|PM", RegexOptions.IgnoreCase);
if (m.Success)
if (DateTime.TryParseExact(value, format12Hours, CultureInfo.InvariantCulture, DateTimeStyles.None,
out time))
{
return DateTime.ParseExact(value, format12Hours, CultureInfo.InvariantCulture).TimeOfDay;
return time.TimeOfDay;
}
else
}
else
{
if (DateTime.TryParseExact(value, format24Hours, CultureInfo.InvariantCulture, DateTimeStyles.None,
out time))
{
return DateTime.ParseExact(value, format24Hours, CultureInfo.InvariantCulture).TimeOfDay;
return time.TimeOfDay;
}
}

HandleParsingError();
return null;
}

private void HandleParsingError()
{
const string ParsingErrorMessage = "Not a valid time span";
Converter.GetError = true;
Converter.GetErrorMessage = ParsingErrorMessage;
Converter.OnError?.Invoke(ParsingErrorMessage);
}

private bool _amPm = false;
Expand Down Expand Up @@ -228,7 +243,7 @@ private string GetMinuteString()
private void UpdateTime()
{
TimeIntermediate = new TimeSpan(_timeSet.Hour, _timeSet.Minute, 0);
if((PickerVariant == PickerVariant.Static && PickerActions == null) || (PickerActions != null && AutoClose))
if ((PickerVariant == PickerVariant.Static && PickerActions == null) || (PickerActions != null && AutoClose))
{
Submit();
}
Expand Down Expand Up @@ -473,7 +488,7 @@ private void OnMouseClickHour(int value)
}
_timeSet.Hour = h;

if(_currentView == OpenTo.Hours)
if (_currentView == OpenTo.Hours)
{
UpdateTime();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -161,7 +161,7 @@ protected virtual T ConvertFromString(string value)
{
return (T)(object)TimeSpan.ParseExact(value, Format ?? DefaultTimeSpanFormat, Culture);
}
catch (FormatException)
catch (Exception e) when (e is FormatException or OverflowException)
{
UpdateGetError("Not a valid time span");
}
Expand Down

0 comments on commit 090c061

Please sign in to comment.