AvaloniaObjectTests_SetCurrentValue.cs 16 KB

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