maui-linux/Xamarin.Forms.Core.UnitTests/BindableObjectUnitTests.cs

1627 строки
45 KiB
C#
Исходник Обычный вид История

2016-03-22 23:02:25 +03:00
using System;
using System.Globalization;
using NUnit.Framework;
using Xamarin.Forms.Internals;
2016-03-22 23:02:25 +03:00
namespace Xamarin.Forms.Core.UnitTests
{
2018-01-30 06:26:17 +03:00
[TypeConverter(typeof(ToBarConverter))]
2016-03-22 23:02:25 +03:00
internal class Bar
{
}
internal class Baz
{
}
internal class MockBindable
: VisualElement
{
2018-01-30 06:26:17 +03:00
public static readonly BindableProperty TextProperty = BindableProperty.Create<MockBindable, string>(
2016-03-22 23:02:25 +03:00
b => b.Text, "default", BindingMode.TwoWay);
public string Text
{
2018-01-30 06:26:17 +03:00
get { return (string)GetValue(TextProperty); }
set { SetValue(TextProperty, value); }
2016-03-22 23:02:25 +03:00
}
public string Foo { get; set; }
public int TargetInt { get; set; }
2018-01-30 06:26:17 +03:00
public static readonly BindableProperty BarProperty =
BindableProperty.Create<MockBindable, Bar>(w => w.Bar, default(Bar));
2016-03-22 23:02:25 +03:00
2018-01-30 06:26:17 +03:00
public Bar Bar
{
get { return (Bar)GetValue(BarProperty); }
set { SetValue(BarProperty, value); }
2016-03-22 23:02:25 +03:00
}
2018-01-30 06:26:17 +03:00
public static readonly BindableProperty BazProperty =
BindableProperty.Create<MockBindable, Baz>(w => w.Baz, default(Baz));
2016-03-22 23:02:25 +03:00
2018-01-30 06:26:17 +03:00
[TypeConverter(typeof(ToBazConverter))]
public Baz Baz
{
get { return (Baz)GetValue(BazProperty); }
set { SetValue(BazProperty, value); }
2016-03-22 23:02:25 +03:00
}
2018-01-30 06:26:17 +03:00
public static readonly BindableProperty QuxProperty =
BindableProperty.Create<MockBindable, Baz>(w => w.Qux, default(Baz));
2016-03-22 23:02:25 +03:00
2018-01-30 06:26:17 +03:00
public Baz Qux
{
get { return (Baz)GetValue(QuxProperty); }
set { SetValue(QuxProperty, value); }
2016-03-22 23:02:25 +03:00
}
}
internal class ToBarConverter : TypeConverter
{
2018-01-30 06:26:17 +03:00
public override object ConvertFrom(System.Globalization.CultureInfo culture, object value)
2016-03-22 23:02:25 +03:00
{
2018-01-30 06:26:17 +03:00
return new Bar();
2016-03-22 23:02:25 +03:00
}
}
internal class ToBazConverter : TypeConverter
{
2018-01-30 06:26:17 +03:00
public override object ConvertFrom(System.Globalization.CultureInfo culture, object value)
2016-03-22 23:02:25 +03:00
{
2018-01-30 06:26:17 +03:00
return new Baz();
2016-03-22 23:02:25 +03:00
}
}
[TestFixture]
public class BindableObjectUnitTests : BaseTestFixture
{
[SetUp]
public void Setup()
{
2018-01-30 06:26:17 +03:00
Device.PlatformServices = new MockPlatformServices();
2016-03-22 23:02:25 +03:00
}
[TearDown]
public void TearDown()
{
Device.PlatformServices = null;
}
[Test]
public void BindingContext()
{
var mock = new MockBindable();
2018-01-30 06:26:17 +03:00
Assert.IsNull(mock.BindingContext);
2016-03-22 23:02:25 +03:00
object obj = new object();
mock.BindingContext = obj;
2018-01-30 06:26:17 +03:00
Assert.AreSame(obj, mock.BindingContext);
2016-03-22 23:02:25 +03:00
}
[Test]
public void BindingContextChangedEvent()
{
var mock = new MockBindable();
mock.BindingContextChanged += (sender, args) => Assert.Pass();
mock.BindingContext = new object();
2018-01-30 06:26:17 +03:00
Assert.Fail("The BindingContextChanged event was not fired.");
2016-03-22 23:02:25 +03:00
}
[Test]
public void BindingContextChangedOnce()
{
var count = 0;
var mock = new MockBindable();
mock.BindingContextChanged += (sender, args) => ++count;
mock.BindingContext = new object();
Assert.AreEqual(count, 1);
}
2018-01-30 06:26:17 +03:00
class MockVMEquals
{
public string Key { get; set; }
public string Text { get; set; }
public override bool Equals(object obj)
{
var other = obj as MockVMEquals;
if (other == null)
return false;
return Key == other.Key;
}
public override int GetHashCode()
{
return base.GetHashCode();
}
}
[Test]
//https://bugzilla.xamarin.com/show_bug.cgi?id=59507
public void BindingContextChangedCompareReferences()
{
var mock = new MockBindable();
mock.BindingContext = new MockVMEquals { Key = "Foo", Text = "Foo" };
mock.BindingContextChanged += (sender, args) => Assert.Pass();
mock.BindingContext = new MockVMEquals { Key = "Foo", Text = "Bar" };
Assert.Fail("The BindingContextChanged event was not fired.");
}
[Test]
public void ParentAndChildBindingContextChanged()
{
int parentCount = 0, childCount = 0;
var didNotChange = " BindingContext did not change.";
var changedMoreThanOnce = " BindingContext changed more than once.";
var changedWhenNoChange = " BindingContext was changed when there was no change in context.";
var parent = new MockBindable();
parent.BindingContextChanged += (sender, args) => { ++parentCount; };
var child = new MockBindable();
child.BindingContextChanged += (sender, args) => { ++childCount; };
child.Parent = parent;
Assert.AreEqual(parentCount, 0, "Parent BindingContext was changed while parenting a child.");
Assert.AreEqual(childCount, 0, "Child" + changedWhenNoChange);
child.BindingContext = new object(); // set manually
Assert.GreaterOrEqual(childCount, 1, "Child" + didNotChange);
Assert.AreEqual(childCount, 1, "Child" + changedMoreThanOnce);
Assert.AreEqual(parentCount, 0, "Parent" + changedWhenNoChange);
parent.BindingContext = new object();
Assert.GreaterOrEqual(parentCount, 1, "Parent" + didNotChange);
Assert.AreEqual(parentCount, 1, "Parent" + changedMoreThanOnce);
Assert.AreEqual(childCount, 1, "Child" + changedWhenNoChange);
child.BindingContext = new object();
Assert.GreaterOrEqual(childCount, 2, "Child" + didNotChange);
Assert.AreEqual(childCount, 2, "Child" + changedMoreThanOnce);
Assert.AreEqual(parentCount, 1, "Parent" + changedWhenNoChange);
}
[Test]
public void ParentSetOnNullChildBindingContext()
{
var parent = new MockBindable();
var child = new MockBindable();
child.BindingContextChanged += (sender, args) => { Assert.Fail("Child BindingContext was changed when there was no change in context."); };
child.Parent = parent; // this should not trigger binding context change on child since there is no change
parent.BindingContext = new object();
parent.BindingContext = new object();
}
[Test]
public void ParentSetOnNonNullChildBindingContext()
{
var count = 0;
var parent = new MockBindable();
parent.BindingContextChanged += (sender, args) => { ++count; };
var child = new MockBindable();
child.BindingContextChanged += (sender, args) => { ++count; };
child.BindingContext = new object(); // set manually
Assert.AreEqual(count, 1);
child.Parent = parent; // this should not trigger binding context change because child binding was set manually
Assert.AreEqual(count, 1);
parent.BindingContext = new object();
Assert.AreEqual(count, 2);
child.BindingContext = new object();
Assert.AreEqual(count, 3);
}
2016-03-22 23:02:25 +03:00
[Test]
2018-01-30 06:26:17 +03:00
[Description("When the BindingContext changes, any bindings should be immediately applied.")]
2016-03-22 23:02:25 +03:00
public void BindingContextChangedBindingsApplied()
{
var mock = new MockBindable();
2018-01-30 06:26:17 +03:00
mock.SetBinding(MockBindable.TextProperty, new Binding("."));
2016-03-22 23:02:25 +03:00
mock.BindingContext = "Test";
2018-01-30 06:26:17 +03:00
Assert.AreEqual("Test", mock.GetValue(MockBindable.TextProperty));
2016-03-22 23:02:25 +03:00
mock.BindingContext = "Testing";
2018-01-30 06:26:17 +03:00
Assert.AreEqual("Testing", mock.GetValue(MockBindable.TextProperty),
2016-03-22 23:02:25 +03:00
"Bindings were not reapplied to the new binding context");
}
[Test]
2018-01-30 06:26:17 +03:00
[Description("When the BindingContext changes, the new context needs to listen for updates.")]
2016-03-22 23:02:25 +03:00
public void BindingContextChangedBindingsListening()
{
var mock = new MockBindable();
2018-01-30 06:26:17 +03:00
mock.SetBinding(MockBindable.TextProperty, new Binding("Text"));
2016-03-22 23:02:25 +03:00
var vm = new MockViewModel();
mock.BindingContext = vm;
mock.BindingContext = (vm = new MockViewModel());
vm.Text = "test";
2018-01-30 06:26:17 +03:00
Assert.AreEqual("test", mock.GetValue(MockBindable.TextProperty),
2016-03-22 23:02:25 +03:00
"The new ViewModel was not being listened to after being set");
}
[Test]
2018-01-30 06:26:17 +03:00
[Description("When an INPC implementer is unset as the BindingContext, its changes shouldn't be listened to any further.")]
2016-03-22 23:02:25 +03:00
public void BindingContextUnsetStopsListening()
{
var mock = new MockBindable();
2018-01-30 06:26:17 +03:00
mock.SetBinding(MockBindable.TextProperty, new Binding("Text"));
2016-03-22 23:02:25 +03:00
var vm = new MockViewModel();
mock.BindingContext = vm;
mock.BindingContext = null;
vm.Text = "test";
2018-01-30 06:26:17 +03:00
Assert.IsNull(mock.GetValue(Entry.TextProperty), "ViewModel was still being listened to after set to null");
2016-03-22 23:02:25 +03:00
}
[Test]
public void PropertyChanging()
{
var mock = new MockBindable();
2018-01-30 06:26:17 +03:00
mock.PropertyChanging += (sender, args) =>
{
Assert.AreEqual(MockBindable.TextProperty.PropertyName, args.PropertyName);
Assert.AreEqual(MockBindable.TextProperty.DefaultValue, mock.GetValue(MockBindable.TextProperty));
2016-03-22 23:02:25 +03:00
Assert.Pass();
};
2018-01-30 06:26:17 +03:00
mock.SetValue(MockBindable.TextProperty, "foo");
2016-03-22 23:02:25 +03:00
2018-01-30 06:26:17 +03:00
Assert.Fail("The PropertyChanging event was not fired.");
2016-03-22 23:02:25 +03:00
}
[Test]
public void PropertyChangingSameValue()
{
const string value = "foo";
var mock = new MockBindable();
2018-01-30 06:26:17 +03:00
mock.SetValue(MockBindable.TextProperty, value);
mock.PropertyChanging += (s, e) => Assert.Fail();
2016-03-22 23:02:25 +03:00
2018-01-30 06:26:17 +03:00
mock.SetValue(MockBindable.TextProperty, value);
2016-03-22 23:02:25 +03:00
Assert.Pass();
}
[Test]
public void PropertyChangingDefaultValue()
{
2018-01-30 06:26:17 +03:00
var prop = BindableProperty.Create<MockBindable, string>(w => w.Foo, "DefaultValue");
2016-03-22 23:02:25 +03:00
var mock = new MockBindable();
2018-01-30 06:26:17 +03:00
mock.PropertyChanging += (s, e) => Assert.Fail();
mock.SetValue(prop, prop.DefaultValue);
2016-03-22 23:02:25 +03:00
Assert.Pass();
}
[Test]
public void PropertyChanged()
{
const string value = "foo";
var mock = new MockBindable();
2018-01-30 06:26:17 +03:00
mock.PropertyChanged += (sender, args) =>
{
Assert.AreEqual(MockBindable.TextProperty.PropertyName, args.PropertyName);
Assert.AreEqual(value, mock.GetValue(MockBindable.TextProperty));
2016-03-22 23:02:25 +03:00
Assert.Pass();
};
2018-01-30 06:26:17 +03:00
mock.SetValue(MockBindable.TextProperty, value);
Assert.Fail("The PropertyChanged event was not fired.");
2016-03-22 23:02:25 +03:00
}
[Test]
public void PropertyChangedSameValue()
{
const string value = "foo";
var mock = new MockBindable();
2018-01-30 06:26:17 +03:00
mock.SetValue(MockBindable.TextProperty, value);
mock.PropertyChanged += (s, e) => Assert.Fail();
2016-03-22 23:02:25 +03:00
2018-01-30 06:26:17 +03:00
mock.SetValue(MockBindable.TextProperty, value);
2016-03-22 23:02:25 +03:00
Assert.Pass();
}
[Test]
public void PropertyChangedDefaultValue()
{
2018-01-30 06:26:17 +03:00
var prop = BindableProperty.Create<MockBindable, string>(w => w.Foo, "DefaultValue");
2016-03-22 23:02:25 +03:00
var mock = new MockBindable();
2018-01-30 06:26:17 +03:00
mock.PropertyChanged += (s, e) => Assert.Fail();
mock.SetValue(prop, prop.DefaultValue);
2016-03-22 23:02:25 +03:00
Assert.Pass();
}
[Test]
public void GetSetValue()
{
const string value = "foo";
var mock = new MockBindable();
2018-01-30 06:26:17 +03:00
mock.SetValue(MockBindable.TextProperty, value);
2016-03-22 23:02:25 +03:00
2018-01-30 06:26:17 +03:00
Assert.AreEqual(value, mock.GetValue(MockBindable.TextProperty));
2016-03-22 23:02:25 +03:00
}
[Test]
public void GetValueDefault()
{
2018-01-30 06:26:17 +03:00
var nulldefault = BindableProperty.Create<MockBindable, string>(w => w.Foo, null);
TestGetValueDefault(nulldefault);
2016-03-22 23:02:25 +03:00
2018-01-30 06:26:17 +03:00
var foodefault = BindableProperty.Create<MockBindable, string>(w => w.Foo, "Foo");
TestGetValueDefault(foodefault);
2016-03-22 23:02:25 +03:00
}
2018-01-30 06:26:17 +03:00
void TestGetValueDefault(BindableProperty property)
2016-03-22 23:02:25 +03:00
{
var mock = new MockBindable();
2018-01-30 06:26:17 +03:00
object value = mock.GetValue(property);
Assert.AreEqual(property.DefaultValue, value);
2016-03-22 23:02:25 +03:00
}
[Test]
public void SetValueInvalid()
{
var mock = new MockBindable();
2018-01-30 06:26:17 +03:00
Assert.Throws<ArgumentNullException>(() => mock.SetValue((BindableProperty)null, "null"));
2016-03-22 23:02:25 +03:00
}
[Test]
public void GetValueInvalid()
{
var mock = new MockBindable();
2018-01-30 06:26:17 +03:00
Assert.Throws<ArgumentNullException>(() => mock.GetValue(null));
2016-03-22 23:02:25 +03:00
}
[Test]
public void ClearValueInvalid()
{
var mock = new MockBindable();
2018-01-30 06:26:17 +03:00
Assert.Throws<ArgumentNullException>(() => mock.ClearValue((BindableProperty)null));
2016-03-22 23:02:25 +03:00
}
[Test]
public void ClearValue()
{
const string value = "foo";
var mock = new MockBindable();
2018-01-30 06:26:17 +03:00
mock.SetValue(MockBindable.TextProperty, value);
Assert.AreEqual(value, mock.GetValue(MockBindable.TextProperty));
2016-03-22 23:02:25 +03:00
2018-01-30 06:26:17 +03:00
mock.ClearValue(MockBindable.TextProperty);
TestGetValueDefault(MockBindable.TextProperty);
2016-03-22 23:02:25 +03:00
}
[Test]
2018-01-30 06:26:17 +03:00
public void ClearValueTriggersINPC()
2016-03-22 23:02:25 +03:00
{
2018-01-30 06:26:17 +03:00
var bindable = new MockBindable();
2016-03-22 23:02:25 +03:00
bool changingfired = false;
bool changedfired = false;
bool changingdelegatefired = false;
bool changeddelegatefired = false;
2018-01-30 06:26:17 +03:00
var property = BindableProperty.Create("Foo", typeof(string), typeof(MockBindable), "foo",
2016-03-22 23:02:25 +03:00
propertyChanged: (b, o, n) => changeddelegatefired = true,
propertyChanging: (b, o, n) => changingdelegatefired = true
);
bindable.PropertyChanged += (sender, e) => { changedfired |= e.PropertyName == "Foo"; };
bindable.PropertyChanging += (sender, e) => { changingfired |= e.PropertyName == "Foo"; };
2018-01-30 06:26:17 +03:00
bindable.SetValue(property, "foobar");
2016-03-22 23:02:25 +03:00
changingfired = changedfired = changeddelegatefired = changingdelegatefired = false;
2018-01-30 06:26:17 +03:00
bindable.ClearValue(property);
Assert.True(changingfired);
Assert.True(changedfired);
Assert.True(changingdelegatefired);
Assert.True(changeddelegatefired);
2016-03-22 23:02:25 +03:00
}
[Test]
2018-01-30 06:26:17 +03:00
public void ClearValueDoesNotTriggersINPCOnSameValues()
2016-03-22 23:02:25 +03:00
{
2018-01-30 06:26:17 +03:00
var bindable = new MockBindable();
2016-03-22 23:02:25 +03:00
bool changingfired = false;
bool changedfired = false;
bool changingdelegatefired = false;
bool changeddelegatefired = false;
2018-01-30 06:26:17 +03:00
var property = BindableProperty.Create("Foo", typeof(string), typeof(MockBindable), "foo",
2016-03-22 23:02:25 +03:00
propertyChanged: (b, o, n) => changeddelegatefired = true,
propertyChanging: (b, o, n) => changingdelegatefired = true
);
bindable.PropertyChanged += (sender, e) => { changedfired |= e.PropertyName == "Foo"; };
bindable.PropertyChanging += (sender, e) => { changingfired |= e.PropertyName == "Foo"; };
2018-01-30 06:26:17 +03:00
bindable.SetValue(property, "foobar");
bindable.SetValue(property, "foo");
2016-03-22 23:02:25 +03:00
changingfired = changedfired = changeddelegatefired = changingdelegatefired = false;
2018-01-30 06:26:17 +03:00
bindable.ClearValue(property);
Assert.False(changingfired);
Assert.False(changedfired);
Assert.False(changingdelegatefired);
Assert.False(changeddelegatefired);
2016-03-22 23:02:25 +03:00
}
[Test]
public void SetBindingInvalid()
{
var mock = new MockBindable();
2018-01-30 06:26:17 +03:00
Assert.Throws<ArgumentNullException>(() => mock.SetBinding(null, new Binding(".")));
Assert.Throws<ArgumentNullException>(() => mock.SetBinding(MockBindable.TextProperty, null));
2016-03-22 23:02:25 +03:00
}
[Test]
public void RemoveUnaddedBinding()
{
var mock = new MockBindable();
2018-01-30 06:26:17 +03:00
Assert.That(() => mock.RemoveBinding(MockBindable.TextProperty), Throws.Nothing);
2016-03-22 23:02:25 +03:00
}
[Test]
public void RemoveBindingInvalid()
{
var mock = new MockBindable();
2018-01-30 06:26:17 +03:00
Assert.Throws<ArgumentNullException>(() => mock.RemoveBinding(null));
2016-03-22 23:02:25 +03:00
}
[Test]
public void RemovedBindingDoesNotUpdate()
{
const string newvalue = "New Value";
2018-01-30 06:26:17 +03:00
var viewmodel = new MockViewModel
{
2016-03-22 23:02:25 +03:00
Text = "Foo"
};
2018-01-30 06:26:17 +03:00
var binding = new Binding("Text");
2016-03-22 23:02:25 +03:00
var bindable = new MockBindable();
bindable.BindingContext = viewmodel;
2018-01-30 06:26:17 +03:00
bindable.SetBinding(MockBindable.TextProperty, binding);
2016-03-22 23:02:25 +03:00
2018-01-30 06:26:17 +03:00
string original = (string)bindable.GetValue(MockBindable.TextProperty);
2016-03-22 23:02:25 +03:00
2018-01-30 06:26:17 +03:00
bindable.RemoveBinding(MockBindable.TextProperty);
2016-03-22 23:02:25 +03:00
viewmodel.Text = newvalue;
2018-01-30 06:26:17 +03:00
Assert.AreEqual(original, bindable.GetValue(MockBindable.TextProperty),
2016-03-22 23:02:25 +03:00
"Property updated from a removed binding");
}
[Test]
public void CoerceValue()
{
2018-01-30 06:26:17 +03:00
var property = BindableProperty.Create<MockBindable, string>(w => w.Foo, null,
2016-03-22 23:02:25 +03:00
coerceValue: (bo, o) => o.ToUpper());
const string value = "value";
var mock = new MockBindable();
2018-01-30 06:26:17 +03:00
mock.SetValue(property, value);
Assert.AreEqual(value.ToUpper(), mock.GetValue(property));
2016-03-22 23:02:25 +03:00
}
[Test]
public void ValidateValue()
{
2018-01-30 06:26:17 +03:00
var property = BindableProperty.Create<MockBindable, string>(w => w.Foo, null,
2016-03-22 23:02:25 +03:00
validateValue: (b, v) => false);
var mock = new MockBindable();
2018-01-30 06:26:17 +03:00
Assert.Throws<ArgumentException>(() => mock.SetValue(property, null));
2016-03-22 23:02:25 +03:00
}
[Test]
public void BindablePropertyChanged()
{
bool changed = false;
string oldv = "bar";
string newv = "foo";
2018-01-30 06:26:17 +03:00
var property = BindableProperty.Create<MockBindable, string>(w => w.Foo, oldv,
propertyChanged: (b, ov, nv) =>
{
Assert.AreSame(oldv, ov);
Assert.AreSame(newv, nv);
2016-03-22 23:02:25 +03:00
changed = true;
});
var mock = new MockBindable();
2018-01-30 06:26:17 +03:00
mock.SetValue(property, newv);
2016-03-22 23:02:25 +03:00
2018-01-30 06:26:17 +03:00
Assert.IsTrue(changed, "PropertyChanged was not called");
2016-03-22 23:02:25 +03:00
}
[Test]
2018-01-30 06:26:17 +03:00
public void RecursiveChange()
2016-03-22 23:02:25 +03:00
{
bool changedA1 = false, changedA2 = false, changedB1 = false, changedB2 = false;
2018-01-30 06:26:17 +03:00
var mock = new MockBindable();
mock.PropertyChanged += (sender, args) =>
{
if (!changedA1)
{
Assert.AreEqual("1", mock.GetValue(MockBindable.TextProperty));
Assert.IsFalse(changedA2);
Assert.IsFalse(changedB1);
Assert.IsFalse(changedB2);
mock.SetValue(MockBindable.TextProperty, "2");
2016-03-22 23:02:25 +03:00
changedA1 = true;
2018-01-30 06:26:17 +03:00
}
else
{
Assert.AreEqual("2", mock.GetValue(MockBindable.TextProperty));
Assert.IsFalse(changedA2);
Assert.IsTrue(changedB1);
Assert.IsFalse(changedB2);
2016-03-22 23:02:25 +03:00
changedA2 = true;
}
};
2018-01-30 06:26:17 +03:00
mock.PropertyChanged += (sender, args) =>
{
if (!changedB1)
{
Assert.AreEqual("1", mock.GetValue(MockBindable.TextProperty));
Assert.IsTrue(changedA1);
Assert.IsFalse(changedA2);
Assert.IsFalse(changedB2);
2016-03-22 23:02:25 +03:00
changedB1 = true;
2018-01-30 06:26:17 +03:00
}
else
{
Assert.AreEqual("2", mock.GetValue(MockBindable.TextProperty));
Assert.IsTrue(changedA1);
Assert.IsTrue(changedA2);
Assert.IsFalse(changedB2);
2016-03-22 23:02:25 +03:00
changedB2 = true;
}
};
2018-01-30 06:26:17 +03:00
mock.SetValue(MockBindable.TextProperty, "1");
Assert.AreEqual("2", mock.GetValue(MockBindable.TextProperty));
Assert.IsTrue(changedA1);
Assert.IsTrue(changedA2);
Assert.IsTrue(changedB1);
Assert.IsTrue(changedB2);
2016-03-22 23:02:25 +03:00
}
[Test]
public void RaiseOnEqual()
{
string foo = "foo";
var mock = new MockBindable();
2018-01-30 06:26:17 +03:00
mock.SetValue(MockBindable.TextProperty, foo);
2016-03-22 23:02:25 +03:00
bool changing = false;
2018-01-30 06:26:17 +03:00
mock.PropertyChanging += (o, e) =>
{
Assert.That(e.PropertyName, Is.EqualTo(MockBindable.TextProperty.PropertyName));
2016-03-22 23:02:25 +03:00
changing = true;
};
bool changed = true;
2018-01-30 06:26:17 +03:00
mock.PropertyChanged += (o, e) =>
{
Assert.That(e.PropertyName, Is.EqualTo(MockBindable.TextProperty.PropertyName));
2016-03-22 23:02:25 +03:00
changed = true;
};
2018-01-30 06:26:17 +03:00
mock.SetValueCore(MockBindable.TextProperty, foo,
SetValueFlags.ClearOneWayBindings | SetValueFlags.ClearDynamicResource | SetValueFlags.RaiseOnEqual);
2016-03-22 23:02:25 +03:00
2018-01-30 06:26:17 +03:00
Assert.That(changing, Is.True, "PropertyChanging event did not fire");
Assert.That(changed, Is.True, "PropertyChanged event did not fire");
2016-03-22 23:02:25 +03:00
}
[Test]
2018-01-30 06:26:17 +03:00
public void BindingContextGetter()
2016-03-22 23:02:25 +03:00
{
2018-01-30 06:26:17 +03:00
var label = new Label();
var view = new StackLayout { Children = { label } };
2016-03-22 23:02:25 +03:00
2018-01-30 06:26:17 +03:00
view.BindingContext = new { item0 = "Foo", item1 = "Bar" };
label.SetBinding(BindableObject.BindingContextProperty, "item0");
label.SetBinding(Label.TextProperty, Binding.SelfPath);
2016-03-22 23:02:25 +03:00
2018-01-30 06:26:17 +03:00
Assert.AreSame(label.BindingContext, label.GetValue(BindableObject.BindingContextProperty));
2016-03-22 23:02:25 +03:00
}
[Test]
2018-01-30 06:26:17 +03:00
public void BoundBindingContextUpdate()
2016-03-22 23:02:25 +03:00
{
2018-01-30 06:26:17 +03:00
var label = new Label();
var view = new StackLayout { Children = { label } };
2016-03-22 23:02:25 +03:00
var vm = new MockViewModel { Text = "FooBar" };
view.BindingContext = vm;
2018-01-30 06:26:17 +03:00
label.SetBinding(BindableObject.BindingContextProperty, "Text");
label.SetBinding(Label.TextProperty, Binding.SelfPath);
2016-03-22 23:02:25 +03:00
2018-01-30 06:26:17 +03:00
Assert.AreEqual("FooBar", label.BindingContext);
2016-03-22 23:02:25 +03:00
vm.Text = "Baz";
2018-01-30 06:26:17 +03:00
Assert.AreEqual("Baz", label.BindingContext);
2016-03-22 23:02:25 +03:00
}
[Test]
2018-01-30 06:26:17 +03:00
public void BoundBindingContextChange()
2016-03-22 23:02:25 +03:00
{
2018-01-30 06:26:17 +03:00
var label = new Label();
var view = new StackLayout { Children = { label } };
2016-03-22 23:02:25 +03:00
2018-01-30 06:26:17 +03:00
view.BindingContext = new MockViewModel { Text = "FooBar" }; ;
label.SetBinding(BindableObject.BindingContextProperty, "Text");
label.SetBinding(Label.TextProperty, Binding.SelfPath);
2016-03-22 23:02:25 +03:00
2018-01-30 06:26:17 +03:00
Assert.AreEqual("FooBar", label.BindingContext);
2016-03-22 23:02:25 +03:00
2018-01-30 06:26:17 +03:00
view.BindingContext = new MockViewModel { Text = "Baz" }; ;
Assert.AreEqual("Baz", label.BindingContext);
2016-03-22 23:02:25 +03:00
}
[Test]
2018-01-30 06:26:17 +03:00
public void TestReadOnly()
2016-03-22 23:02:25 +03:00
{
2018-01-30 06:26:17 +03:00
var bindablePropertyKey = BindableProperty.CreateReadOnly<MockBindable, string>(w => w.Foo, "DefaultValue");
2016-03-22 23:02:25 +03:00
var bindableProperty = bindablePropertyKey.BindableProperty;
2018-01-30 06:26:17 +03:00
var bindable = new MockBindable();
Assert.AreEqual("DefaultValue", bindable.GetValue(bindableProperty));
2016-03-22 23:02:25 +03:00
2018-01-30 06:26:17 +03:00
bindable.SetValue(bindablePropertyKey, "Bar");
Assert.AreEqual("Bar", bindable.GetValue(bindableProperty));
2016-03-22 23:02:25 +03:00
2018-01-30 06:26:17 +03:00
Assert.Throws<InvalidOperationException>(() => bindable.SetValue(bindableProperty, "Baz"));
Assert.AreEqual("Bar", bindable.GetValue(bindableProperty));
2016-03-22 23:02:25 +03:00
2018-01-30 06:26:17 +03:00
Assert.Throws<InvalidOperationException>(() => bindable.ClearValue(bindableProperty));
2016-03-22 23:02:25 +03:00
2018-01-30 06:26:17 +03:00
bindable.ClearValue(bindablePropertyKey);
Assert.AreEqual("DefaultValue", bindable.GetValue(bindableProperty));
2016-03-22 23:02:25 +03:00
}
[Test]
2018-01-30 06:26:17 +03:00
public void TestBindingTwoWayOnReadOnly()
2016-03-22 23:02:25 +03:00
{
2018-01-30 06:26:17 +03:00
var bindablePropertyKey = BindableProperty.CreateReadOnly<MockBindable, string>(w => w.Foo, "DefaultValue", BindingMode.OneWayToSource);
2016-03-22 23:02:25 +03:00
var bindableProperty = bindablePropertyKey.BindableProperty;
2018-01-30 06:26:17 +03:00
var bindable = new MockBindable();
var vm = new MockViewModel();
2016-03-22 23:02:25 +03:00
2018-01-30 06:26:17 +03:00
bindable.SetBinding(bindableProperty, new Binding("Text", BindingMode.TwoWay));
Assert.DoesNotThrow(() => bindable.BindingContext = vm);
2016-03-22 23:02:25 +03:00
2018-01-30 06:26:17 +03:00
Assert.AreEqual("DefaultValue", bindable.GetValue(bindableProperty));
2016-03-22 23:02:25 +03:00
}
[Test]
2018-01-30 06:26:17 +03:00
public void DefaultValueCreator()
2016-03-22 23:02:25 +03:00
{
int invoked = 0;
2018-01-30 06:26:17 +03:00
object defaultValue = new object();
var bindableProperty = BindableProperty.Create("Foo", typeof(object), typeof(MockBindable), defaultValue, defaultValueCreator: o =>
{
2016-03-22 23:02:25 +03:00
invoked++;
2018-01-30 06:26:17 +03:00
return new object();
2016-03-22 23:02:25 +03:00
});
2018-01-30 06:26:17 +03:00
var bindable = new MockBindable();
2016-03-22 23:02:25 +03:00
2018-01-30 06:26:17 +03:00
Assert.AreSame(defaultValue, bindableProperty.DefaultValue);
var newvalue = bindable.GetValue(bindableProperty);
Assert.AreNotSame(defaultValue, newvalue);
Assert.NotNull(newvalue);
Assert.AreEqual(1, invoked);
2016-03-22 23:02:25 +03:00
}
[Test]
2018-01-30 06:26:17 +03:00
public void DefaultValueCreatorIsInvokedOnlyAtFirstTime()
2016-03-22 23:02:25 +03:00
{
int invoked = 0;
2018-01-30 06:26:17 +03:00
var bindableProperty = BindableProperty.Create("Foo", typeof(object), typeof(MockBindable), null, defaultValueCreator: o =>
{
2016-03-22 23:02:25 +03:00
invoked++;
2018-01-30 06:26:17 +03:00
return new object();
2016-03-22 23:02:25 +03:00
});
2018-01-30 06:26:17 +03:00
var bindable = new MockBindable();
2016-03-22 23:02:25 +03:00
2018-01-30 06:26:17 +03:00
var value0 = bindable.GetValue(bindableProperty);
var value1 = bindable.GetValue(bindableProperty);
Assert.NotNull(value0);
Assert.NotNull(value1);
Assert.AreSame(value0, value1);
Assert.AreEqual(1, invoked);
2016-03-22 23:02:25 +03:00
}
[Test]
2018-01-30 06:26:17 +03:00
public void DefaultValueCreatorNotSharedAccrossInstances()
2016-03-22 23:02:25 +03:00
{
int invoked = 0;
2018-01-30 06:26:17 +03:00
var bindableProperty = BindableProperty.Create("Foo", typeof(object), typeof(MockBindable), null, defaultValueCreator: o =>
{
2016-03-22 23:02:25 +03:00
invoked++;
2018-01-30 06:26:17 +03:00
return new object();
2016-03-22 23:02:25 +03:00
});
2018-01-30 06:26:17 +03:00
var bindable0 = new MockBindable();
var bindable1 = new MockBindable();
var value0 = bindable0.GetValue(bindableProperty);
var value1 = bindable1.GetValue(bindableProperty);
2016-03-22 23:02:25 +03:00
2018-01-30 06:26:17 +03:00
Assert.AreNotSame(value0, value1);
Assert.AreEqual(2, invoked);
2016-03-22 23:02:25 +03:00
}
[Test]
2018-01-30 06:26:17 +03:00
public void DefaultValueCreatorInvokedAfterClearValue()
2016-03-22 23:02:25 +03:00
{
int invoked = 0;
2018-01-30 06:26:17 +03:00
var bindableProperty = BindableProperty.Create("Foo", typeof(object), typeof(MockBindable), null, defaultValueCreator: o =>
{
2016-03-22 23:02:25 +03:00
invoked++;
2018-01-30 06:26:17 +03:00
return new object();
2016-03-22 23:02:25 +03:00
});
2018-01-30 06:26:17 +03:00
var bindable = new MockBindable();
2016-03-22 23:02:25 +03:00
2018-01-30 06:26:17 +03:00
Assert.AreEqual(0, invoked);
2016-03-22 23:02:25 +03:00
2018-01-30 06:26:17 +03:00
var value0 = bindable.GetValue(bindableProperty);
Assert.NotNull(value0);
Assert.AreEqual(1, invoked);
bindable.ClearValue(bindableProperty);
2016-03-22 23:02:25 +03:00
2018-01-30 06:26:17 +03:00
var value1 = bindable.GetValue(bindableProperty);
Assert.NotNull(value1);
Assert.AreEqual(2, invoked);
Assert.AreNotSame(value0, value1);
2016-03-22 23:02:25 +03:00
}
[Test]
2018-01-30 06:26:17 +03:00
public void DefaultValueCreatorOnlyInvokedOnGetValue()
2016-03-22 23:02:25 +03:00
{
int invoked = 0;
2018-01-30 06:26:17 +03:00
var bindableProperty = BindableProperty.Create("Foo", typeof(object), typeof(MockBindable), null, defaultValueCreator: o =>
{
2016-03-22 23:02:25 +03:00
invoked++;
2018-01-30 06:26:17 +03:00
return new object();
2016-03-22 23:02:25 +03:00
});
2018-01-30 06:26:17 +03:00
var bindable = new MockBindable();
2016-03-22 23:02:25 +03:00
2018-01-30 06:26:17 +03:00
Assert.AreEqual(0, invoked);
2016-03-22 23:02:25 +03:00
2018-01-30 06:26:17 +03:00
var newvalue = bindable.GetValue(bindableProperty);
Assert.NotNull(newvalue);
Assert.AreEqual(1, invoked);
2016-03-22 23:02:25 +03:00
}
[Test]
2018-01-30 06:26:17 +03:00
public void DefaultValueCreatorDoesNotTriggerINPC()
2016-03-22 23:02:25 +03:00
{
int invoked = 0;
int propertychanged = 0;
int changedfired = 0;
2018-01-30 06:26:17 +03:00
var bindableProperty = BindableProperty.Create("Foo", typeof(object), typeof(MockBindable), null,
propertyChanged: (bindable, oldvalue, newvalue) =>
{
propertychanged++;
2016-03-22 23:02:25 +03:00
},
2018-01-30 06:26:17 +03:00
defaultValueCreator: o =>
{
2016-03-22 23:02:25 +03:00
invoked++;
2018-01-30 06:26:17 +03:00
return new object();
2016-03-22 23:02:25 +03:00
});
2018-01-30 06:26:17 +03:00
var bp = new MockBindable();
bp.PropertyChanged += (sender, e) =>
{
2016-03-22 23:02:25 +03:00
if (e.PropertyName == "Foo")
changedfired++;
};
2018-01-30 06:26:17 +03:00
var value0 = bp.GetValue(bindableProperty);
Assert.NotNull(value0);
Assert.AreEqual(1, invoked);
Assert.AreEqual(0, propertychanged);
Assert.AreEqual(0, changedfired);
}
[Test]
public void IsSetIsFalseWhenPropNotSet()
{
string defaultValue = "default";
var bindableProperty = BindableProperty.Create("Foo", typeof(string), typeof(MockBindable), defaultValue);
var bindable = new MockBindable();
Assert.AreEqual(defaultValue, bindableProperty.DefaultValue);
var isSet = bindable.IsSet(bindableProperty);
Assert.IsFalse(isSet);
}
[Test]
public void IsSetIsTrueWhenPropSet()
{
string defaultValue = "default";
string newValue = "new value";
var bindableProperty = BindableProperty.Create("Foo", typeof(string), typeof(MockBindable), defaultValue);
var bindable = new MockBindable();
Assert.AreEqual(defaultValue, bindableProperty.DefaultValue);
bindable.SetValue(bindableProperty, newValue);
var isSet = bindable.IsSet(bindableProperty);
Assert.IsTrue(isSet);
}
[Test]
public void IsSetIsTrueWhenPropSetToDefault()
{
string defaultValue = "default";
var bindableProperty = BindableProperty.Create("Foo", typeof(string), typeof(MockBindable), defaultValue);
var bindable = new MockBindable();
Assert.AreEqual(defaultValue, bindableProperty.DefaultValue);
bindable.SetValue(bindableProperty, defaultValue);
var isSet = bindable.IsSet(bindableProperty);
Assert.IsTrue(isSet);
}
[Test]
public void IsSetIsTrueWhenPropSetByDefaultValueCreator()
{
string defaultValue = "default";
string defaultValueC = "defaultVC";
2016-03-22 23:02:25 +03:00
2018-01-30 06:26:17 +03:00
var bindableProperty = BindableProperty.Create("Foo", typeof(string), typeof(MockBindable), defaultValue, defaultValueCreator: o =>
{
return defaultValueC;
});
var bindable = new MockBindable();
Assert.AreEqual(defaultValue, bindableProperty.DefaultValue);
var created = bindable.GetValue(bindableProperty);
Assert.AreEqual(defaultValueC, created);
var isSet = bindable.IsSet(bindableProperty);
Assert.IsTrue(isSet);
}
[Test]
public void IsDefaultIsTrueWhenPropNotSet()
{
string defaultValue = "default";
var bindableProperty = BindableProperty.Create("Foo", typeof(string), typeof(MockBindable), defaultValue);
var bindable = new MockBindable();
Assert.AreEqual(defaultValue, bindableProperty.DefaultValue);
var isDefault = bindable.IsDefault(bindableProperty);
Assert.IsTrue(isDefault);
}
[Test]
public void IsDefaultIsFalseWhenPropSet()
{
string defaultValue = "default";
string newValue = "new value";
var bindableProperty = BindableProperty.Create("Foo", typeof(string), typeof(MockBindable), defaultValue);
var bindable = new MockBindable();
Assert.AreEqual(defaultValue, bindableProperty.DefaultValue);
bindable.SetValue(bindableProperty, newValue);
var isDefault = bindable.IsDefault(bindableProperty);
Assert.IsFalse(isDefault);
}
[Test]
public void IsDefaultIsTrueWhenPropSetToDefault()
{
string defaultValue = "default";
var bindableProperty = BindableProperty.Create("Foo", typeof(string), typeof(MockBindable), defaultValue);
var bindable = new MockBindable();
Assert.AreEqual(defaultValue, bindableProperty.DefaultValue);
bindable.SetValue(bindableProperty, defaultValue);
var isDefault = bindable.IsDefault(bindableProperty);
Assert.IsTrue(isDefault);
2016-03-22 23:02:25 +03:00
}
[Test]
2018-01-30 06:26:17 +03:00
public void IsDefaultIsTrueWhenPropSetByDefaultValueCreator()
2016-03-22 23:02:25 +03:00
{
2018-01-30 06:26:17 +03:00
string defaultValue = "default";
string defaultValueC = "defaultVC";
2016-03-22 23:02:25 +03:00
2018-01-30 06:26:17 +03:00
var bindableProperty = BindableProperty.Create("Foo", typeof(string), typeof(MockBindable), defaultValue, defaultValueCreator: o =>
{
return defaultValueC;
});
var bindable = new MockBindable();
Assert.AreEqual(defaultValue, bindableProperty.DefaultValue);
var created = bindable.GetValue(bindableProperty);
Assert.AreEqual(defaultValueC, created);
var isDefault = bindable.IsDefault(bindableProperty);
Assert.IsTrue(isDefault);
2016-03-22 23:02:25 +03:00
}
[Test]
2018-01-30 06:26:17 +03:00
public void IsDefaultIsTrueWhenPropSetToDefaultValueCreatorValue()
2016-03-22 23:02:25 +03:00
{
2018-01-30 06:26:17 +03:00
string defaultValue = "default";
string defaultValueC = "defaultVC";
var bindableProperty = BindableProperty.Create("Foo", typeof(string), typeof(MockBindable), defaultValue, defaultValueCreator: o =>
{
return defaultValueC;
});
var bindable = new MockBindable();
Assert.AreEqual(defaultValue, bindableProperty.DefaultValue);
var created = bindable.GetValue(bindableProperty);
Assert.AreEqual(defaultValueC, created);
2016-03-22 23:02:25 +03:00
2018-01-30 06:26:17 +03:00
bindable.SetValue(bindableProperty, defaultValueC);
var isDefault = bindable.IsDefault(bindableProperty);
Assert.IsTrue(isDefault);
2016-03-22 23:02:25 +03:00
}
[Test]
2018-01-30 06:26:17 +03:00
public void StyleValueIsOverridenByValue()
2016-03-22 23:02:25 +03:00
{
2018-01-30 06:26:17 +03:00
var label = new Label();
label.SetValue(Label.TextProperty, "Foo", true);
Assert.AreEqual("Foo", label.Text);
label.SetValue(Label.TextProperty, "Bar");
Assert.AreEqual("Bar", label.Text);
}
[Test]
public void StyleBindingIsOverridenByValue()
{
var label = new Label();
label.SetBinding(Label.TextProperty, new Binding("foo"), true);
label.BindingContext = new { foo = "Foo" };
Assert.AreEqual("Foo", label.Text);
label.SetValue(Label.TextProperty, "Bar");
Assert.AreEqual("Bar", label.Text);
}
[Test]
public void StyleDynResourceIsOverridenByValue()
{
var label = new Label();
label.SetDynamicResource(Label.TextProperty, "foo", true);
2016-03-22 23:02:25 +03:00
label.Resources = new ResourceDictionary {
{"foo", "Foo"}
};
2018-01-30 06:26:17 +03:00
Assert.AreEqual("Foo", label.Text);
2016-03-22 23:02:25 +03:00
2018-01-30 06:26:17 +03:00
label.SetValue(Label.TextProperty, "Bar");
Assert.AreEqual("Bar", label.Text);
2016-03-22 23:02:25 +03:00
}
[Test]
2018-01-30 06:26:17 +03:00
public void StyleValueIsOverridenByBinding()
2016-03-22 23:02:25 +03:00
{
2018-01-30 06:26:17 +03:00
var label = new Label();
label.BindingContext = new { foo = "Foo", bar = "Bar" };
label.SetValue(Label.TextProperty, "Foo", true);
Assert.AreEqual("Foo", label.Text);
2016-03-22 23:02:25 +03:00
2018-01-30 06:26:17 +03:00
label.SetBinding(Label.TextProperty, "bar");
Assert.AreEqual("Bar", label.Text);
2016-03-22 23:02:25 +03:00
}
[Test]
2018-01-30 06:26:17 +03:00
public void StyleBindingIsOverridenByBinding()
2016-03-22 23:02:25 +03:00
{
2018-01-30 06:26:17 +03:00
var label = new Label();
label.BindingContext = new { foo = "Foo", bar = "Bar" };
label.SetBinding(Label.TextProperty, new Binding("foo"), true);
Assert.AreEqual("Foo", label.Text);
2016-03-22 23:02:25 +03:00
2018-01-30 06:26:17 +03:00
label.SetBinding(Label.TextProperty, "bar");
Assert.AreEqual("Bar", label.Text);
2016-03-22 23:02:25 +03:00
}
[Test]
2018-01-30 06:26:17 +03:00
public void StyleDynResourceIsOverridenByBinding()
2016-03-22 23:02:25 +03:00
{
2018-01-30 06:26:17 +03:00
var label = new Label();
label.BindingContext = new { foo = "Foo", bar = "Bar" };
label.SetDynamicResource(Label.TextProperty, "foo", true);
2016-03-22 23:02:25 +03:00
label.Resources = new ResourceDictionary {
{"foo", "Foo"},
};
2018-01-30 06:26:17 +03:00
Assert.AreEqual("Foo", label.Text);
2016-03-22 23:02:25 +03:00
2018-01-30 06:26:17 +03:00
label.SetBinding(Label.TextProperty, "bar");
Assert.AreEqual("Bar", label.Text);
2016-03-22 23:02:25 +03:00
}
[Test]
2018-01-30 06:26:17 +03:00
public void StyleValueIsOverridenByDynResource()
2016-03-22 23:02:25 +03:00
{
2018-01-30 06:26:17 +03:00
var label = new Label();
2016-03-22 23:02:25 +03:00
label.Resources = new ResourceDictionary {
{"foo", "Foo"},
{"bar", "Bar"}
};
2018-01-30 06:26:17 +03:00
label.BindingContext = new { foo = "Foo", bar = "Bar" };
label.SetValue(Label.TextProperty, "Foo", true);
Assert.AreEqual("Foo", label.Text);
2016-03-22 23:02:25 +03:00
2018-01-30 06:26:17 +03:00
label.SetDynamicResource(Label.TextProperty, "bar");
Assert.AreEqual("Bar", label.Text);
2016-03-22 23:02:25 +03:00
}
[Test]
2018-01-30 06:26:17 +03:00
public void StyleBindingIsOverridenByDynResource()
2016-03-22 23:02:25 +03:00
{
2018-01-30 06:26:17 +03:00
var label = new Label();
2016-03-22 23:02:25 +03:00
label.Resources = new ResourceDictionary {
{"foo", "Foo"},
{"bar", "Bar"}
};
2018-01-30 06:26:17 +03:00
label.BindingContext = new { foo = "Foo", bar = "Bar" };
label.SetBinding(Label.TextProperty, new Binding("foo"), true);
Assert.AreEqual("Foo", label.Text);
2016-03-22 23:02:25 +03:00
2018-01-30 06:26:17 +03:00
label.SetDynamicResource(Label.TextProperty, "bar");
Assert.AreEqual("Bar", label.Text);
2016-03-22 23:02:25 +03:00
}
[Test]
2018-01-30 06:26:17 +03:00
public void StyleDynResourceIsOverridenByDynResource()
2016-03-22 23:02:25 +03:00
{
2018-01-30 06:26:17 +03:00
var label = new Label();
2016-03-22 23:02:25 +03:00
label.Resources = new ResourceDictionary {
{"foo", "Foo"},
{"bar", "Bar"}
};
2018-01-30 06:26:17 +03:00
label.BindingContext = new { foo = "Foo", bar = "Bar" };
label.SetDynamicResource(Label.TextProperty, "foo", true);
2016-03-22 23:02:25 +03:00
2018-01-30 06:26:17 +03:00
Assert.AreEqual("Foo", label.Text);
2016-03-22 23:02:25 +03:00
2018-01-30 06:26:17 +03:00
label.SetDynamicResource(Label.TextProperty, "bar");
Assert.AreEqual("Bar", label.Text);
2016-03-22 23:02:25 +03:00
}
[Test]
2018-01-30 06:26:17 +03:00
public void ValueIsPreservedOnStyleValue()
2016-03-22 23:02:25 +03:00
{
2018-01-30 06:26:17 +03:00
var label = new Label();
label.SetValue(Label.TextProperty, "Foo");
Assert.AreEqual("Foo", label.Text);
2016-03-22 23:02:25 +03:00
2018-01-30 06:26:17 +03:00
label.SetValue(Label.TextProperty, "Bar", true);
Assert.AreEqual("Foo", label.Text);
2016-03-22 23:02:25 +03:00
}
[Test]
2018-01-30 06:26:17 +03:00
public void BindingIsPreservedOnStyleValue()
2016-03-22 23:02:25 +03:00
{
2018-01-30 06:26:17 +03:00
var label = new Label();
label.SetBinding(Label.TextProperty, new Binding("foo"));
label.BindingContext = new { foo = "Foo" };
Assert.AreEqual("Foo", label.Text);
2016-03-22 23:02:25 +03:00
2018-01-30 06:26:17 +03:00
label.SetValue(Label.TextProperty, "Bar", true);
Assert.AreEqual("Foo", label.Text);
2016-03-22 23:02:25 +03:00
}
[Test]
2018-01-30 06:26:17 +03:00
public void DynResourceIsPreservedOnStyleValue()
2016-03-22 23:02:25 +03:00
{
2018-01-30 06:26:17 +03:00
var label = new Label();
label.SetDynamicResource(Label.TextProperty, "foo");
2016-03-22 23:02:25 +03:00
label.Resources = new ResourceDictionary {
{"foo", "Foo"}
};
2018-01-30 06:26:17 +03:00
Assert.AreEqual("Foo", label.Text);
2016-03-22 23:02:25 +03:00
2018-01-30 06:26:17 +03:00
label.SetValue(Label.TextProperty, "Bar", true);
Assert.AreEqual("Foo", label.Text);
2016-03-22 23:02:25 +03:00
}
[Test]
2018-01-30 06:26:17 +03:00
public void ValueIsPreservedOnStyleBinding()
2016-03-22 23:02:25 +03:00
{
2018-01-30 06:26:17 +03:00
var label = new Label();
label.BindingContext = new { foo = "Foo", bar = "Bar" };
label.SetValue(Label.TextProperty, "Foo");
Assert.AreEqual("Foo", label.Text);
2016-03-22 23:02:25 +03:00
2018-01-30 06:26:17 +03:00
label.SetBinding(Label.TextProperty, new Binding("bar"), true);
Assert.AreEqual("Foo", label.Text);
2016-03-22 23:02:25 +03:00
}
[Test]
2018-01-30 06:26:17 +03:00
public void BindingIsPreservedOnStyleBinding()
2016-03-22 23:02:25 +03:00
{
2018-01-30 06:26:17 +03:00
var label = new Label();
label.BindingContext = new { foo = "Foo", bar = "Bar" };
label.SetBinding(Label.TextProperty, new Binding("foo"));
Assert.AreEqual("Foo", label.Text);
2016-03-22 23:02:25 +03:00
2018-01-30 06:26:17 +03:00
label.SetBinding(Label.TextProperty, new Binding("bar"), true);
Assert.AreEqual("Foo", label.Text);
2016-03-22 23:02:25 +03:00
}
[Test]
2018-01-30 06:26:17 +03:00
public void DynResourceIsPreservedOnStyleBinding()
2016-03-22 23:02:25 +03:00
{
2018-01-30 06:26:17 +03:00
var label = new Label();
label.BindingContext = new { foo = "Foo", bar = "Bar" };
label.SetDynamicResource(Label.TextProperty, "foo");
2016-03-22 23:02:25 +03:00
label.Resources = new ResourceDictionary {
{"foo", "Foo"},
};
2018-01-30 06:26:17 +03:00
Assert.AreEqual("Foo", label.Text);
2016-03-22 23:02:25 +03:00
2018-01-30 06:26:17 +03:00
label.SetBinding(Label.TextProperty, new Binding("bar"), true);
Assert.AreEqual("Foo", label.Text);
2016-03-22 23:02:25 +03:00
}
[Test]
2018-01-30 06:26:17 +03:00
public void ValueIsPreservedOnStyleDynResource()
2016-03-22 23:02:25 +03:00
{
2018-01-30 06:26:17 +03:00
var label = new Label();
2016-03-22 23:02:25 +03:00
label.Resources = new ResourceDictionary {
{"foo", "Foo"},
{"bar", "Bar"}
};
2018-01-30 06:26:17 +03:00
label.BindingContext = new { foo = "Foo", bar = "Bar" };
label.SetValue(Label.TextProperty, "Foo");
Assert.AreEqual("Foo", label.Text);
2016-03-22 23:02:25 +03:00
2018-01-30 06:26:17 +03:00
label.SetDynamicResource(Label.TextProperty, "bar", true);
Assert.AreEqual("Foo", label.Text);
2016-03-22 23:02:25 +03:00
}
[Test]
2018-01-30 06:26:17 +03:00
public void BindingIsPreservedOnStyleDynResource()
2016-03-22 23:02:25 +03:00
{
2018-01-30 06:26:17 +03:00
var label = new Label();
2016-03-22 23:02:25 +03:00
label.Resources = new ResourceDictionary {
{"foo", "Foo"},
{"bar", "Bar"}
};
2018-01-30 06:26:17 +03:00
label.BindingContext = new { foo = "Foo", bar = "Bar" };
label.SetBinding(Label.TextProperty, new Binding("foo"));
Assert.AreEqual("Foo", label.Text);
2016-03-22 23:02:25 +03:00
2018-01-30 06:26:17 +03:00
label.SetDynamicResource(Label.TextProperty, "bar", true);
Assert.AreEqual("Foo", label.Text);
2016-03-22 23:02:25 +03:00
}
[Test]
2018-01-30 06:26:17 +03:00
public void DynResourceIsPreservedOnStyleDynResource()
2016-03-22 23:02:25 +03:00
{
2018-01-30 06:26:17 +03:00
var label = new Label();
2016-03-22 23:02:25 +03:00
label.Resources = new ResourceDictionary {
{"foo", "Foo"},
{"bar", "Bar"}
};
2018-01-30 06:26:17 +03:00
label.BindingContext = new { foo = "Foo", bar = "Bar" };
label.SetDynamicResource(Label.TextProperty, "foo");
2016-03-22 23:02:25 +03:00
2018-01-30 06:26:17 +03:00
Assert.AreEqual("Foo", label.Text);
2016-03-22 23:02:25 +03:00
2018-01-30 06:26:17 +03:00
label.SetDynamicResource(Label.TextProperty, "bar", true);
Assert.AreEqual("Foo", label.Text);
2016-03-22 23:02:25 +03:00
}
[Test]
2018-01-30 06:26:17 +03:00
public void StyleValueIsOverridenByStyleValue()
2016-03-22 23:02:25 +03:00
{
2018-01-30 06:26:17 +03:00
var label = new Label();
label.SetValue(Label.TextProperty, "Foo", true);
Assert.AreEqual("Foo", label.Text);
2016-03-22 23:02:25 +03:00
2018-01-30 06:26:17 +03:00
label.SetValue(Label.TextProperty, "Bar", true);
Assert.AreEqual("Bar", label.Text);
2016-03-22 23:02:25 +03:00
}
[Test]
2018-01-30 06:26:17 +03:00
public void StyleBindingIsOverridenByStyleValue()
2016-03-22 23:02:25 +03:00
{
2018-01-30 06:26:17 +03:00
var label = new Label();
label.SetBinding(Label.TextProperty, new Binding("foo"), true);
label.BindingContext = new { foo = "Foo" };
Assert.AreEqual("Foo", label.Text);
2016-03-22 23:02:25 +03:00
2018-01-30 06:26:17 +03:00
label.SetValue(Label.TextProperty, "Bar", true);
Assert.AreEqual("Bar", label.Text);
2016-03-22 23:02:25 +03:00
}
[Test]
2018-01-30 06:26:17 +03:00
public void StyleDynResourceIsOverridenByStyleValue()
2016-03-22 23:02:25 +03:00
{
2018-01-30 06:26:17 +03:00
var label = new Label();
label.SetDynamicResource(Label.TextProperty, "foo", true);
2016-03-22 23:02:25 +03:00
label.Resources = new ResourceDictionary {
{"foo", "Foo"}
};
2018-01-30 06:26:17 +03:00
Assert.AreEqual("Foo", label.Text);
2016-03-22 23:02:25 +03:00
2018-01-30 06:26:17 +03:00
label.SetValue(Label.TextProperty, "Bar", true);
Assert.AreEqual("Bar", label.Text);
2016-03-22 23:02:25 +03:00
}
[Test]
2018-01-30 06:26:17 +03:00
public void StyleValueIsOverridenByStyleBinding()
2016-03-22 23:02:25 +03:00
{
2018-01-30 06:26:17 +03:00
var label = new Label();
label.BindingContext = new { foo = "Foo", bar = "Bar" };
label.SetValue(Label.TextProperty, "Foo", true);
Assert.AreEqual("Foo", label.Text);
2016-03-22 23:02:25 +03:00
2018-01-30 06:26:17 +03:00
label.SetBinding(Label.TextProperty, new Binding("bar"), true);
Assert.AreEqual("Bar", label.Text);
2016-03-22 23:02:25 +03:00
}
[Test]
2018-01-30 06:26:17 +03:00
public void StyleBindingIsOverridenByStyleBinding()
2016-03-22 23:02:25 +03:00
{
2018-01-30 06:26:17 +03:00
var label = new Label();
label.BindingContext = new { foo = "Foo", bar = "Bar" };
label.SetBinding(Label.TextProperty, new Binding("foo"), true);
Assert.AreEqual("Foo", label.Text);
2016-03-22 23:02:25 +03:00
2018-01-30 06:26:17 +03:00
label.SetBinding(Label.TextProperty, new Binding("bar"), true);
Assert.AreEqual("Bar", label.Text);
2016-03-22 23:02:25 +03:00
}
[Test]
2018-01-30 06:26:17 +03:00
public void StyleDynResourceIsOverridenByStyleBinding()
2016-03-22 23:02:25 +03:00
{
2018-01-30 06:26:17 +03:00
var label = new Label();
label.BindingContext = new { foo = "Foo", bar = "Bar" };
label.SetDynamicResource(Label.TextProperty, "foo", true);
2016-03-22 23:02:25 +03:00
label.Resources = new ResourceDictionary {
{"foo", "Foo"},
};
2018-01-30 06:26:17 +03:00
Assert.AreEqual("Foo", label.Text);
2016-03-22 23:02:25 +03:00
2018-01-30 06:26:17 +03:00
label.SetBinding(Label.TextProperty, new Binding("bar"), true);
Assert.AreEqual("Bar", label.Text);
2016-03-22 23:02:25 +03:00
}
[Test]
2018-01-30 06:26:17 +03:00
public void StyleValueIsOverridenByStyleDynResource()
2016-03-22 23:02:25 +03:00
{
2018-01-30 06:26:17 +03:00
var label = new Label();
2016-03-22 23:02:25 +03:00
label.Resources = new ResourceDictionary {
{"foo", "Foo"},
{"bar", "Bar"}
};
2018-01-30 06:26:17 +03:00
label.BindingContext = new { foo = "Foo", bar = "Bar" };
label.SetValue(Label.TextProperty, "Foo", true);
Assert.AreEqual("Foo", label.Text);
2016-03-22 23:02:25 +03:00
2018-01-30 06:26:17 +03:00
label.SetDynamicResource(Label.TextProperty, "bar", true);
Assert.AreEqual("Bar", label.Text);
2016-03-22 23:02:25 +03:00
}
[Test]
2018-01-30 06:26:17 +03:00
public void StyleBindingIsOverridenByStyleDynResource()
2016-03-22 23:02:25 +03:00
{
2018-01-30 06:26:17 +03:00
var label = new Label();
2016-03-22 23:02:25 +03:00
label.Resources = new ResourceDictionary {
{"foo", "Foo"},
{"bar", "Bar"}
};
2018-01-30 06:26:17 +03:00
label.BindingContext = new { foo = "Foo", bar = "Bar" };
label.SetBinding(Label.TextProperty, new Binding("foo"), true);
Assert.AreEqual("Foo", label.Text);
2016-03-22 23:02:25 +03:00
2018-01-30 06:26:17 +03:00
label.SetDynamicResource(Label.TextProperty, "bar", true);
Assert.AreEqual("Bar", label.Text);
2016-03-22 23:02:25 +03:00
}
[Test]
2018-01-30 06:26:17 +03:00
public void StyleDynResourceIsOverridenByStyleDynResource()
2016-03-22 23:02:25 +03:00
{
2018-01-30 06:26:17 +03:00
var label = new Label();
2016-03-22 23:02:25 +03:00
label.Resources = new ResourceDictionary {
{"foo", "Foo"},
{"bar", "Bar"}
};
2018-01-30 06:26:17 +03:00
label.BindingContext = new { foo = "Foo", bar = "Bar" };
label.SetDynamicResource(Label.TextProperty, "foo", true);
2016-03-22 23:02:25 +03:00
2018-01-30 06:26:17 +03:00
Assert.AreEqual("Foo", label.Text);
2016-03-22 23:02:25 +03:00
2018-01-30 06:26:17 +03:00
label.SetDynamicResource(Label.TextProperty, "bar", true);
Assert.AreEqual("Bar", label.Text);
2016-03-22 23:02:25 +03:00
}
[Test]
2018-01-30 06:26:17 +03:00
public void SetValueCoreImplicitelyCastBasicType()
2016-03-22 23:02:25 +03:00
{
2018-01-30 06:26:17 +03:00
var prop = BindableProperty.Create("Foo", typeof(int), typeof(MockBindable), 0);
var bindable = new MockBindable();
2016-03-22 23:02:25 +03:00
2018-01-30 06:26:17 +03:00
Assert.DoesNotThrow(() => bindable.SetValue(prop, (object)(short)42));
Assert.AreEqual(42, bindable.GetValue(prop));
2016-03-22 23:02:25 +03:00
2018-01-30 06:26:17 +03:00
bindable.SetValue(prop, (object)(long)-42);
Assert.AreNotEqual(-42, bindable.GetValue(prop));
2016-03-22 23:02:25 +03:00
}
class CastFromString
{
public string Result { get; private set; }
2018-01-30 06:26:17 +03:00
public static implicit operator CastFromString(string source)
2016-03-22 23:02:25 +03:00
{
2018-01-30 06:26:17 +03:00
var o = new CastFromString();
2016-03-22 23:02:25 +03:00
o.Result = source;
return o;
}
}
[Test]
2018-01-30 06:26:17 +03:00
public void SetValueCoreInvokesOpImplicitOnPropertyType()
2016-03-22 23:02:25 +03:00
{
2018-01-30 06:26:17 +03:00
var prop = BindableProperty.Create("Foo", typeof(CastFromString), typeof(MockBindable), null);
var bindable = new MockBindable();
2016-03-22 23:02:25 +03:00
2018-01-30 06:26:17 +03:00
Assert.Null(bindable.GetValue(prop));
bindable.SetValue(prop, "foo");
2016-03-22 23:02:25 +03:00
2018-01-30 06:26:17 +03:00
Assert.AreEqual("foo", ((CastFromString)bindable.GetValue(prop)).Result);
2016-03-22 23:02:25 +03:00
}
class CastToString
{
string Result { get; set; }
2018-01-30 06:26:17 +03:00
public CastToString(string result)
2016-03-22 23:02:25 +03:00
{
Result = result;
}
2018-01-30 06:26:17 +03:00
public static implicit operator string(CastToString source)
2016-03-22 23:02:25 +03:00
{
return source.Result;
}
2018-01-30 06:26:17 +03:00
public override string ToString()
2016-03-22 23:02:25 +03:00
{
2018-01-30 06:26:17 +03:00
throw new InvalidOperationException();
2016-03-22 23:02:25 +03:00
}
}
[Test]
2018-01-30 06:26:17 +03:00
public void SetValueCoreInvokesOpImplicitOnValue()
2016-03-22 23:02:25 +03:00
{
2018-01-30 06:26:17 +03:00
var prop = BindableProperty.Create("Foo", typeof(string), typeof(MockBindable), null);
var bindable = new MockBindable();
2016-03-22 23:02:25 +03:00
2018-01-30 06:26:17 +03:00
Assert.Null(bindable.GetValue(prop));
bindable.SetValue(prop, new CastToString("foo"));
2016-03-22 23:02:25 +03:00
2018-01-30 06:26:17 +03:00
Assert.AreEqual("foo", bindable.GetValue(prop));
2016-03-22 23:02:25 +03:00
}
[Test]
2018-01-30 06:26:17 +03:00
public void DefaultValueCreatorCalledForChangeDelegates()
2016-03-22 23:02:25 +03:00
{
int changedOld = -1;
int changedNew = -1;
int changingOld = -1;
int changingNew = -1;
2018-01-30 06:26:17 +03:00
var prop = BindableProperty.Create("Foo", typeof(int), typeof(MockBindable), 0, defaultValueCreator: b => 10,
propertyChanged: (b, value, newValue) =>
{
changedOld = (int)value;
changedNew = (int)newValue;
},
propertyChanging: (b, value, newValue) =>
{
changingOld = (int)value;
changingNew = (int)newValue;
2016-03-22 23:02:25 +03:00
});
2018-01-30 06:26:17 +03:00
var bindable = new MockBindable();
2016-03-22 23:02:25 +03:00
2018-01-30 06:26:17 +03:00
var defaultValue = (int)bindable.GetValue(prop);
2016-03-22 23:02:25 +03:00
2018-01-30 06:26:17 +03:00
Assert.AreEqual(10, defaultValue);
2016-03-22 23:02:25 +03:00
2018-01-30 06:26:17 +03:00
bindable.SetValue(prop, 5);
2016-03-22 23:02:25 +03:00
2018-01-30 06:26:17 +03:00
bindable.ClearValue(prop);
2016-03-22 23:02:25 +03:00
2018-01-30 06:26:17 +03:00
Assert.AreEqual(5, changedOld);
Assert.AreEqual(5, changingOld);
Assert.AreEqual(10, changedNew);
Assert.AreEqual(10, changingNew);
2016-03-22 23:02:25 +03:00
}
[Test]
public void GetValuesDefaults()
{
2018-01-30 06:26:17 +03:00
var prop = BindableProperty.Create("Foo", typeof(int), typeof(MockBindable), 0);
var prop1 = BindableProperty.Create("Foo1", typeof(int), typeof(MockBindable), 1);
var prop2 = BindableProperty.Create("Foo2", typeof(int), typeof(MockBindable), 2);
var bindable = new MockBindable();
2016-03-22 23:02:25 +03:00
2018-01-30 06:26:17 +03:00
object[] values = bindable.GetValues(prop, prop1, prop2);
Assert.That(values.Length == 3);
Assert.That(values[0], Is.EqualTo(0));
Assert.That(values[1], Is.EqualTo(1));
Assert.That(values[2], Is.EqualTo(2));
2016-03-22 23:02:25 +03:00
}
[Test]
public void GetValues()
{
2018-01-30 06:26:17 +03:00
var prop = BindableProperty.Create("Foo", typeof(int), typeof(MockBindable), 0);
var prop1 = BindableProperty.Create("Foo1", typeof(int), typeof(MockBindable), 1);
var prop2 = BindableProperty.Create("Foo2", typeof(int), typeof(MockBindable), 2);
var bindable = new MockBindable();
bindable.SetValue(prop, 3);
bindable.SetValue(prop2, 5);
2016-03-22 23:02:25 +03:00
2018-01-30 06:26:17 +03:00
object[] values = bindable.GetValues(prop, prop1, prop2);
Assert.That(values.Length == 3);
Assert.That(values[0], Is.EqualTo(3));
Assert.That(values[1], Is.EqualTo(1));
Assert.That(values[2], Is.EqualTo(5));
2016-03-22 23:02:25 +03:00
}
class BindingContextConverter
: IValueConverter
{
2018-01-30 06:26:17 +03:00
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
2016-03-22 23:02:25 +03:00
{
return new MockViewModel { Text = value + "Converted" };
}
2018-01-30 06:26:17 +03:00
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
2016-03-22 23:02:25 +03:00
{
throw new NotImplementedException();
}
}
[Test]
//https://bugzilla.xamarin.com/show_bug.cgi?id=24485
public void BindingContextBoundThroughConverter()
{
var bindable = new MockBindable();
bindable.BindingContext = "test";
2018-01-30 06:26:17 +03:00
bindable.SetBinding(BindableObject.BindingContextProperty, new Binding(".", converter: new BindingContextConverter()));
bindable.SetBinding(MockBindable.TextProperty, "Text");
2016-03-22 23:02:25 +03:00
2018-01-30 06:26:17 +03:00
Assert.That(() => bindable.Text, Is.EqualTo("testConverted"));
2016-03-22 23:02:25 +03:00
}
public class VMLocator
{
public event EventHandler Invoked;
public int Count;
2018-01-30 06:26:17 +03:00
public object VM
{
get
{
2016-03-22 23:02:25 +03:00
Count++;
var eh = Invoked;
if (eh != null)
2018-01-30 06:26:17 +03:00
eh(this, EventArgs.Empty);
return new object();
2016-03-22 23:02:25 +03:00
}
}
}
[Test]
//https://bugzilla.xamarin.com/show_bug.cgi?id=27299
2018-01-30 06:26:17 +03:00
public void BindingOnBindingContextDoesntReapplyBindingContextBinding()
2016-03-22 23:02:25 +03:00
{
2018-01-30 06:26:17 +03:00
var bindable = new MockBindable();
var locator = new VMLocator();
Assert.AreEqual(0, locator.Count);
locator.Invoked += (sender, e) => Assert.IsTrue(locator.Count <= 1);
bindable.SetBinding(BindableObject.BindingContextProperty, new Binding("VM", source: locator));
Assert.IsTrue(locator.Count == 1);
2016-03-22 23:02:25 +03:00
}
[Test]
public void BindingsEditableAfterUnapplied()
{
var bindable = new MockBindable();
2018-01-30 06:26:17 +03:00
var binding = new Binding(".");
bindable.SetBinding(MockBindable.TextProperty, binding);
2016-03-22 23:02:25 +03:00
bindable.BindingContext = "foo";
2018-01-30 06:26:17 +03:00
Assume.That(bindable.Text, Is.EqualTo(bindable.BindingContext));
2016-03-22 23:02:25 +03:00
2018-01-30 06:26:17 +03:00
bindable.RemoveBinding(MockBindable.TextProperty);
2016-03-22 23:02:25 +03:00
2018-01-30 06:26:17 +03:00
Assert.That(() => binding.Path = "foo", Throws.Nothing);
2016-03-22 23:02:25 +03:00
}
[Test]
// https://bugzilla.xamarin.com/show_bug.cgi?id=24054
public void BindingsAppliedUnappliedWithNullContext()
{
var bindable = new MockBindable();
2018-01-30 06:26:17 +03:00
var binding = new Binding(".");
bindable.SetBinding(MockBindable.TextProperty, binding);
2016-03-22 23:02:25 +03:00
bindable.BindingContext = "foo";
2018-01-30 06:26:17 +03:00
Assume.That(bindable.Text, Is.EqualTo(bindable.BindingContext));
2016-03-22 23:02:25 +03:00
bindable.BindingContext = null;
2018-01-30 06:26:17 +03:00
Assume.That(bindable.Text, Is.EqualTo(bindable.BindingContext));
2016-03-22 23:02:25 +03:00
bindable.BindingContext = "bar";
2018-01-30 06:26:17 +03:00
Assume.That(bindable.Text, Is.EqualTo(bindable.BindingContext));
2016-03-22 23:02:25 +03:00
2018-01-30 06:26:17 +03:00
bindable.RemoveBinding(MockBindable.TextProperty);
2016-03-22 23:02:25 +03:00
2018-01-30 06:26:17 +03:00
Assert.That(() => binding.Path = "Foo", Throws.Nothing);
2016-03-22 23:02:25 +03:00
}
}
}