| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306 |
- // Copyright (c) The Avalonia Project. All rights reserved.
- // Licensed under the MIT license. See licence.md file in the project root for full license information.
- using System;
- using System.Linq;
- using System.Reactive.Linq;
- using System.Reactive.Subjects;
- using Moq;
- using Xunit;
- namespace Avalonia.Base.UnitTests
- {
- public class PriorityValueTests
- {
- private static readonly AvaloniaProperty TestProperty =
- new StyledProperty<string>(
- "Test",
- typeof(PriorityValueTests),
- new StyledPropertyMetadata<string>());
- [Fact]
- public void Initial_Value_Should_Be_UnsetValue()
- {
- var target = new PriorityValue(null, TestProperty, typeof(string));
- Assert.Same(AvaloniaProperty.UnsetValue, target.Value);
- }
- [Fact]
- public void First_Binding_Sets_Value()
- {
- var target = new PriorityValue(null, TestProperty, typeof(string));
- target.Add(Single("foo"), 0);
- Assert.Equal("foo", target.Value);
- }
- [Fact]
- public void Changing_Binding_Should_Set_Value()
- {
- var target = new PriorityValue(null, TestProperty, typeof(string));
- var subject = new BehaviorSubject<string>("foo");
- target.Add(subject, 0);
- Assert.Equal("foo", target.Value);
- subject.OnNext("bar");
- Assert.Equal("bar", target.Value);
- }
- [Fact]
- public void Setting_Direct_Value_Should_Override_Binding()
- {
- var target = new PriorityValue(null, TestProperty, typeof(string));
- target.Add(Single("foo"), 0);
- target.SetValue("bar", 0);
- Assert.Equal("bar", target.Value);
- }
- [Fact]
- public void Binding_Firing_Should_Override_Direct_Value()
- {
- var target = new PriorityValue(null, TestProperty, typeof(string));
- var source = new BehaviorSubject<object>("initial");
- target.Add(source, 0);
- Assert.Equal("initial", target.Value);
- target.SetValue("first", 0);
- Assert.Equal("first", target.Value);
- source.OnNext("second");
- Assert.Equal("second", target.Value);
- }
- [Fact]
- public void Earlier_Binding_Firing_Should_Not_Override_Later()
- {
- var target = new PriorityValue(null, TestProperty, typeof(string));
- var nonActive = new BehaviorSubject<object>("na");
- var source = new BehaviorSubject<object>("initial");
- target.Add(nonActive, 1);
- target.Add(source, 1);
- Assert.Equal("initial", target.Value);
- target.SetValue("first", 1);
- Assert.Equal("first", target.Value);
- nonActive.OnNext("second");
- Assert.Equal("first", target.Value);
- }
- [Fact]
- public void Binding_Completing_Should_Revert_To_Direct_Value()
- {
- var target = new PriorityValue(null, TestProperty, typeof(string));
- var source = new BehaviorSubject<object>("initial");
- target.Add(source, 0);
- Assert.Equal("initial", target.Value);
- target.SetValue("first", 0);
- Assert.Equal("first", target.Value);
- source.OnNext("second");
- Assert.Equal("second", target.Value);
- source.OnCompleted();
- Assert.Equal("first", target.Value);
- }
- [Fact]
- public void Binding_With_Lower_Priority_Has_Precedence()
- {
- var target = new PriorityValue(null, TestProperty, typeof(string));
- target.Add(Single("foo"), 1);
- target.Add(Single("bar"), 0);
- target.Add(Single("baz"), 1);
- Assert.Equal("bar", target.Value);
- }
- [Fact]
- public void Later_Binding_With_Same_Priority_Should_Take_Precedence()
- {
- var target = new PriorityValue(null, TestProperty, typeof(string));
- target.Add(Single("foo"), 1);
- target.Add(Single("bar"), 0);
- target.Add(Single("baz"), 0);
- target.Add(Single("qux"), 1);
- Assert.Equal("baz", target.Value);
- }
- [Fact]
- public void Changing_Binding_With_Lower_Priority_Should_Set_Not_Value()
- {
- var target = new PriorityValue(null, TestProperty, typeof(string));
- var subject = new BehaviorSubject<string>("bar");
- target.Add(Single("foo"), 0);
- target.Add(subject, 1);
- Assert.Equal("foo", target.Value);
- subject.OnNext("baz");
- Assert.Equal("foo", target.Value);
- }
- [Fact]
- public void UnsetValue_Should_Fall_Back_To_Next_Binding()
- {
- var target = new PriorityValue(null, TestProperty, typeof(string));
- var subject = new BehaviorSubject<object>("bar");
- target.Add(subject, 0);
- target.Add(Single("foo"), 1);
- Assert.Equal("bar", target.Value);
- subject.OnNext(AvaloniaProperty.UnsetValue);
- Assert.Equal("foo", target.Value);
- }
- [Fact]
- public void Adding_Value_Should_Call_OnNext()
- {
- var owner = new Mock<IPriorityValueOwner>();
- var target = new PriorityValue(owner.Object, TestProperty, typeof(string));
- target.Add(Single("foo"), 0);
- owner.Verify(x => x.Changed(target.Property, target.ValuePriority, AvaloniaProperty.UnsetValue, "foo"));
- }
- [Fact]
- public void Changing_Value_Should_Call_OnNext()
- {
- var owner = new Mock<IPriorityValueOwner>();
- var target = new PriorityValue(owner.Object, TestProperty, typeof(string));
- var subject = new BehaviorSubject<object>("foo");
- target.Add(subject, 0);
- subject.OnNext("bar");
- owner.Verify(x => x.Changed(target.Property, target.ValuePriority, "foo", "bar"));
- }
- [Fact]
- public void Disposing_A_Binding_Should_Revert_To_Next_Value()
- {
- var target = new PriorityValue(null, TestProperty, typeof(string));
- target.Add(Single("foo"), 0);
- var disposable = target.Add(Single("bar"), 0);
- Assert.Equal("bar", target.Value);
- disposable.Dispose();
- Assert.Equal("foo", target.Value);
- }
- [Fact]
- public void Disposing_A_Binding_Should_Remove_BindingEntry()
- {
- var target = new PriorityValue(null, TestProperty, typeof(string));
- target.Add(Single("foo"), 0);
- var disposable = target.Add(Single("bar"), 0);
- Assert.Equal(2, target.GetBindings().Count());
- disposable.Dispose();
- Assert.Single(target.GetBindings());
- }
- [Fact]
- public void Completing_A_Binding_Should_Revert_To_Previous_Binding()
- {
- var target = new PriorityValue(null, TestProperty, typeof(string));
- var source = new BehaviorSubject<object>("bar");
- target.Add(Single("foo"), 0);
- target.Add(source, 0);
- Assert.Equal("bar", target.Value);
- source.OnCompleted();
- Assert.Equal("foo", target.Value);
- }
- [Fact]
- public void Completing_A_Binding_Should_Revert_To_Lower_Priority()
- {
- var target = new PriorityValue(null, TestProperty, typeof(string));
- var source = new BehaviorSubject<object>("bar");
- target.Add(Single("foo"), 1);
- target.Add(source, 0);
- Assert.Equal("bar", target.Value);
- source.OnCompleted();
- Assert.Equal("foo", target.Value);
- }
- [Fact]
- public void Completing_A_Binding_Should_Remove_BindingEntry()
- {
- var target = new PriorityValue(null, TestProperty, typeof(string));
- var subject = new BehaviorSubject<object>("bar");
- target.Add(Single("foo"), 0);
- target.Add(subject, 0);
- Assert.Equal(2, target.GetBindings().Count());
- subject.OnCompleted();
- Assert.Single(target.GetBindings());
- }
- [Fact]
- public void Direct_Value_Should_Be_Coerced()
- {
- var target = new PriorityValue(null, TestProperty, typeof(int), x => Math.Min((int)x, 10));
- target.SetValue(5, 0);
- Assert.Equal(5, target.Value);
- target.SetValue(15, 0);
- Assert.Equal(10, target.Value);
- }
- [Fact]
- public void Bound_Value_Should_Be_Coerced()
- {
- var target = new PriorityValue(null, TestProperty, typeof(int), x => Math.Min((int)x, 10));
- var source = new Subject<object>();
- target.Add(source, 0);
- source.OnNext(5);
- Assert.Equal(5, target.Value);
- source.OnNext(15);
- Assert.Equal(10, target.Value);
- }
- [Fact]
- public void Revalidate_Should_ReCoerce_Value()
- {
- var max = 10;
- var target = new PriorityValue(null, TestProperty, typeof(int), x => Math.Min((int)x, max));
- var source = new Subject<object>();
- target.Add(source, 0);
- source.OnNext(5);
- Assert.Equal(5, target.Value);
- source.OnNext(15);
- Assert.Equal(10, target.Value);
- max = 12;
- target.Revalidate();
- Assert.Equal(12, target.Value);
- }
- /// <summary>
- /// Returns an observable that returns a single value but does not complete.
- /// </summary>
- /// <typeparam name="T">The type of the observable.</typeparam>
- /// <param name="value">The value.</param>
- /// <returns>The observable.</returns>
- private IObservable<T> Single<T>(T value)
- {
- return Observable.Never<T>().StartWith(value);
- }
- }
- }
|