@@ -1234,7 +1234,7 @@ public void When_xBind_TwoWay_Back()
1234
1234
[ TestMethod ]
1235
1235
public void When_Collection_Implicit_Add_Item ( )
1236
1236
{
1237
- var SUT = LoadXaml < SwipeItems > ( """
1237
+ var SUT = XamlHelper . LoadXaml < SwipeItems > ( """
1238
1238
<SwipeItems>
1239
1239
<SwipeItem Text="asd" />
1240
1240
</SwipeItems>
@@ -1247,7 +1247,7 @@ public void When_Collection_Implicit_Add_Item()
1247
1247
[ TestMethod ]
1248
1248
public void When_Collection_Property_Nest_Collection ( )
1249
1249
{
1250
- var SUT = LoadXaml < SwipeControl > ( """
1250
+ var SUT = XamlHelper . LoadXaml < SwipeControl > ( """
1251
1251
<SwipeControl>
1252
1252
<SwipeControl.LeftItems>
1253
1253
<SwipeItems Mode="Execute">
@@ -1266,7 +1266,7 @@ public void When_Collection_Property_Nest_Collection()
1266
1266
[ TestMethod ]
1267
1267
public void When_Collection_Property_Nest_Multiple_Collections ( )
1268
1268
{
1269
- var SUT = LoadXaml < SwipeControl > ( """
1269
+ var SUT = XamlHelper . LoadXaml < SwipeControl > ( """
1270
1270
<SwipeControl>
1271
1271
<SwipeControl.LeftItems>
1272
1272
<!-- This is actually allowed, however only the last will be kept -->
@@ -1504,6 +1504,14 @@ public void When_Geometry()
1504
1504
Assert . AreEqual ( FillRule . EvenOdd , geometry . FillRule ) ;
1505
1505
}
1506
1506
1507
+ [ TestMethod ]
1508
+ public void When_RectangleGeometry ( )
1509
+ {
1510
+ var sut = XamlHelper . LoadXaml < RectangleGeometry > ( "<RectangleGeometry Rect='0 1 2 3' />" ) ;
1511
+
1512
+ Assert . AreEqual ( new Windows . Foundation . Rect ( 0 , 1 , 2 , 3 ) , sut . Rect ) ;
1513
+ }
1514
+
1507
1515
[ TestMethod ]
1508
1516
public void When_ThemeResource_With_StaticResource ( )
1509
1517
{
@@ -1598,35 +1606,6 @@ public void When_Binding_Converter_StaticResource()
1598
1606
Assert . AreEqual ( new CornerRadius ( 0 , 6 , 6 , 0 ) , rightRadiusGrid . CornerRadius ) ;
1599
1607
}
1600
1608
1601
- /// <summary>
1602
- /// XamlReader.Load the xaml and type-check result.
1603
- /// </summary>
1604
- /// <param name="sanitizedXaml">Xaml with single or double quots</param>
1605
- /// <param name="defaultXmlns">The default xmlns to inject; use null to not inject one.</param>
1606
- private T LoadXaml < T > ( string sanitizedXaml , string defaultXmlns = "http://schemas.microsoft.com/winfx/2006/xaml/presentation" ) where T : class =>
1607
- LoadXaml < T > ( sanitizedXaml , new Dictionary < string , string > { [ string . Empty ] = defaultXmlns } ) ;
1608
-
1609
- /// <summary>
1610
- /// XamlReader.Load the xaml and type-check result.
1611
- /// </summary>
1612
- /// <param name="sanitizedXaml">Xaml with single or double quots</param>
1613
- /// <param name="xmlnses">Xmlns to inject; use string.Empty for the default xmlns' key</param>
1614
- private T LoadXaml < T > ( string xaml , Dictionary < string , string > xmlnses ) where T : class
1615
- {
1616
- var injection = " " + string . Join ( " " , xmlnses
1617
- . Where ( x => x . Value != null )
1618
- . Select ( x => $ "xmlns{ ( string . IsNullOrEmpty ( x . Key ) ? "" : $ ":{ x . Key } ") } =\" { x . Value } \" ")
1619
- ) ;
1620
-
1621
- xaml = new Regex ( @"(?=\\?>)" ) . Replace ( xaml , injection , 1 ) ;
1622
-
1623
- var result = Windows . UI . Xaml . Markup . XamlReader . Load ( xaml ) ;
1624
- Assert . IsNotNull ( result , "XamlReader.Load returned null" ) ;
1625
- Assert . IsInstanceOfType ( result , typeof ( T ) , "XamlReader.Load did not return the expected type" ) ;
1626
-
1627
- return ( T ) result ;
1628
- }
1629
-
1630
1609
private string GetContent ( string testName )
1631
1610
{
1632
1611
var assembly = this . GetType ( ) . Assembly ;
@@ -1637,5 +1616,76 @@ private string GetContent(string testName)
1637
1616
return stream . ReadToEnd ( ) ;
1638
1617
}
1639
1618
}
1619
+
1620
+ private static class XamlHelper
1621
+ {
1622
+ /// <summary>
1623
+ /// Matches right before the > or \> tail of any tag.
1624
+ /// </summary>
1625
+ /// <remarks>
1626
+ /// It will match an opening or closing or self-closing tag.
1627
+ /// </remarks>
1628
+ private static readonly Regex EndOfTagRegex = new Regex ( @"(?=( ?/)?>)" ) ;
1629
+
1630
+ /// <summary>
1631
+ /// Matches any tag without xmlns prefix.
1632
+ /// </summary>
1633
+ private static readonly Regex NonXmlnsTagRegex = new Regex ( @"<\w+[ />]" ) ;
1634
+
1635
+ private static readonly IReadOnlyDictionary < string , string > KnownXmlnses = new Dictionary < string , string >
1636
+ {
1637
+ [ string . Empty ] = "http://schemas.microsoft.com/winfx/2006/xaml/presentation" ,
1638
+ [ "x" ] = "http://schemas.microsoft.com/winfx/2006/xaml" ,
1639
+ [ "local" ] = "Uno.UI.Tests.Windows_UI_Xaml_Markup.XamlReaderTests" ,
1640
+ [ "toolkit" ] = "using:Uno.UI.Toolkit" ,
1641
+ [ "muxc" ] = "using:Microsoft.UI.Xaml.Controls" ,
1642
+ } ;
1643
+
1644
+ /// <summary>
1645
+ /// XamlReader.Load the xaml and type-check result.
1646
+ /// </summary>
1647
+ /// <param name="xaml">Xaml with single or double quotes</param>
1648
+ /// <param name="autoInjectXmlns">Toggle automatic detection of xmlns required and inject to the xaml</param>
1649
+ public static T LoadXaml < T > ( string xaml , bool autoInjectXmlns = true ) where T : class
1650
+ {
1651
+ var xmlnses = new Dictionary < string , string > ( ) ;
1652
+
1653
+ if ( autoInjectXmlns )
1654
+ {
1655
+ foreach ( var xmlns in KnownXmlnses )
1656
+ {
1657
+ var match = xmlns . Key == string . Empty
1658
+ ? NonXmlnsTagRegex . IsMatch ( xaml )
1659
+ : xaml . Contains ( $ "<{ xmlns . Key } :") ;
1660
+ if ( match )
1661
+ {
1662
+ xmlnses . Add ( xmlns . Key , xmlns . Value ) ;
1663
+ }
1664
+ }
1665
+ }
1666
+
1667
+ return LoadXaml < T > ( xaml , xmlnses ) ;
1668
+ }
1669
+
1670
+ /// <summary>
1671
+ /// XamlReader.Load the xaml and type-check result.
1672
+ /// </summary>
1673
+ /// <param name="xaml">Xaml with single or double quotes</param>
1674
+ /// <param name="xmlnses">Xmlns to inject; use string.Empty for the default xmlns' key</param>
1675
+ public static T LoadXaml < T > ( string xaml , Dictionary < string , string > xmlnses ) where T : class
1676
+ {
1677
+ var injection = " " + string . Join ( " " , xmlnses
1678
+ . Select ( x => $ "xmlns{ ( string . IsNullOrEmpty ( x . Key ) ? "" : $ ":{ x . Key } ") } =\" { x . Value } \" ")
1679
+ ) ;
1680
+
1681
+ xaml = EndOfTagRegex . Replace ( xaml , injection . TrimEnd ( ) , 1 ) ;
1682
+
1683
+ var result = Windows . UI . Xaml . Markup . XamlReader . Load ( xaml ) ;
1684
+ Assert . IsNotNull ( result , "XamlReader.Load returned null" ) ;
1685
+ Assert . IsInstanceOfType ( result , typeof ( T ) , "XamlReader.Load did not return the expected type" ) ;
1686
+
1687
+ return ( T ) result ;
1688
+ }
1689
+ }
1640
1690
}
1641
1691
}
0 commit comments