diff options
Diffstat (limited to 'Xamarin.Forms.Core.UnitTests/BindingBaseUnitTests.cs')
-rw-r--r-- | Xamarin.Forms.Core.UnitTests/BindingBaseUnitTests.cs | 227 |
1 files changed, 227 insertions, 0 deletions
diff --git a/Xamarin.Forms.Core.UnitTests/BindingBaseUnitTests.cs b/Xamarin.Forms.Core.UnitTests/BindingBaseUnitTests.cs new file mode 100644 index 00000000..dd0d2244 --- /dev/null +++ b/Xamarin.Forms.Core.UnitTests/BindingBaseUnitTests.cs @@ -0,0 +1,227 @@ +using System; +using System.Linq; +using NUnit.Framework; + +namespace Xamarin.Forms.Core.UnitTests +{ + public abstract class BindingBaseUnitTests : BaseTestFixture + { + protected abstract BindingBase CreateBinding (BindingMode mode, string stringFormat = null); + + [Test] + public void CloneMode() + { + var binding = CreateBinding (BindingMode.Default); + var clone = binding.Clone(); + + Assert.AreEqual (binding.Mode, clone.Mode); + } + + [Test] + public void StringFormat() + { + var property = BindableProperty.Create<MockBindable, string> (w => w.Foo, null); + + var binding = CreateBinding (BindingMode.Default, "Foo {0}"); + + var vm = new MockViewModel { Text = "Bar" }; + var bo = new MockBindable { BindingContext = vm }; + bo.SetBinding (property, binding); + + Assert.That (bo.GetValue (property), Is.EqualTo ("Foo Bar")); + } + + [Test] + public void StringFormatOnUpdate() + { + var property = BindableProperty.Create<MockBindable, string> (w => w.Foo, null); + + var binding = CreateBinding (BindingMode.Default, "Foo {0}"); + + var vm = new MockViewModel { Text = "Bar" }; + var bo = new MockBindable { BindingContext = vm }; + bo.SetBinding (property, binding); + + vm.Text = "Baz"; + + Assert.That (bo.GetValue (property), Is.EqualTo ("Foo Baz")); + } + + [Test] + [Description ("StringFormat should not be applied to OneWayToSource bindings")] + public void StringFormatOneWayToSource() + { + var property = BindableProperty.Create<MockBindable, string> (w => w.Foo, null); + + var binding = CreateBinding (BindingMode.OneWayToSource, "Foo {0}"); + + var vm = new MockViewModel { Text = "Bar" }; + var bo = new MockBindable { BindingContext = vm }; + bo.SetBinding (property, binding); + + bo.SetValue (property, "Bar"); + + Assert.That (vm.Text, Is.EqualTo ("Bar")); + } + + [Test] + [Description ("StringFormat should only be applied from from source in TwoWay bindings")] + public void StringFormatTwoWay() + { + var property = BindableProperty.Create<MockBindable, string> (w => w.Foo, null); + + var binding = CreateBinding (BindingMode.TwoWay, "Foo {0}"); + + var vm = new MockViewModel { Text = "Bar" }; + var bo = new MockBindable { BindingContext = vm }; + bo.SetBinding (property, binding); + + bo.SetValue (property, "Baz"); + + Assert.That (vm.Text, Is.EqualTo ("Baz")); + Assert.That (bo.GetValue (property), Is.EqualTo ("Foo Baz")); + } + + [Test] + [Description ("You should get an exception when trying to change a binding after it's been applied")] + public void ChangeAfterApply() + { + var property = BindableProperty.Create<MockBindable, string> (w => w.Foo, null); + + var binding = CreateBinding (BindingMode.OneWay); + + var vm = new MockViewModel { Text = "Bar" }; + var bo = new MockBindable { BindingContext = vm }; + bo.SetBinding (property, binding); + + Assert.That (() => binding.Mode = BindingMode.OneWayToSource, Throws.InvalidOperationException); + Assert.That (() => binding.StringFormat = "{0}", Throws.InvalidOperationException); + } + } + + [TestFixture] + public class BindingBaseTests : BaseTestFixture + { + [Test] + public void EnableCollectionSynchronizationInvalid() + { + Assert.That (() => BindingBase.EnableCollectionSynchronization (null, new object(), + (collection, context, method, access) => { }), Throws.InstanceOf<ArgumentNullException>()); + Assert.That (() => BindingBase.EnableCollectionSynchronization (new string[0], new object(), + null), Throws.InstanceOf<ArgumentNullException>()); + Assert.That (() => BindingBase.EnableCollectionSynchronization (new string[0], null, + (collection, context, method, access) => { }), Throws.Nothing); + } + + [Test] + public void EnableCollectionSynchronization() + { + string[] stuff = new[] {"foo", "bar"}; + object context = new object(); + CollectionSynchronizationCallback callback = (collection, o, method, access) => { }; + + BindingBase.EnableCollectionSynchronization (stuff, context, callback); + + CollectionSynchronizationContext syncContext; + Assert.IsTrue (BindingBase.TryGetSynchronizedCollection (stuff, out syncContext)); + Assert.That (syncContext, Is.Not.Null); + Assert.AreSame (syncContext.Callback, callback); + Assert.That (syncContext.ContextReference, Is.Not.Null); + Assert.That (syncContext.ContextReference.Target, Is.SameAs (context)); + } + + [Test] + public void DisableCollectionSynchronization() + { + string[] stuff = new[] {"foo", "bar"}; + object context = new object(); + CollectionSynchronizationCallback callback = (collection, o, method, access) => { }; + + BindingBase.EnableCollectionSynchronization (stuff, context, callback); + + BindingBase.DisableCollectionSynchronization (stuff); + + CollectionSynchronizationContext syncContext; + Assert.IsFalse (BindingBase.TryGetSynchronizedCollection (stuff, out syncContext)); + Assert.IsNull (syncContext); + } + + [Test] + public void CollectionAndContextAreHeldWeakly() + { + WeakReference weakCollection = null, weakContext = null; + + int i = 0; + Action create = null; + create = () => { + if (i++ < 1024) { + create(); + return; + } + + string[] collection = new[] {"foo", "bar"}; + weakCollection = new WeakReference (collection); + + object context = new object(); + weakContext = new WeakReference (context); + + BindingBase.EnableCollectionSynchronization (collection, context, (enumerable, o, method, access) => { }); + }; + + create(); + + GC.Collect(); + GC.WaitForPendingFinalizers(); + + Assert.IsFalse (weakCollection.IsAlive); + Assert.IsFalse (weakContext.IsAlive); + } + + [Test] + public void CollectionAndContextAreHeldWeaklyClosingOverCollection() + { + WeakReference weakCollection = null, weakContext = null; + + int i = 0; + Action create = null; + create = () => { + if (i++ < 1024) { + create(); + return; + } + + string[] collection = new[] {"foo", "bar"}; + weakCollection = new WeakReference (collection); + + object context = new object(); + weakContext = new WeakReference (context); + + BindingBase.EnableCollectionSynchronization (collection, context, (enumerable, o, method, access) => { + collection[0] = "baz"; + }); + }; + + create(); + + GC.Collect(); + GC.WaitForPendingFinalizers(); + + Assert.IsFalse (weakCollection.IsAlive); + Assert.IsFalse (weakContext.IsAlive); + } + + [Test] + public void DisableCollectionSynchronizationInvalid() + { + Assert.That (() => BindingBase.DisableCollectionSynchronization (null), Throws.InstanceOf<ArgumentNullException>()); + } + + [Test] + public void TryGetSynchronizedCollectionInvalid() + { + CollectionSynchronizationContext context; + Assert.That (() => BindingBase.TryGetSynchronizedCollection (null, out context), + Throws.InstanceOf<ArgumentNullException>()); + } + } +} |