ExpressionObserverTests_SetValue.cs 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111
  1. using System;
  2. using System.Reactive.Linq;
  3. using System.Reactive.Subjects;
  4. using Avalonia.Data.Core;
  5. using Avalonia.Markup.Parsers;
  6. using Avalonia.UnitTests;
  7. using Xunit;
  8. namespace Avalonia.Base.UnitTests.Data.Core
  9. {
  10. public class ExpressionObserverTests_SetValue
  11. {
  12. [Fact]
  13. public void Should_Set_Simple_Property_Value()
  14. {
  15. var data = new { Foo = "foo" };
  16. var target = ExpressionObserver.Create(data, o => o.Foo);
  17. using (target.Subscribe(_ => { }))
  18. {
  19. target.SetValue("bar");
  20. }
  21. Assert.Equal("foo", data.Foo);
  22. }
  23. [Fact]
  24. public void Should_Set_Value_On_Simple_Property_Chain()
  25. {
  26. var data = new Class1 { Foo = new Class2 { Bar = "bar" } };
  27. var target = ExpressionObserver.Create(data, o => o.Foo.Bar);
  28. using (target.Subscribe(_ => { }))
  29. {
  30. target.SetValue("foo");
  31. }
  32. Assert.Equal("foo", data.Foo.Bar);
  33. }
  34. [Fact]
  35. public void Should_Not_Try_To_Set_Value_On_Broken_Chain()
  36. {
  37. var data = new Class1 { Foo = new Class2 { Bar = "bar" } };
  38. var target = ExpressionObserver.Create(data, o => o.Foo.Bar);
  39. // Ensure the ExpressionObserver's subscriptions are kept active.
  40. using (target.OfType<string>().Subscribe(x => { }))
  41. {
  42. data.Foo = null;
  43. Assert.False(target.SetValue("foo"));
  44. }
  45. }
  46. /// <summary>
  47. /// Test for #831 - Bound properties are incorrectly updated when changing tab items.
  48. /// </summary>
  49. /// <remarks>
  50. /// There was a bug whereby pushing a null as the ExpressionObserver root didn't update
  51. /// the leaf node, cauing a subsequent SetValue to update an object that should have become
  52. /// unbound.
  53. /// </remarks>
  54. [Fact]
  55. public void Pushing_Null_To_RootObservable_Updates_Leaf_Node()
  56. {
  57. var data = new Class1 { Foo = new Class2 { Bar = "bar" } };
  58. var rootObservable = new BehaviorSubject<Class1>(data);
  59. var target = ExpressionObserver.Create(rootObservable, o => o.Foo.Bar);
  60. using (target.Subscribe(_ => { }))
  61. {
  62. rootObservable.OnNext(null);
  63. target.SetValue("baz");
  64. Assert.Equal("bar", data.Foo.Bar);
  65. }
  66. }
  67. private class Class1 : NotifyingBase
  68. {
  69. private Class2 _foo;
  70. public Class2 Foo
  71. {
  72. get { return _foo; }
  73. set
  74. {
  75. _foo = value;
  76. RaisePropertyChanged(nameof(Foo));
  77. }
  78. }
  79. }
  80. private class Class2 : NotifyingBase
  81. {
  82. private string _bar;
  83. public string Bar
  84. {
  85. get { return _bar; }
  86. set
  87. {
  88. _bar = value;
  89. RaisePropertyChanged(nameof(Bar));
  90. }
  91. }
  92. }
  93. }
  94. }