From b3d08f04d6416a92fdaeba84d065b19482f54072 Mon Sep 17 00:00:00 2001 From: Christoph P Date: Mon, 22 Nov 2021 17:04:01 +0100 Subject: [PATCH 1/3] Add test for DateTime and TimeSpan ~ set CultureInfo on test start + add test for DateTime + add test for TimeSpan --- .../DataGrid/Utils/FunctionCompilerTests.cs | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/Tests/Blazorise.Tests/DataGrid/Utils/FunctionCompilerTests.cs b/Tests/Blazorise.Tests/DataGrid/Utils/FunctionCompilerTests.cs index 31c96139b8..d2bc95dc6d 100644 --- a/Tests/Blazorise.Tests/DataGrid/Utils/FunctionCompilerTests.cs +++ b/Tests/Blazorise.Tests/DataGrid/Utils/FunctionCompilerTests.cs @@ -1,5 +1,7 @@ -using System.Collections; +using System; +using System.Collections; using System.Collections.Generic; +using System.Globalization; using Blazorise.DataGrid; using Blazorise.DataGrid.Utils; using Xunit; @@ -13,6 +15,8 @@ public class FunctionCompilerTests [InlineData( "Name", null )] [InlineData( "Value", null )] [InlineData( "Boolean", "False" )] + [InlineData( "DateTime", "1/1/0001 12:00:00 AM" )] + [InlineData( "DateTime.TimeOfDay", "12:00:00 AM" )] [InlineData( "Information.Id", "0" )] [InlineData( "Information.Message", null )] [InlineData( "Information.Detail.Id", "0" )] @@ -30,6 +34,8 @@ public void ValueGetter_ReturnsCorrectPropertyOrField_DefaultValue(string field, [InlineData( "Name", "John" )] [InlineData( "Value", "200" )] [InlineData( "Boolean", "True" )] + [InlineData( "DateTime", "12/31/9999 11:59:59 PM" )] + [InlineData( "DateTime.TimeOfDay", "11:59:59 PM" )] [InlineData( "Information.Id", "1000" )] [InlineData( "Information.Message", "This is a message!" )] [InlineData( "Information.Detail.Id", "2000" )] @@ -42,6 +48,12 @@ public void ValueGetter_ReturnsCorrectPropertyOrField_ActualValue( string field, Assert.Equal( expected, valueGetter( test )?.ToString() ); } + public FunctionCompilerTests() + { + // force to use us culture info + CultureInfo.CurrentCulture = new CultureInfo( "en-US" ); + } + private Test GetTest() { return new() @@ -50,6 +62,7 @@ private Test GetTest() Name = "John", Value = 200, Boolean = true, + DateTime = DateTime.MaxValue, Information = new() { Id = 1000, @@ -71,6 +84,7 @@ private class Test public string Name { get; set; } public int? Value { get; set; } public bool Boolean { get; set; } + public DateTime DateTime { get; set; } public Information Information { get; set; } } From fcc279d2a27dfba925e94f43daa14b6269a51b24 Mon Sep 17 00:00:00 2001 From: Christoph P Date: Mon, 22 Nov 2021 17:46:52 +0100 Subject: [PATCH 2/3] Value type comparison + implement value type handling for expression compare ~ fix timespan test to use correct expecting values --- .../Blazorise.DataGrid/Utils/FunctionCompiler.cs | 7 ++++++- .../DataGrid/Utils/FunctionCompilerTests.cs | 4 ++-- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/Source/Extensions/Blazorise.DataGrid/Utils/FunctionCompiler.cs b/Source/Extensions/Blazorise.DataGrid/Utils/FunctionCompiler.cs index 0fe67a501c..bab7ce8cd3 100644 --- a/Source/Extensions/Blazorise.DataGrid/Utils/FunctionCompiler.cs +++ b/Source/Extensions/Blazorise.DataGrid/Utils/FunctionCompiler.cs @@ -32,6 +32,9 @@ private static Expression GetSafePropertyOrField( Expression item, string proper Expression field = null; MemberInfo memberInfo = GetSafeMember( item.Type, parts[0] ); + + if ( memberInfo.ReflectedType == null ) + throw new ArgumentException( $"Cannot detect type of {item.Type}" ); if ( memberInfo is PropertyInfo propertyInfo ) field = Expression.Property( item, propertyInfo ); @@ -41,7 +44,9 @@ private static Expression GetSafePropertyOrField( Expression item, string proper if ( field == null ) throw new ArgumentException( $"Cannot detect the member of {item.Type}", propertyOrFieldName ); - field = Expression.Condition( Expression.Equal( item, Expression.Constant( null ) ), + var nullObject = Expression.Constant( memberInfo.ReflectedType.IsValueType ? Activator.CreateInstance( memberInfo.ReflectedType ) : null ); + + field = Expression.Condition( Expression.Equal( item, nullObject ), IsNullable( field.Type ) ? Expression.Constant( null, field.Type ) : Expression.Default( field.Type ), field ); diff --git a/Tests/Blazorise.Tests/DataGrid/Utils/FunctionCompilerTests.cs b/Tests/Blazorise.Tests/DataGrid/Utils/FunctionCompilerTests.cs index d2bc95dc6d..1dfeae08ef 100644 --- a/Tests/Blazorise.Tests/DataGrid/Utils/FunctionCompilerTests.cs +++ b/Tests/Blazorise.Tests/DataGrid/Utils/FunctionCompilerTests.cs @@ -16,7 +16,7 @@ public class FunctionCompilerTests [InlineData( "Value", null )] [InlineData( "Boolean", "False" )] [InlineData( "DateTime", "1/1/0001 12:00:00 AM" )] - [InlineData( "DateTime.TimeOfDay", "12:00:00 AM" )] + [InlineData( "DateTime.TimeOfDay", "00:00:00" )] [InlineData( "Information.Id", "0" )] [InlineData( "Information.Message", null )] [InlineData( "Information.Detail.Id", "0" )] @@ -35,7 +35,7 @@ public void ValueGetter_ReturnsCorrectPropertyOrField_DefaultValue(string field, [InlineData( "Value", "200" )] [InlineData( "Boolean", "True" )] [InlineData( "DateTime", "12/31/9999 11:59:59 PM" )] - [InlineData( "DateTime.TimeOfDay", "11:59:59 PM" )] + [InlineData( "DateTime.TimeOfDay", "23:59:59.9999999" )] [InlineData( "Information.Id", "1000" )] [InlineData( "Information.Message", "This is a message!" )] [InlineData( "Information.Detail.Id", "2000" )] From ad68fa45db5b8d2841815f1a556d3a6cd86150fd Mon Sep 17 00:00:00 2001 From: Christoph P Date: Tue, 23 Nov 2021 08:56:36 +0100 Subject: [PATCH 3/3] add more test & simplify + add more corner test ~ replace activator with expression default ~ replace member.reflectedtype with item.type --- .../Utils/FunctionCompiler.cs | 7 +------ .../DataGrid/Utils/FunctionCompilerTests.cs | 17 +++++++++++++---- 2 files changed, 14 insertions(+), 10 deletions(-) diff --git a/Source/Extensions/Blazorise.DataGrid/Utils/FunctionCompiler.cs b/Source/Extensions/Blazorise.DataGrid/Utils/FunctionCompiler.cs index bab7ce8cd3..6aa686a44d 100644 --- a/Source/Extensions/Blazorise.DataGrid/Utils/FunctionCompiler.cs +++ b/Source/Extensions/Blazorise.DataGrid/Utils/FunctionCompiler.cs @@ -32,9 +32,6 @@ private static Expression GetSafePropertyOrField( Expression item, string proper Expression field = null; MemberInfo memberInfo = GetSafeMember( item.Type, parts[0] ); - - if ( memberInfo.ReflectedType == null ) - throw new ArgumentException( $"Cannot detect type of {item.Type}" ); if ( memberInfo is PropertyInfo propertyInfo ) field = Expression.Property( item, propertyInfo ); @@ -44,9 +41,7 @@ private static Expression GetSafePropertyOrField( Expression item, string proper if ( field == null ) throw new ArgumentException( $"Cannot detect the member of {item.Type}", propertyOrFieldName ); - var nullObject = Expression.Constant( memberInfo.ReflectedType.IsValueType ? Activator.CreateInstance( memberInfo.ReflectedType ) : null ); - - field = Expression.Condition( Expression.Equal( item, nullObject ), + field = Expression.Condition( Expression.Equal( item, Expression.Default( item.Type ) ), IsNullable( field.Type ) ? Expression.Constant( null, field.Type ) : Expression.Default( field.Type ), field ); diff --git a/Tests/Blazorise.Tests/DataGrid/Utils/FunctionCompilerTests.cs b/Tests/Blazorise.Tests/DataGrid/Utils/FunctionCompilerTests.cs index 1dfeae08ef..7bf3ff9128 100644 --- a/Tests/Blazorise.Tests/DataGrid/Utils/FunctionCompilerTests.cs +++ b/Tests/Blazorise.Tests/DataGrid/Utils/FunctionCompilerTests.cs @@ -1,8 +1,5 @@ using System; -using System.Collections; -using System.Collections.Generic; using System.Globalization; -using Blazorise.DataGrid; using Blazorise.DataGrid.Utils; using Xunit; @@ -11,12 +8,15 @@ namespace Blazorise.Tests.DataGrid.Utils public class FunctionCompilerTests { [Theory] - [InlineData("Id", "0")] + [InlineData( "Id", "0" )] [InlineData( "Name", null )] [InlineData( "Value", null )] [InlineData( "Boolean", "False" )] [InlineData( "DateTime", "1/1/0001 12:00:00 AM" )] [InlineData( "DateTime.TimeOfDay", "00:00:00" )] + [InlineData( "DateTimeNull", null )] + [InlineData( "TimeSpan", "00:00:00" )] + [InlineData( "TimeSpanNull", null )] [InlineData( "Information.Id", "0" )] [InlineData( "Information.Message", null )] [InlineData( "Information.Detail.Id", "0" )] @@ -36,6 +36,9 @@ public void ValueGetter_ReturnsCorrectPropertyOrField_DefaultValue(string field, [InlineData( "Boolean", "True" )] [InlineData( "DateTime", "12/31/9999 11:59:59 PM" )] [InlineData( "DateTime.TimeOfDay", "23:59:59.9999999" )] + [InlineData( "DateTimeNull", "8/18/2018 12:00:00 AM" )] + [InlineData( "TimeSpan", "10675199.02:48:05.4775807" )] + [InlineData( "TimeSpanNull", "20:00:00" )] [InlineData( "Information.Id", "1000" )] [InlineData( "Information.Message", "This is a message!" )] [InlineData( "Information.Detail.Id", "2000" )] @@ -63,6 +66,9 @@ private Test GetTest() Value = 200, Boolean = true, DateTime = DateTime.MaxValue, + DateTimeNull = DateTime.Parse( "08/18/2018" ), + TimeSpan = TimeSpan.MaxValue, + TimeSpanNull = TimeSpan.FromHours( 20.0 ), Information = new() { Id = 1000, @@ -85,6 +91,9 @@ private class Test public int? Value { get; set; } public bool Boolean { get; set; } public DateTime DateTime { get; set; } + public DateTime? DateTimeNull { get; set; } + public TimeSpan TimeSpan { get; set; } + public TimeSpan? TimeSpanNull { get; set; } public Information Information { get; set; } }