AvaloniaObjectTests_SetCurrentValue.cs 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428
  1. using System;
  2. using Avalonia.Controls;
  3. using Avalonia.Data;
  4. using Avalonia.Diagnostics;
  5. using Avalonia.Styling;
  6. using Avalonia.UnitTests;
  7. using Xunit;
  8. using Observable = Avalonia.Reactive.Observable;
  9. namespace Avalonia.Base.UnitTests
  10. {
  11. public class AvaloniaObjectTests_SetCurrentValue
  12. {
  13. [Fact]
  14. public void SetCurrentValue_Sets_Unset_Value()
  15. {
  16. var target = new Class1();
  17. target.SetCurrentValue(Class1.FooProperty, "newvalue");
  18. Assert.Equal("newvalue", target.GetValue(Class1.FooProperty));
  19. Assert.True(target.IsSet(Class1.FooProperty));
  20. Assert.Equal(BindingPriority.Unset, GetPriority(target, Class1.FooProperty));
  21. Assert.True(IsOverridden(target, Class1.FooProperty));
  22. }
  23. [Fact]
  24. public void SetCurrentValue_Sets_Unset_Value_Untyped()
  25. {
  26. var target = new Class1();
  27. target.SetCurrentValue((AvaloniaProperty)Class1.FooProperty, "newvalue");
  28. Assert.Equal("newvalue", target.GetValue(Class1.FooProperty));
  29. Assert.True(target.IsSet(Class1.FooProperty));
  30. Assert.Equal(BindingPriority.Unset, GetPriority(target, Class1.FooProperty));
  31. Assert.True(IsOverridden(target, Class1.FooProperty));
  32. }
  33. [Theory]
  34. [InlineData(BindingPriority.LocalValue)]
  35. [InlineData(BindingPriority.Style)]
  36. [InlineData(BindingPriority.Animation)]
  37. public void SetCurrentValue_Overrides_Existing_Value(BindingPriority priority)
  38. {
  39. var target = new Class1();
  40. target.SetValue(Class1.FooProperty, "oldvalue", priority);
  41. target.SetCurrentValue(Class1.FooProperty, "newvalue");
  42. Assert.Equal("newvalue", target.GetValue(Class1.FooProperty));
  43. Assert.True(target.IsSet(Class1.FooProperty));
  44. Assert.Equal(priority, GetPriority(target, Class1.FooProperty));
  45. Assert.True(IsOverridden(target, Class1.FooProperty));
  46. }
  47. [Fact]
  48. public void SetCurrentValue_Overrides_Inherited_Value()
  49. {
  50. var parent = new Class1();
  51. var target = new Class1 { InheritanceParent = parent };
  52. parent.SetValue(Class1.InheritedProperty, "inheritedvalue");
  53. target.SetCurrentValue(Class1.InheritedProperty, "newvalue");
  54. Assert.Equal("newvalue", target.GetValue(Class1.InheritedProperty));
  55. Assert.True(target.IsSet(Class1.InheritedProperty));
  56. Assert.Equal(BindingPriority.Unset, GetPriority(target, Class1.InheritedProperty));
  57. Assert.True(IsOverridden(target, Class1.InheritedProperty));
  58. }
  59. [Fact]
  60. public void SetCurrentValue_Is_Inherited()
  61. {
  62. var parent = new Class1();
  63. var target = new Class1 { InheritanceParent = parent };
  64. parent.SetCurrentValue(Class1.InheritedProperty, "newvalue");
  65. Assert.Equal("newvalue", target.GetValue(Class1.InheritedProperty));
  66. Assert.False(target.IsSet(Class1.FooProperty));
  67. Assert.Equal(BindingPriority.Inherited, GetPriority(target, Class1.InheritedProperty));
  68. Assert.False(IsOverridden(target, Class1.InheritedProperty));
  69. }
  70. [Fact]
  71. public void ClearValue_Clears_CurrentValue_With_Unset_Priority()
  72. {
  73. var target = new Class1();
  74. target.SetCurrentValue(Class1.FooProperty, "newvalue");
  75. target.ClearValue(Class1.FooProperty);
  76. Assert.Equal("foodefault", target.Foo);
  77. Assert.False(target.IsSet(Class1.FooProperty));
  78. Assert.False(IsOverridden(target, Class1.FooProperty));
  79. }
  80. [Fact]
  81. public void ClearValue_Clears_CurrentValue_With_Inherited_Priority()
  82. {
  83. var parent = new Class1();
  84. var target = new Class1 { InheritanceParent = parent };
  85. parent.SetValue(Class1.InheritedProperty, "inheritedvalue");
  86. target.SetCurrentValue(Class1.InheritedProperty, "newvalue");
  87. target.ClearValue(Class1.InheritedProperty);
  88. Assert.Equal("inheritedvalue", target.Inherited);
  89. Assert.False(target.IsSet(Class1.FooProperty));
  90. Assert.False(IsOverridden(target, Class1.FooProperty));
  91. }
  92. [Fact]
  93. public void ClearValue_Clears_CurrentValue_With_LocalValue_Priority()
  94. {
  95. var target = new Class1();
  96. target.SetValue(Class1.FooProperty, "localvalue");
  97. target.SetCurrentValue(Class1.FooProperty, "newvalue");
  98. target.ClearValue(Class1.FooProperty);
  99. Assert.Equal("foodefault", target.Foo);
  100. Assert.False(target.IsSet(Class1.FooProperty));
  101. Assert.False(IsOverridden(target, Class1.FooProperty));
  102. }
  103. [Fact]
  104. public void ClearValue_Clears_CurrentValue_With_Style_Priority()
  105. {
  106. var target = new Class1();
  107. target.SetValue(Class1.FooProperty, "stylevalue", BindingPriority.Style);
  108. target.SetCurrentValue(Class1.FooProperty, "newvalue");
  109. target.ClearValue(Class1.FooProperty);
  110. Assert.Equal("stylevalue", target.Foo);
  111. Assert.True(target.IsSet(Class1.FooProperty));
  112. Assert.False(IsOverridden(target, Class1.FooProperty));
  113. }
  114. [Fact]
  115. public void SetCurrentValue_Can_Be_Coerced()
  116. {
  117. var target = new Class1();
  118. target.SetCurrentValue(Class1.CoercedProperty, 60);
  119. Assert.Equal(60, target.GetValue(Class1.CoercedProperty));
  120. target.CoerceMax = 50;
  121. target.CoerceValue(Class1.CoercedProperty);
  122. Assert.Equal(50, target.GetValue(Class1.CoercedProperty));
  123. target.CoerceMax = 100;
  124. target.CoerceValue(Class1.CoercedProperty);
  125. Assert.Equal(60, target.GetValue(Class1.CoercedProperty));
  126. }
  127. [Fact]
  128. public void SetCurrentValue_Unset_Clears_CurrentValue()
  129. {
  130. var target = new Class1();
  131. target.SetCurrentValue(Class1.FooProperty, "newvalue");
  132. target.SetCurrentValue(Class1.FooProperty, AvaloniaProperty.UnsetValue);
  133. Assert.Equal("foodefault", target.Foo);
  134. Assert.False(target.IsSet(Class1.FooProperty));
  135. Assert.False(IsOverridden(target, Class1.FooProperty));
  136. }
  137. [Theory]
  138. [InlineData(BindingPriority.LocalValue)]
  139. [InlineData(BindingPriority.Style)]
  140. [InlineData(BindingPriority.Animation)]
  141. public void SetValue_Overrides_CurrentValue_With_Unset_Priority(BindingPriority priority)
  142. {
  143. var target = new Class1();
  144. target.SetCurrentValue(Class1.FooProperty, "current");
  145. target.SetValue(Class1.FooProperty, "setvalue", priority);
  146. Assert.Equal("setvalue", target.Foo);
  147. Assert.True(target.IsSet(Class1.FooProperty));
  148. Assert.Equal(priority, GetPriority(target, Class1.FooProperty));
  149. Assert.False(IsOverridden(target, Class1.FooProperty));
  150. }
  151. [Fact]
  152. public void Animation_Value_Overrides_CurrentValue_With_LocalValue_Priority()
  153. {
  154. var target = new Class1();
  155. target.SetValue(Class1.FooProperty, "localvalue");
  156. target.SetCurrentValue(Class1.FooProperty, "current");
  157. target.SetValue(Class1.FooProperty, "setvalue", BindingPriority.Animation);
  158. Assert.Equal("setvalue", target.Foo);
  159. Assert.True(target.IsSet(Class1.FooProperty));
  160. Assert.Equal(BindingPriority.Animation, GetPriority(target, Class1.FooProperty));
  161. Assert.False(IsOverridden(target, Class1.FooProperty));
  162. }
  163. [Fact]
  164. public void StyleTrigger_Value_Overrides_CurrentValue_With_Style_Priority()
  165. {
  166. var target = new Class1();
  167. target.SetValue(Class1.FooProperty, "style", BindingPriority.Style);
  168. target.SetCurrentValue(Class1.FooProperty, "current");
  169. target.SetValue(Class1.FooProperty, "setvalue", BindingPriority.StyleTrigger);
  170. Assert.Equal("setvalue", target.Foo);
  171. Assert.True(target.IsSet(Class1.FooProperty));
  172. Assert.Equal(BindingPriority.StyleTrigger, GetPriority(target, Class1.FooProperty));
  173. Assert.False(IsOverridden(target, Class1.FooProperty));
  174. }
  175. [Theory]
  176. [InlineData(BindingPriority.LocalValue)]
  177. [InlineData(BindingPriority.Style)]
  178. [InlineData(BindingPriority.Animation)]
  179. public void Binding_Overrides_CurrentValue_With_Unset_Priority(BindingPriority priority)
  180. {
  181. var target = new Class1();
  182. target.SetCurrentValue(Class1.FooProperty, "current");
  183. var s = target.Bind(Class1.FooProperty, Observable.SingleValue("binding"), priority);
  184. Assert.Equal("binding", target.Foo);
  185. Assert.True(target.IsSet(Class1.FooProperty));
  186. Assert.Equal(priority, GetPriority(target, Class1.FooProperty));
  187. Assert.False(IsOverridden(target, Class1.FooProperty));
  188. s.Dispose();
  189. Assert.Equal("foodefault", target.Foo);
  190. }
  191. [Fact]
  192. public void Animation_Binding_Overrides_CurrentValue_With_LocalValue_Priority()
  193. {
  194. var target = new Class1();
  195. target.SetValue(Class1.FooProperty, "localvalue");
  196. target.SetCurrentValue(Class1.FooProperty, "current");
  197. var s = target.Bind(Class1.FooProperty, Observable.SingleValue("binding"), BindingPriority.Animation);
  198. Assert.Equal("binding", target.Foo);
  199. Assert.True(target.IsSet(Class1.FooProperty));
  200. Assert.Equal(BindingPriority.Animation, GetPriority(target, Class1.FooProperty));
  201. Assert.False(IsOverridden(target, Class1.FooProperty));
  202. s.Dispose();
  203. Assert.Equal("current", target.Foo);
  204. }
  205. [Fact]
  206. public void StyleTrigger_Binding_Overrides_CurrentValue_With_Style_Priority()
  207. {
  208. var target = new Class1();
  209. target.SetValue(Class1.FooProperty, "style", BindingPriority.Style);
  210. target.SetCurrentValue(Class1.FooProperty, "current");
  211. var s = target.Bind(Class1.FooProperty, Observable.SingleValue("binding"), BindingPriority.StyleTrigger);
  212. Assert.Equal("binding", target.Foo);
  213. Assert.True(target.IsSet(Class1.FooProperty));
  214. Assert.Equal(BindingPriority.StyleTrigger, GetPriority(target, Class1.FooProperty));
  215. Assert.False(IsOverridden(target, Class1.FooProperty));
  216. s.Dispose();
  217. Assert.Equal("style", target.Foo);
  218. }
  219. [Fact]
  220. public void SetCurrent_Value_Persists_When_Toggling_Style_1()
  221. {
  222. var target = new Class1();
  223. var root = new TestRoot(target)
  224. {
  225. Styles =
  226. {
  227. new Style(x => x.OfType<Class1>().Class("foo"))
  228. {
  229. Setters = { new Setter(Class1.BarProperty, "bar") },
  230. }
  231. }
  232. };
  233. root.LayoutManager.ExecuteInitialLayoutPass();
  234. target.SetCurrentValue(Class1.FooProperty, "current");
  235. Assert.Equal("current", target.Foo);
  236. Assert.Equal("bardefault", target.Bar);
  237. target.Classes.Add("foo");
  238. Assert.Equal("current", target.Foo);
  239. Assert.Equal("bar", target.Bar);
  240. target.Classes.Remove("foo");
  241. Assert.Equal("current", target.Foo);
  242. Assert.Equal("bardefault", target.Bar);
  243. }
  244. [Fact]
  245. public void SetCurrent_Value_Persists_When_Toggling_Style_2()
  246. {
  247. var target = new Class1();
  248. var root = new TestRoot(target)
  249. {
  250. Styles =
  251. {
  252. new Style(x => x.OfType<Class1>().Class("foo"))
  253. {
  254. Setters =
  255. {
  256. new Setter(Class1.BarProperty, "bar"),
  257. new Setter(Class1.InheritedProperty, "inherited"),
  258. },
  259. }
  260. }
  261. };
  262. root.LayoutManager.ExecuteInitialLayoutPass();
  263. target.SetCurrentValue(Class1.FooProperty, "current");
  264. Assert.Equal("current", target.Foo);
  265. Assert.Equal("bardefault", target.Bar);
  266. Assert.Equal("inheriteddefault", target.Inherited);
  267. target.Classes.Add("foo");
  268. Assert.Equal("current", target.Foo);
  269. Assert.Equal("bar", target.Bar);
  270. Assert.Equal("inherited", target.Inherited);
  271. target.Classes.Remove("foo");
  272. Assert.Equal("current", target.Foo);
  273. Assert.Equal("bardefault", target.Bar);
  274. Assert.Equal("inheriteddefault", target.Inherited);
  275. }
  276. [Fact]
  277. public void SetCurrent_Value_Persists_When_Toggling_Style_3()
  278. {
  279. var target = new Class1();
  280. var root = new TestRoot(target)
  281. {
  282. Styles =
  283. {
  284. new Style(x => x.OfType<Class1>().Class("foo"))
  285. {
  286. Setters =
  287. {
  288. new Setter(Class1.BarProperty, "bar"),
  289. new Setter(Class1.InheritedProperty, "inherited"),
  290. },
  291. }
  292. }
  293. };
  294. root.LayoutManager.ExecuteInitialLayoutPass();
  295. target.SetValue(Class1.FooProperty, "not current", BindingPriority.Template);
  296. target.SetCurrentValue(Class1.FooProperty, "current");
  297. Assert.Equal("current", target.Foo);
  298. Assert.Equal("bardefault", target.Bar);
  299. Assert.Equal("inheriteddefault", target.Inherited);
  300. target.Classes.Add("foo");
  301. Assert.Equal("current", target.Foo);
  302. Assert.Equal("bar", target.Bar);
  303. Assert.Equal("inherited", target.Inherited);
  304. target.Classes.Remove("foo");
  305. Assert.Equal("current", target.Foo);
  306. Assert.Equal("bardefault", target.Bar);
  307. Assert.Equal("inheriteddefault", target.Inherited);
  308. }
  309. private BindingPriority GetPriority(AvaloniaObject target, AvaloniaProperty property)
  310. {
  311. return target.GetDiagnostic(property).Priority;
  312. }
  313. private bool IsOverridden(AvaloniaObject target, AvaloniaProperty property)
  314. {
  315. return target.GetDiagnostic(property).IsOverriddenCurrentValue;
  316. }
  317. private class Class1 : Control
  318. {
  319. public static readonly StyledProperty<string> FooProperty =
  320. AvaloniaProperty.Register<Class1, string>(nameof(Foo), "foodefault");
  321. public static readonly StyledProperty<string> BarProperty =
  322. AvaloniaProperty.Register<Class1, string>(nameof(Bar), "bardefault");
  323. public static readonly StyledProperty<string> InheritedProperty =
  324. AvaloniaProperty.Register<Class1, string>(nameof(Inherited), "inheriteddefault", inherits: true);
  325. public static readonly StyledProperty<double> CoercedProperty =
  326. AvaloniaProperty.Register<Class1, double>(nameof(Coerced), coerce: Coerce);
  327. public string Foo => GetValue(FooProperty);
  328. public string Bar => GetValue(BarProperty);
  329. public string Inherited => GetValue(InheritedProperty);
  330. public double Coerced => GetValue(CoercedProperty);
  331. public double CoerceMax { get; set; } = 100;
  332. private static double Coerce(AvaloniaObject sender, double value)
  333. {
  334. return Math.Min(value, ((Class1)sender).CoerceMax);
  335. }
  336. }
  337. }
  338. }