Browse Source

Disallow selectors with trailing /template/.

It's an invalid selector: what does `Button /template/` select?
Steven Kirk 3 years ago
parent
commit
002377044a

+ 15 - 1
src/Avalonia.Base/Styling/Style.cs

@@ -7,6 +7,8 @@ namespace Avalonia.Styling
     /// </summary>
     public class Style : StyleBase
     {
+        private Selector? _selector;
+
         /// <summary>
         /// Initializes a new instance of the <see cref="Style"/> class.
         /// </summary>
@@ -26,7 +28,11 @@ namespace Avalonia.Styling
         /// <summary>
         /// Gets or sets the style's selector.
         /// </summary>
-        public Selector? Selector { get; set; }
+        public Selector? Selector 
+        {
+            get => _selector;
+            set => _selector = ValidateSelector(value);
+        }
 
         public override SelectorMatchResult TryAttach(IStyleable target, object? host)
         {
@@ -88,5 +94,13 @@ namespace Avalonia.Styling
 
             base.SetParent(parent);
         }
+
+        private static Selector? ValidateSelector(Selector? selector)
+        {
+            if (selector is TemplateSelector)
+                throw new InvalidOperationException(
+                    "Invalid selector: Template selector must be followed by control selector.");
+            return selector;
+        }
     }
 }

+ 0 - 72
tests/Avalonia.Base.UnitTests/Styling/SelectorTests_Nesting.cs

@@ -150,78 +150,6 @@ namespace Avalonia.Base.UnitTests.Styling
             Assert.False(sink.Active);
         }
 
-        [Fact(Skip = "Template selectors a the end of nesting parent selectors currently broken")]
-        public void Template_Nesting_OfType_Matches()
-        {
-            var control = new Control1 { Classes = { "foo" } };
-            var button = new Button
-            {
-                Template = new FuncControlTemplate((x, _) => control),
-            };
-
-            button.ApplyTemplate();
-
-            Style nested;
-            var parent = new Style(x => x.OfType<Button>().Template())
-            {
-                Children =
-                {
-                    (nested = new Style(x => x.Nesting().OfType<Control1>())),
-                }
-            };
-
-            var match = nested.Selector.Match(control, parent);
-            Assert.Equal(SelectorMatchResult.AlwaysThisInstance, match.Result);
-        }
-
-        [Fact]
-        public void Template_Nesting_OfType_Class_Matches()
-        {
-            var control = new Control1 { Classes = { "foo" } };
-            var button = new Button
-            {
-                Template = new FuncControlTemplate((x, _) => control),
-            };
-
-            button.ApplyTemplate();
-
-            Style nested;
-            var parent = new Style(x => x.OfType<Button>().Template())
-            {
-                Children =
-                {
-                    (nested = new Style(x => x.Nesting().OfType<Control1>().Class("foo"))),
-                }
-            };
-
-            var match = nested.Selector.Match(control, parent);
-            Assert.Equal(SelectorMatchResult.Sometimes, match.Result);
-        }
-
-        [Fact(Skip = "Template selectors a the end of nesting parent selectors currently broken")]
-        public void Class_Template_Nesting_OfType_Matches()
-        {
-            var control = new Control1 { Classes = { "foo" } };
-            var button = new Button
-            {
-                Template = new FuncControlTemplate((x, _) => control),
-            };
-
-            button.ApplyTemplate();
-
-            Style nested;
-            var parent = new Style(x => x.OfType<Button>().Class("bar").Template())
-            {
-                Children =
-                {
-                    (nested = new Style(x => x.Nesting().OfType<Control1>())),
-                }
-            };
-
-            var match = nested.Selector.Match(control, parent);
-            Assert.Equal(SelectorMatchResult.Sometimes, match.Result);
-        }
-
         [Fact]
         public void Or_Nesting_Class_Matches()
         {

+ 7 - 0
tests/Avalonia.Base.UnitTests/Styling/StyleTests.cs

@@ -69,6 +69,13 @@ namespace Avalonia.Base.UnitTests.Styling
             Assert.Equal("Foo", target.Foo);
         }
 
+        [Fact]
+        public void Should_Throw_For_Selector_With_Trailing_Template_Selector()
+        {
+            Assert.Throws<InvalidOperationException>(() =>
+                new Style(x => x.OfType<Button>().Template()));
+        }
+
         [Fact]
         public void Style_With_No_Selector_Should_Not_Apply_To_Other_Control()
         {