Skip to content

Commit

Permalink
test: Type check for dependency properties
Browse files Browse the repository at this point in the history
  • Loading branch information
MartinZikmund committed Feb 18, 2025
1 parent e0d4ae8 commit 6084b6e
Show file tree
Hide file tree
Showing 2 changed files with 105 additions and 0 deletions.
105 changes: 105 additions & 0 deletions src/Uno.UI.Tests/DependencyProperty/Given_DependencyProperty.Type.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
using System;
using System.Linq;
using System.Reflection;
using Microsoft.UI.Xaml;
using Microsoft.UI.Xaml.Controls;
using Microsoft.VisualStudio.TestTools.UnitTesting;

namespace Uno.UI.Tests;

[TestClass]
public class DependencyProperty_Type
{
[TestMethod]
public void Check_All_DP_Data_Types()
{
var getOwnerType = GetOwnerGetter();

var asm = typeof(FrameworkElement).Assembly;

foreach (var dependencyObject in asm.DefinedTypes.Where(t => t.ImplementedInterfaces.Contains(typeof(DependencyObject))))
{
// If there is a static DependencyProperty property with name "XProperty" and also a instance property with the name "X"
// check whether the type of X == the "PropertyType" of the DependencyProperty property
var dependencyProperties = dependencyObject.DeclaredProperties
.Where(p => p.PropertyType == typeof(DependencyProperty) &&
p.Name.EndsWith("Property") &&
p.GetCustomAttributes(typeof(NotImplementedAttribute), true).Length == 0 &&
(p.GetGetMethod()?.IsStatic ?? false)
);

foreach (var dpInfo in dependencyProperties)
{
var associatedInstanceProperty = dependencyObject.DeclaredProperties.FirstOrDefault(
p => p.Name == dpInfo.Name.Substring(0, dpInfo.Name.Length - "Property".Length)
);

if (associatedInstanceProperty is null)
{
continue;
}

var type = associatedInstanceProperty?.PropertyType;
var dp = (DependencyProperty)dpInfo.GetValue(null);

CheckType(dp, type);
}
}
}

[TestMethod]
public void Check_All_DP_Default_Value_Types()
{
var getOwnerType = GetOwnerGetter();

Check notice on line 53 in src/Uno.UI.Tests/DependencyProperty/Given_DependencyProperty.Type.cs

View check run for this annotation

Codacy Production / Codacy Static Code Analysis

src/Uno.UI.Tests/DependencyProperty/Given_DependencyProperty.Type.cs#L53

Remove the unused local variable 'getOwnerType'.
var asm = typeof(FrameworkElement).Assembly;
foreach (var dependencyObject in asm.DefinedTypes.Where(t => t.ImplementedInterfaces.Contains(typeof(DependencyObject))))
{
var dependencyProperties = dependencyObject.DeclaredProperties
.Where(p => p.PropertyType == typeof(DependencyProperty) &&
p.GetCustomAttributes(typeof(NotImplementedAttribute), true).Length == 0 &&
(p.GetGetMethod()?.IsStatic ?? false)
);

foreach (var dpInfo in dependencyProperties)
{
var dp = (DependencyProperty)dpInfo.GetValue(null);
CheckDefaultValue(dp);
}
}
}

private void CheckDefaultValue(DependencyProperty property)
{
var dpSpecifiedType = property.Type;
var dpDefaultValue = property.GetDefaultValue(null, property.OwnerType);
if (dpDefaultValue is null)
{
// type needs to be a reference type
Assert.IsFalse(dpSpecifiedType.IsValueType);
}
else
{
// type needs to be same type or derived from it
Assert.IsTrue(dpSpecifiedType.IsAssignableFrom(dpDefaultValue.GetType()));
}
}

private static void CheckType(DependencyProperty dp, Type expectedType)
{
var dpSpecifiedType = dp.Type;

if (expectedType != typeof(PasswordRevealMode))
{
Assert.AreEqual(expectedType, dpSpecifiedType, $"Type mismatch for {dp.Name} on {dp.OwnerType}");
}
}

private static Func<DependencyProperty, Type> GetOwnerGetter()
{
var all = typeof(DependencyProperty).GetProperties();

Check notice on line 99 in src/Uno.UI.Tests/DependencyProperty/Given_DependencyProperty.Type.cs

View check run for this annotation

Codacy Production / Codacy Static Code Analysis

src/Uno.UI.Tests/DependencyProperty/Given_DependencyProperty.Type.cs#L99

Remove the unused local variable 'all'.
var all2 = typeof(DependencyProperty).GetProperties(BindingFlags.NonPublic | BindingFlags.Instance);

Check warning on line 100 in src/Uno.UI.Tests/DependencyProperty/Given_DependencyProperty.Type.cs

View check run for this annotation

Codacy Production / Codacy Static Code Analysis

src/Uno.UI.Tests/DependencyProperty/Given_DependencyProperty.Type.cs#L100

Make sure that this accessibility bypass is safe here.

Check notice on line 100 in src/Uno.UI.Tests/DependencyProperty/Given_DependencyProperty.Type.cs

View check run for this annotation

Codacy Production / Codacy Static Code Analysis

src/Uno.UI.Tests/DependencyProperty/Given_DependencyProperty.Type.cs#L100

Remove the unused local variable 'all2'.
var p = typeof(DependencyProperty).GetProperty("OwnerType", BindingFlags.NonPublic | BindingFlags.Instance);

Check warning on line 101 in src/Uno.UI.Tests/DependencyProperty/Given_DependencyProperty.Type.cs

View check run for this annotation

Codacy Production / Codacy Static Code Analysis

src/Uno.UI.Tests/DependencyProperty/Given_DependencyProperty.Type.cs#L101

Make sure that this accessibility bypass is safe here.

return o => (Type)p.GetValue(o);
}
}

0 comments on commit 6084b6e

Please sign in to comment.