9 changed files with 254 additions and 65 deletions
@ -0,0 +1,68 @@ |
|||
// -----------------------------------------------------------------------
|
|||
// <copyright file="SelectorTests.cs" company="Steven Kirk">
|
|||
// Copyright 2014 MIT Licence. See licence.md for more information.
|
|||
// </copyright>
|
|||
// -----------------------------------------------------------------------
|
|||
|
|||
namespace Perspex.UnitTests.Styling |
|||
{ |
|||
using System; |
|||
using System.Linq; |
|||
using System.Reactive; |
|||
using System.Reactive.Linq; |
|||
using Microsoft.VisualStudio.TestTools.UnitTesting; |
|||
using Perspex.Styling; |
|||
using Match = Perspex.Styling.Match; |
|||
|
|||
[TestClass] |
|||
public class SelectorTests |
|||
{ |
|||
[TestMethod] |
|||
public void OfType_Matches_Control_Of_Correct_Type() |
|||
{ |
|||
var control = new Class1(); |
|||
var target = control.Select().OfType<Class1>(); |
|||
|
|||
CollectionAssert.AreEqual(new[] { true }, target.GetActivator().Take(1).ToEnumerable().ToArray()); |
|||
} |
|||
|
|||
[TestMethod] |
|||
public void OfType_Doesnt_Match_Control_Of_Wrong_Type() |
|||
{ |
|||
var control = new Class2(); |
|||
var target = control.Select().OfType<Class1>(); |
|||
|
|||
CollectionAssert.AreEqual(new[] { false }, target.GetActivator().Take(1).ToEnumerable().ToArray()); |
|||
} |
|||
|
|||
[TestMethod] |
|||
public void When_OfType_Matches_Control_Other_Selectors_Are_Subscribed() |
|||
{ |
|||
var control = new Class1(); |
|||
var target = control.Select().OfType<Class1>().SubscribeCheck(); |
|||
|
|||
var result = target.GetActivator().ToEnumerable().Take(1).ToArray(); |
|||
|
|||
Assert.AreEqual(1, control.SubscribeCheckObservable.SubscribedCount); |
|||
} |
|||
|
|||
[TestMethod] |
|||
public void When_OfType_Doesnt_Match_Control_Other_Selectors_Are_Not_Subscribed() |
|||
{ |
|||
var control = new Class1(); |
|||
var target = control.Select().OfType<Class2>().SubscribeCheck(); |
|||
|
|||
var result = target.GetActivator().ToEnumerable().Take(1).ToArray(); |
|||
|
|||
Assert.AreEqual(0, control.SubscribeCheckObservable.SubscribedCount); |
|||
} |
|||
|
|||
public class Class1 : SubscribeCheck |
|||
{ |
|||
} |
|||
|
|||
public class Class2 : SubscribeCheck |
|||
{ |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,59 @@ |
|||
// -----------------------------------------------------------------------
|
|||
// <copyright file="SubscribeCheck.cs" company="Steven Kirk">
|
|||
// Copyright 2014 MIT Licence. See licence.md for more information.
|
|||
// </copyright>
|
|||
// -----------------------------------------------------------------------
|
|||
|
|||
namespace Perspex.UnitTests.Styling |
|||
{ |
|||
using System; |
|||
using System.Reactive.Disposables; |
|||
using Perspex.Styling; |
|||
using Match = Perspex.Styling.Match; |
|||
|
|||
public class TestObservable : IObservable<bool> |
|||
{ |
|||
public int SubscribedCount { get; private set; } |
|||
|
|||
public IDisposable Subscribe(IObserver<bool> observer) |
|||
{ |
|||
++this.SubscribedCount; |
|||
observer.OnNext(true); |
|||
return Disposable.Create(() => --this.SubscribedCount); |
|||
} |
|||
} |
|||
|
|||
public class SubscribeCheck : IStyleable |
|||
{ |
|||
public SubscribeCheck() |
|||
{ |
|||
this.Classes = new PerspexList<string>(); |
|||
this.SubscribeCheckObservable = new TestObservable(); |
|||
} |
|||
|
|||
public PerspexList<string> Classes |
|||
{ |
|||
get; |
|||
private set; |
|||
} |
|||
|
|||
public TestObservable SubscribeCheckObservable |
|||
{ |
|||
get; |
|||
private set; |
|||
} |
|||
|
|||
public virtual void SetValue(PerspexProperty property, object value, IObservable<bool> activator) |
|||
{ |
|||
} |
|||
} |
|||
|
|||
public static class TestSelectors |
|||
{ |
|||
public static Match SubscribeCheck(this Match match) |
|||
{ |
|||
match.Observables.Add(((SubscribeCheck)match.Control).SubscribeCheckObservable); |
|||
return match; |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,89 @@ |
|||
// -----------------------------------------------------------------------
|
|||
// <copyright file="Activator.cs" company="Steven Kirk">
|
|||
// Copyright 2014 MIT Licence. See licence.md for more information.
|
|||
// </copyright>
|
|||
// -----------------------------------------------------------------------
|
|||
|
|||
namespace Perspex.Styling |
|||
{ |
|||
using System; |
|||
using System.Collections.Generic; |
|||
using System.Diagnostics.Contracts; |
|||
using System.Linq; |
|||
using System.Reactive.Disposables; |
|||
|
|||
public class Activator : IObservable<bool> |
|||
{ |
|||
List<bool> values = new List<bool>(); |
|||
|
|||
List<IDisposable> subscriptions = new List<IDisposable>(); |
|||
|
|||
List<IObserver<bool>> observers = new List<IObserver<bool>>(); |
|||
|
|||
bool last = false; |
|||
|
|||
public Activator(IList<IObservable<bool>> observables) |
|||
{ |
|||
int i = 0; |
|||
|
|||
foreach (IObservable<bool> o in observables.Reverse()) |
|||
{ |
|||
int iCaptured = i; |
|||
|
|||
this.values.Add(false); |
|||
|
|||
IDisposable subscription = o.Subscribe( |
|||
x => this.Update(iCaptured, x), |
|||
x => this.Finish(iCaptured), |
|||
() => this.Finish(iCaptured)); |
|||
|
|||
this.subscriptions.Add(subscription); |
|||
|
|||
++i; |
|||
} |
|||
} |
|||
|
|||
public IDisposable Subscribe(IObserver<bool> observer) |
|||
{ |
|||
Contract.Requires<ArgumentNullException>(observer != null); |
|||
|
|||
this.observers.Add(observer); |
|||
observer.OnNext(last); |
|||
return Disposable.Create(() => this.observers.Remove(observer)); |
|||
} |
|||
|
|||
private void Update(int index, bool value) |
|||
{ |
|||
this.values[index] = value; |
|||
|
|||
bool current = this.values.All(x => x); |
|||
|
|||
if (current != last) |
|||
{ |
|||
this.Push(current); |
|||
last = current; |
|||
} |
|||
} |
|||
|
|||
private void Finish(int i) |
|||
{ |
|||
if (!this.values[i]) |
|||
{ |
|||
// If the observable has finished on 'false' then it will never go back to true
|
|||
// so we can unsubscribe from all the other subscriptions now.
|
|||
foreach (IDisposable subscription in this.subscriptions) |
|||
{ |
|||
subscription.Dispose(); |
|||
} |
|||
} |
|||
} |
|||
|
|||
private void Push(bool value) |
|||
{ |
|||
foreach (IObserver<bool> observer in this.observers) |
|||
{ |
|||
observer.OnNext(value); |
|||
} |
|||
} |
|||
} |
|||
} |
|||
Loading…
Reference in new issue