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

1596 строки
44 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
{
[TypeConverter(typeof(ToBarConverter))]
2016-03-22 23:02:25 +03:00
internal class Bar
{
}
internal class Baz
{
}
internal class MockBindable
: VisualElement
{
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
{
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; }
public static readonly BindableProperty BarProperty =
BindableProperty.Create<MockBindable, Bar>(w => w.Bar, default(Bar));
2016-03-22 23:02:25 +03:00
public Bar Bar
{
get { return (Bar)GetValue(BarProperty); }
set { SetValue(BarProperty, value); }
2016-03-22 23:02:25 +03:00
}
public static readonly BindableProperty BazProperty =
BindableProperty.Create<MockBindable, Baz>(w => w.Baz, default(Baz));
2016-03-22 23:02:25 +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
}
public static readonly BindableProperty QuxProperty =
BindableProperty.Create<MockBindable, Baz>(w => w.Qux, default(Baz));
2016-03-22 23:02:25 +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
{
public override object ConvertFrom(System.Globalization.CultureInfo culture, object value)
2016-03-22 23:02:25 +03:00
{
return new Bar();
2016-03-22 23:02:25 +03:00
}
}
internal class ToBazConverter : TypeConverter
{
public override object ConvertFrom(System.Globalization.CultureInfo culture, object value)
2016-03-22 23:02:25 +03:00
{
return new Baz();
2016-03-22 23:02:25 +03:00
}
}
[TestFixture]
public class BindableObjectUnitTests : BaseTestFixture
{
[SetUp]
public void Setup()
{
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();
Assert.IsNull(mock.BindingContext);
2016-03-22 23:02:25 +03:00
object obj = new object();
mock.BindingContext = obj;
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();
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);
}
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]
[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();
mock.SetBinding(MockBindable.TextProperty, new Binding("."));
2016-03-22 23:02:25 +03:00
mock.BindingContext = "Test";
Assert.AreEqual("Test", mock.GetValue(MockBindable.TextProperty));
2016-03-22 23:02:25 +03:00
mock.BindingContext = "Testing";
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]
[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();
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";
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]
[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();
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";
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();
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();
};
mock.SetValue(MockBindable.TextProperty, "foo");
2016-03-22 23:02:25 +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();
mock.SetValue(MockBindable.TextProperty, value);
mock.PropertyChanging += (s, e) => Assert.Fail();
2016-03-22 23:02:25 +03:00
mock.SetValue(MockBindable.TextProperty, value);
2016-03-22 23:02:25 +03:00
Assert.Pass();
}
[Test]
public void PropertyChangingDefaultValue()
{
var prop = BindableProperty.Create<MockBindable, string>(w => w.Foo, "DefaultValue");
2016-03-22 23:02:25 +03:00
var mock = new MockBindable();
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();
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();
};
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();
mock.SetValue(MockBindable.TextProperty, value);
mock.PropertyChanged += (s, e) => Assert.Fail();
2016-03-22 23:02:25 +03:00
mock.SetValue(MockBindable.TextProperty, value);
2016-03-22 23:02:25 +03:00
Assert.Pass();
}
[Test]
public void PropertyChangedDefaultValue()
{
var prop = BindableProperty.Create<MockBindable, string>(w => w.Foo, "DefaultValue");
2016-03-22 23:02:25 +03:00
var mock = new MockBindable();
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();
mock.SetValue(MockBindable.TextProperty, value);
2016-03-22 23:02:25 +03:00
Assert.AreEqual(value, mock.GetValue(MockBindable.TextProperty));
2016-03-22 23:02:25 +03:00
}
[Test]
public void GetValueDefault()
{
var nulldefault = BindableProperty.Create<MockBindable, string>(w => w.Foo, null);
TestGetValueDefault(nulldefault);
2016-03-22 23:02:25 +03:00
var foodefault = BindableProperty.Create<MockBindable, string>(w => w.Foo, "Foo");
TestGetValueDefault(foodefault);
2016-03-22 23:02:25 +03:00
}
void TestGetValueDefault(BindableProperty property)
2016-03-22 23:02:25 +03:00
{
var mock = new MockBindable();
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();
Assert.Throws<ArgumentNullException>(() => mock.SetValue((BindableProperty)null, "null"));
2016-03-22 23:02:25 +03:00
}
[Test]
public void GetValueInvalid()
{
var mock = new MockBindable();
Assert.Throws<ArgumentNullException>(() => mock.GetValue(null));
2016-03-22 23:02:25 +03:00
}
[Test]
public void ClearValueInvalid()
{
var mock = new MockBindable();
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();
mock.SetValue(MockBindable.TextProperty, value);
Assert.AreEqual(value, mock.GetValue(MockBindable.TextProperty));
2016-03-22 23:02:25 +03:00
mock.ClearValue(MockBindable.TextProperty);
TestGetValueDefault(MockBindable.TextProperty);
2016-03-22 23:02:25 +03:00
}
[Test]
public void ClearValueTriggersINPC()
2016-03-22 23:02:25 +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;
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"; };
bindable.SetValue(property, "foobar");
2016-03-22 23:02:25 +03:00
changingfired = changedfired = changeddelegatefired = changingdelegatefired = false;
bindable.ClearValue(property);
Assert.True(changingfired);
Assert.True(changedfired);
Assert.True(changingdelegatefired);
Assert.True(changeddelegatefired);
2016-03-22 23:02:25 +03:00
}
[Test]
public void ClearValueDoesNotTriggersINPCOnSameValues()
2016-03-22 23:02:25 +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;
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"; };
bindable.SetValue(property, "foobar");
bindable.SetValue(property, "foo");
2016-03-22 23:02:25 +03:00
changingfired = changedfired = changeddelegatefired = changingdelegatefired = false;
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();
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();
Assert.That(() => mock.RemoveBinding(MockBindable.TextProperty), Throws.Nothing);
2016-03-22 23:02:25 +03:00
}
[Test]
public void RemoveBindingInvalid()
{
var mock = new MockBindable();
Assert.Throws<ArgumentNullException>(() => mock.RemoveBinding(null));
2016-03-22 23:02:25 +03:00
}
[Test]
public void RemovedBindingDoesNotUpdate()
{
const string newvalue = "New Value";
var viewmodel = new MockViewModel
{
2016-03-22 23:02:25 +03:00
Text = "Foo"
};
var binding = new Binding("Text");
2016-03-22 23:02:25 +03:00
var bindable = new MockBindable();
bindable.BindingContext = viewmodel;
bindable.SetBinding(MockBindable.TextProperty, binding);
2016-03-22 23:02:25 +03:00
string original = (string)bindable.GetValue(MockBindable.TextProperty);
2016-03-22 23:02:25 +03:00
bindable.RemoveBinding(MockBindable.TextProperty);
2016-03-22 23:02:25 +03:00
viewmodel.Text = newvalue;
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()
{
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();
mock.SetValue(property, value);
Assert.AreEqual(value.ToUpper(), mock.GetValue(property));
2016-03-22 23:02:25 +03:00
}
[Test]
public void ValidateValue()
{
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();
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";
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();
mock.SetValue(property, newv);
2016-03-22 23:02:25 +03:00
Assert.IsTrue(changed, "PropertyChanged was not called");
2016-03-22 23:02:25 +03:00
}
[Test]
public void RecursiveChange()
2016-03-22 23:02:25 +03:00
{
bool changedA1 = false, changedA2 = false, changedB1 = false, changedB2 = false;
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;
}
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;
}
};
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;
}
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;
}
};
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();
mock.SetValue(MockBindable.TextProperty, foo);
2016-03-22 23:02:25 +03:00
bool changing = false;
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;
mock.PropertyChanged += (o, e) =>
{
Assert.That(e.PropertyName, Is.EqualTo(MockBindable.TextProperty.PropertyName));
2016-03-22 23:02:25 +03:00
changed = true;
};
mock.SetValueCore(MockBindable.TextProperty, foo,
SetValueFlags.ClearOneWayBindings | SetValueFlags.ClearDynamicResource | SetValueFlags.RaiseOnEqual);
2016-03-22 23:02:25 +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]
public void BindingContextGetter()
2016-03-22 23:02:25 +03:00
{
var label = new Label();
var view = new StackLayout { Children = { label } };
2016-03-22 23:02:25 +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
Assert.AreSame(label.BindingContext, label.GetValue(BindableObject.BindingContextProperty));
2016-03-22 23:02:25 +03:00
}
[Test]
public void BoundBindingContextUpdate()
2016-03-22 23:02:25 +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;
label.SetBinding(BindableObject.BindingContextProperty, "Text");
label.SetBinding(Label.TextProperty, Binding.SelfPath);
2016-03-22 23:02:25 +03:00
Assert.AreEqual("FooBar", label.BindingContext);
2016-03-22 23:02:25 +03:00
vm.Text = "Baz";
Assert.AreEqual("Baz", label.BindingContext);
2016-03-22 23:02:25 +03:00
}
[Test]
public void BoundBindingContextChange()
2016-03-22 23:02:25 +03:00
{
var label = new Label();
var view = new StackLayout { Children = { label } };
2016-03-22 23:02:25 +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
Assert.AreEqual("FooBar", label.BindingContext);
2016-03-22 23:02:25 +03:00
view.BindingContext = new MockViewModel { Text = "Baz" }; ;
Assert.AreEqual("Baz", label.BindingContext);
2016-03-22 23:02:25 +03:00
}
[Test]
public void TestReadOnly()
2016-03-22 23:02:25 +03:00
{
var bindablePropertyKey = BindableProperty.CreateReadOnly<MockBindable, string>(w => w.Foo, "DefaultValue");
2016-03-22 23:02:25 +03:00
var bindableProperty = bindablePropertyKey.BindableProperty;
var bindable = new MockBindable();
Assert.AreEqual("DefaultValue", bindable.GetValue(bindableProperty));
2016-03-22 23:02:25 +03:00
bindable.SetValue(bindablePropertyKey, "Bar");
Assert.AreEqual("Bar", bindable.GetValue(bindableProperty));
2016-03-22 23:02:25 +03:00
Assert.Throws<InvalidOperationException>(() => bindable.SetValue(bindableProperty, "Baz"));
Assert.AreEqual("Bar", bindable.GetValue(bindableProperty));
2016-03-22 23:02:25 +03:00
Assert.Throws<InvalidOperationException>(() => bindable.ClearValue(bindableProperty));
2016-03-22 23:02:25 +03:00
bindable.ClearValue(bindablePropertyKey);
Assert.AreEqual("DefaultValue", bindable.GetValue(bindableProperty));
2016-03-22 23:02:25 +03:00
}
[Test]
public void TestBindingTwoWayOnReadOnly()
2016-03-22 23:02:25 +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;
var bindable = new MockBindable();
var vm = new MockViewModel();
2016-03-22 23:02:25 +03:00
bindable.SetBinding(bindableProperty, new Binding("Text", BindingMode.TwoWay));
Assert.DoesNotThrow(() => bindable.BindingContext = vm);
2016-03-22 23:02:25 +03:00
Assert.AreEqual("DefaultValue", bindable.GetValue(bindableProperty));
2016-03-22 23:02:25 +03:00
}
[Test]
public void DefaultValueCreator()
2016-03-22 23:02:25 +03:00
{
int invoked = 0;
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++;
return new object();
2016-03-22 23:02:25 +03:00
});
var bindable = new MockBindable();
2016-03-22 23:02:25 +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]
public void DefaultValueCreatorIsInvokedOnlyAtFirstTime()
2016-03-22 23:02:25 +03:00
{
int invoked = 0;
var bindableProperty = BindableProperty.Create("Foo", typeof(object), typeof(MockBindable), null, defaultValueCreator: o =>
{
2016-03-22 23:02:25 +03:00
invoked++;
return new object();
2016-03-22 23:02:25 +03:00
});
var bindable = new MockBindable();
2016-03-22 23:02:25 +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]
public void DefaultValueCreatorNotSharedAccrossInstances()
2016-03-22 23:02:25 +03:00
{
int invoked = 0;
var bindableProperty = BindableProperty.Create("Foo", typeof(object), typeof(MockBindable), null, defaultValueCreator: o =>
{
2016-03-22 23:02:25 +03:00
invoked++;
return new object();
2016-03-22 23:02:25 +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
Assert.AreNotSame(value0, value1);
Assert.AreEqual(2, invoked);
2016-03-22 23:02:25 +03:00
}
[Test]
public void DefaultValueCreatorInvokedAfterClearValue()
2016-03-22 23:02:25 +03:00
{
int invoked = 0;
var bindableProperty = BindableProperty.Create("Foo", typeof(object), typeof(MockBindable), null, defaultValueCreator: o =>
{
2016-03-22 23:02:25 +03:00
invoked++;
return new object();
2016-03-22 23:02:25 +03:00
});
var bindable = new MockBindable();
2016-03-22 23:02:25 +03:00
Assert.AreEqual(0, invoked);
2016-03-22 23:02:25 +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
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]
public void DefaultValueCreatorOnlyInvokedOnGetValue()
2016-03-22 23:02:25 +03:00
{
int invoked = 0;
var bindableProperty = BindableProperty.Create("Foo", typeof(object), typeof(MockBindable), null, defaultValueCreator: o =>
{
2016-03-22 23:02:25 +03:00
invoked++;
return new object();
2016-03-22 23:02:25 +03:00
});
var bindable = new MockBindable();
2016-03-22 23:02:25 +03:00
Assert.AreEqual(0, invoked);
2016-03-22 23:02:25 +03:00
var newvalue = bindable.GetValue(bindableProperty);
Assert.NotNull(newvalue);
Assert.AreEqual(1, invoked);
2016-03-22 23:02:25 +03:00
}
[Test]
public void DefaultValueCreatorDoesNotTriggerINPC()
2016-03-22 23:02:25 +03:00
{
int invoked = 0;
int propertychanged = 0;
int changedfired = 0;
var bindableProperty = BindableProperty.Create("Foo", typeof(object), typeof(MockBindable), null,
propertyChanged: (bindable, oldvalue, newvalue) =>
{
propertychanged++;
2016-03-22 23:02:25 +03:00
},
defaultValueCreator: o =>
{
2016-03-22 23:02:25 +03:00
invoked++;
return new object();
2016-03-22 23:02:25 +03:00
});
var bp = new MockBindable();
bp.PropertyChanged += (sender, e) =>
{
2016-03-22 23:02:25 +03:00
if (e.PropertyName == "Foo")
changedfired++;
};
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);
}
[Android] Button Border can be set independent of other properties and will not change the size of the Button. fixes #1436 **behavior change** (#1570) * Revert "Revert "Fix border on android buttons (#941)"" This reverts commit a4c7f31d1215174aa86d7647bcbce0dd5e719a9a. * Add repro for 1436 Fix typo * [Core] Use 2dp for Android default Button BorderRadius * [Android] Add shadow & padding to ButtonDrawable * [Android] Set BackgroundDrawable on Button when BorderWidth, BorderRadius, and BorderColor are changed Also add RippleDrawable when supported for the nice ripple effect on press, and set the PaddingTop for the ButtonDrawable. fixes #1436 * [Android] Default Color for Button is specified for AppCompat and AppAct * [Android] Check BorderRadius value against proper default * Fix test case number * grumble grumble this branch is still vs2015 grumble * [Android] Get button color from resources * [Core] Obsolete Button.BorderRadius in favor of CornerRadius * [Core] Added VisualElement.DefaultBackgroundColor * Update tests to ignore obsolete prop warning * [Android] Use Button.CornerRadius instead of BorderRadius * [iOS] Use Button.CornerRadius instead of BorderRadius * [macOS] Use Button.CornerRadius instead of BorderRadius * [UWP] Use Button.CornerRadius instead of BorderRadius * Update docs * Fix more cases of BorderRadius obsolete warnings * [UWP] Use BP.DefaultValue instead of abstracted const * [Android] Use BP.DefaultValue instead of abstracted const * [Core] Remove unnecessary abstracted consts from Button * [Android] Fix default corner radius on ButtonDrawable * Unit tests for Button.CornerRadius/BorderRadius * [iOS] Restore default Button.CornerRadius * [UWP] Add todo
2018-02-08 20:55:08 +03:00
[Test]
public void IsSetIsFalseWhenPropCleared()
[Android] Button Border can be set independent of other properties and will not change the size of the Button. fixes #1436 **behavior change** (#1570) * Revert "Revert "Fix border on android buttons (#941)"" This reverts commit a4c7f31d1215174aa86d7647bcbce0dd5e719a9a. * Add repro for 1436 Fix typo * [Core] Use 2dp for Android default Button BorderRadius * [Android] Add shadow & padding to ButtonDrawable * [Android] Set BackgroundDrawable on Button when BorderWidth, BorderRadius, and BorderColor are changed Also add RippleDrawable when supported for the nice ripple effect on press, and set the PaddingTop for the ButtonDrawable. fixes #1436 * [Android] Default Color for Button is specified for AppCompat and AppAct * [Android] Check BorderRadius value against proper default * Fix test case number * grumble grumble this branch is still vs2015 grumble * [Android] Get button color from resources * [Core] Obsolete Button.BorderRadius in favor of CornerRadius * [Core] Added VisualElement.DefaultBackgroundColor * Update tests to ignore obsolete prop warning * [Android] Use Button.CornerRadius instead of BorderRadius * [iOS] Use Button.CornerRadius instead of BorderRadius * [macOS] Use Button.CornerRadius instead of BorderRadius * [UWP] Use Button.CornerRadius instead of BorderRadius * Update docs * Fix more cases of BorderRadius obsolete warnings * [UWP] Use BP.DefaultValue instead of abstracted const * [Android] Use BP.DefaultValue instead of abstracted const * [Core] Remove unnecessary abstracted consts from Button * [Android] Fix default corner radius on ButtonDrawable * Unit tests for Button.CornerRadius/BorderRadius * [iOS] Restore default Button.CornerRadius * [UWP] Add todo
2018-02-08 20:55:08 +03:00
{
string defaultValue = "default";
string newValue = "new value";
var bindableProperty = BindableProperty.Create("Foo", typeof(string), typeof(MockBindable), defaultValue);
var bindable = new MockBindable();
bindable.SetValue(bindableProperty, newValue);
bindable.ClearValue(bindableProperty);
Assert.That(bindable.IsSet(bindableProperty), Is.False);
[Android] Button Border can be set independent of other properties and will not change the size of the Button. fixes #1436 **behavior change** (#1570) * Revert "Revert "Fix border on android buttons (#941)"" This reverts commit a4c7f31d1215174aa86d7647bcbce0dd5e719a9a. * Add repro for 1436 Fix typo * [Core] Use 2dp for Android default Button BorderRadius * [Android] Add shadow & padding to ButtonDrawable * [Android] Set BackgroundDrawable on Button when BorderWidth, BorderRadius, and BorderColor are changed Also add RippleDrawable when supported for the nice ripple effect on press, and set the PaddingTop for the ButtonDrawable. fixes #1436 * [Android] Default Color for Button is specified for AppCompat and AppAct * [Android] Check BorderRadius value against proper default * Fix test case number * grumble grumble this branch is still vs2015 grumble * [Android] Get button color from resources * [Core] Obsolete Button.BorderRadius in favor of CornerRadius * [Core] Added VisualElement.DefaultBackgroundColor * Update tests to ignore obsolete prop warning * [Android] Use Button.CornerRadius instead of BorderRadius * [iOS] Use Button.CornerRadius instead of BorderRadius * [macOS] Use Button.CornerRadius instead of BorderRadius * [UWP] Use Button.CornerRadius instead of BorderRadius * Update docs * Fix more cases of BorderRadius obsolete warnings * [UWP] Use BP.DefaultValue instead of abstracted const * [Android] Use BP.DefaultValue instead of abstracted const * [Core] Remove unnecessary abstracted consts from Button * [Android] Fix default corner radius on ButtonDrawable * Unit tests for Button.CornerRadius/BorderRadius * [iOS] Restore default Button.CornerRadius * [UWP] Add todo
2018-02-08 20:55:08 +03:00
}
[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);
2016-03-22 23:02:25 +03:00
bindable.SetValue(bindableProperty, defaultValue);
var isSet = bindable.IsSet(bindableProperty);
Assert.IsTrue(isSet);
}
[Android] Button Border can be set independent of other properties and will not change the size of the Button. fixes #1436 **behavior change** (#1570) * Revert "Revert "Fix border on android buttons (#941)"" This reverts commit a4c7f31d1215174aa86d7647bcbce0dd5e719a9a. * Add repro for 1436 Fix typo * [Core] Use 2dp for Android default Button BorderRadius * [Android] Add shadow & padding to ButtonDrawable * [Android] Set BackgroundDrawable on Button when BorderWidth, BorderRadius, and BorderColor are changed Also add RippleDrawable when supported for the nice ripple effect on press, and set the PaddingTop for the ButtonDrawable. fixes #1436 * [Android] Default Color for Button is specified for AppCompat and AppAct * [Android] Check BorderRadius value against proper default * Fix test case number * grumble grumble this branch is still vs2015 grumble * [Android] Get button color from resources * [Core] Obsolete Button.BorderRadius in favor of CornerRadius * [Core] Added VisualElement.DefaultBackgroundColor * Update tests to ignore obsolete prop warning * [Android] Use Button.CornerRadius instead of BorderRadius * [iOS] Use Button.CornerRadius instead of BorderRadius * [macOS] Use Button.CornerRadius instead of BorderRadius * [UWP] Use Button.CornerRadius instead of BorderRadius * Update docs * Fix more cases of BorderRadius obsolete warnings * [UWP] Use BP.DefaultValue instead of abstracted const * [Android] Use BP.DefaultValue instead of abstracted const * [Core] Remove unnecessary abstracted consts from Button * [Android] Fix default corner radius on ButtonDrawable * Unit tests for Button.CornerRadius/BorderRadius * [iOS] Restore default Button.CornerRadius * [UWP] Add todo
2018-02-08 20:55:08 +03:00
[Test]
public void IsSetIsTrueWhenPropSetByDefaultValueCreator()
{
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);
var isSet = bindable.IsSet(bindableProperty);
Assert.IsTrue(isSet);
2016-03-22 23:02:25 +03:00
}
[Test]
public void StyleValueIsOverridenByValue()
2016-03-22 23:02:25 +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
label.SetValue(Label.TextProperty, "Bar");
Assert.AreEqual("Bar", label.Text);
2016-03-22 23:02:25 +03:00
}
[Test]
public void StyleBindingIsOverridenByValue()
2016-03-22 23:02:25 +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
label.SetValue(Label.TextProperty, "Bar");
Assert.AreEqual("Bar", label.Text);
2016-03-22 23:02:25 +03:00
}
[Test]
public void StyleDynResourceIsOverridenByValue()
2016-03-22 23:02:25 +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"}
};
Assert.AreEqual("Foo", label.Text);
2016-03-22 23:02:25 +03:00
label.SetValue(Label.TextProperty, "Bar");
Assert.AreEqual("Bar", label.Text);
2016-03-22 23:02:25 +03:00
}
[Test]
public void StyleValueIsOverridenByBinding()
2016-03-22 23:02:25 +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
label.SetBinding(Label.TextProperty, "bar");
Assert.AreEqual("Bar", label.Text);
2016-03-22 23:02:25 +03:00
}
[Test]
public void StyleBindingIsOverridenByBinding()
2016-03-22 23:02:25 +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
label.SetBinding(Label.TextProperty, "bar");
Assert.AreEqual("Bar", label.Text);
2016-03-22 23:02:25 +03:00
}
[Test]
public void StyleDynResourceIsOverridenByBinding()
2016-03-22 23:02:25 +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"},
};
Assert.AreEqual("Foo", label.Text);
2016-03-22 23:02:25 +03:00
label.SetBinding(Label.TextProperty, "bar");
Assert.AreEqual("Bar", label.Text);
2016-03-22 23:02:25 +03:00
}
[Test]
public void StyleValueIsOverridenByDynResource()
2016-03-22 23:02:25 +03:00
{
var label = new Label();
2016-03-22 23:02:25 +03:00
label.Resources = new ResourceDictionary {
{"foo", "Foo"},
{"bar", "Bar"}
};
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
label.SetDynamicResource(Label.TextProperty, "bar");
Assert.AreEqual("Bar", label.Text);
2016-03-22 23:02:25 +03:00
}
[Test]
public void StyleBindingIsOverridenByDynResource()
2016-03-22 23:02:25 +03:00
{
var label = new Label();
2016-03-22 23:02:25 +03:00
label.Resources = new ResourceDictionary {
{"foo", "Foo"},
{"bar", "Bar"}
};
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
label.SetDynamicResource(Label.TextProperty, "bar");
Assert.AreEqual("Bar", label.Text);
2016-03-22 23:02:25 +03:00
}
[Test]
public void StyleDynResourceIsOverridenByDynResource()
2016-03-22 23:02:25 +03:00
{
var label = new Label();
2016-03-22 23:02:25 +03:00
label.Resources = new ResourceDictionary {
{"foo", "Foo"},
{"bar", "Bar"}
};
label.BindingContext = new { foo = "Foo", bar = "Bar" };
label.SetDynamicResource(Label.TextProperty, "foo", true);
2016-03-22 23:02:25 +03:00
Assert.AreEqual("Foo", label.Text);
2016-03-22 23:02:25 +03:00
label.SetDynamicResource(Label.TextProperty, "bar");
Assert.AreEqual("Bar", label.Text);
2016-03-22 23:02:25 +03:00
}
[Test]
public void ValueIsPreservedOnStyleValue()
2016-03-22 23:02:25 +03:00
{
var label = new Label();
label.SetValue(Label.TextProperty, "Foo");
Assert.AreEqual("Foo", label.Text);
2016-03-22 23:02:25 +03:00
label.SetValue(Label.TextProperty, "Bar", true);
Assert.AreEqual("Foo", label.Text);
2016-03-22 23:02:25 +03:00
}
[Test]
public void BindingIsPreservedOnStyleValue()
2016-03-22 23:02:25 +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
label.SetValue(Label.TextProperty, "Bar", true);
Assert.AreEqual("Foo", label.Text);
2016-03-22 23:02:25 +03:00
}
[Test]
public void DynResourceIsPreservedOnStyleValue()
2016-03-22 23:02:25 +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"}
};
Assert.AreEqual("Foo", label.Text);
2016-03-22 23:02:25 +03:00
label.SetValue(Label.TextProperty, "Bar", true);
Assert.AreEqual("Foo", label.Text);
2016-03-22 23:02:25 +03:00
}
[Test]
public void ValueIsPreservedOnStyleBinding()
2016-03-22 23:02:25 +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
label.SetBinding(Label.TextProperty, new Binding("bar"), true);
Assert.AreEqual("Foo", label.Text);
2016-03-22 23:02:25 +03:00
}
[Test]
public void BindingIsPreservedOnStyleBinding()
2016-03-22 23:02:25 +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
label.SetBinding(Label.TextProperty, new Binding("bar"), true);
Assert.AreEqual("Foo", label.Text);
2016-03-22 23:02:25 +03:00
}
[Test]
public void DynResourceIsPreservedOnStyleBinding()
2016-03-22 23:02:25 +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"},
};
Assert.AreEqual("Foo", label.Text);
2016-03-22 23:02:25 +03:00
label.SetBinding(Label.TextProperty, new Binding("bar"), true);
Assert.AreEqual("Foo", label.Text);
2016-03-22 23:02:25 +03:00
}
[Test]
public void ValueIsPreservedOnStyleDynResource()
2016-03-22 23:02:25 +03:00
{
var label = new Label();
2016-03-22 23:02:25 +03:00
label.Resources = new ResourceDictionary {
{"foo", "Foo"},
{"bar", "Bar"}
};
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
label.SetDynamicResource(Label.TextProperty, "bar", true);
Assert.AreEqual("Foo", label.Text);
2016-03-22 23:02:25 +03:00
}
[Test]
public void BindingIsPreservedOnStyleDynResource()
2016-03-22 23:02:25 +03:00
{
var label = new Label();
2016-03-22 23:02:25 +03:00
label.Resources = new ResourceDictionary {
{"foo", "Foo"},
{"bar", "Bar"}
};
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
label.SetDynamicResource(Label.TextProperty, "bar", true);
Assert.AreEqual("Foo", label.Text);
2016-03-22 23:02:25 +03:00
}
[Test]
public void DynResourceIsPreservedOnStyleDynResource()
2016-03-22 23:02:25 +03:00
{
var label = new Label();
2016-03-22 23:02:25 +03:00
label.Resources = new ResourceDictionary {
{"foo", "Foo"},
{"bar", "Bar"}
};
label.BindingContext = new { foo = "Foo", bar = "Bar" };
label.SetDynamicResource(Label.TextProperty, "foo");
2016-03-22 23:02:25 +03:00
Assert.AreEqual("Foo", label.Text);
2016-03-22 23:02:25 +03:00
label.SetDynamicResource(Label.TextProperty, "bar", true);
Assert.AreEqual("Foo", label.Text);
2016-03-22 23:02:25 +03:00
}
[Test]
public void StyleValueIsOverridenByStyleValue()
2016-03-22 23:02:25 +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
label.SetValue(Label.TextProperty, "Bar", true);
Assert.AreEqual("Bar", label.Text);
2016-03-22 23:02:25 +03:00
}
[Test]
public void StyleBindingIsOverridenByStyleValue()
2016-03-22 23:02:25 +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
label.SetValue(Label.TextProperty, "Bar", true);
Assert.AreEqual("Bar", label.Text);
2016-03-22 23:02:25 +03:00
}
[Test]
public void StyleDynResourceIsOverridenByStyleValue()
2016-03-22 23:02:25 +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"}
};
Assert.AreEqual("Foo", label.Text);
2016-03-22 23:02:25 +03:00
label.SetValue(Label.TextProperty, "Bar", true);
Assert.AreEqual("Bar", label.Text);
2016-03-22 23:02:25 +03:00
}
[Test]
public void StyleValueIsOverridenByStyleBinding()
2016-03-22 23:02:25 +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
label.SetBinding(Label.TextProperty, new Binding("bar"), true);
Assert.AreEqual("Bar", label.Text);
2016-03-22 23:02:25 +03:00
}
[Test]
public void StyleBindingIsOverridenByStyleBinding()
2016-03-22 23:02:25 +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
label.SetBinding(Label.TextProperty, new Binding("bar"), true);
Assert.AreEqual("Bar", label.Text);
2016-03-22 23:02:25 +03:00
}
[Test]
public void StyleDynResourceIsOverridenByStyleBinding()
2016-03-22 23:02:25 +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"},
};
Assert.AreEqual("Foo", label.Text);
2016-03-22 23:02:25 +03:00
label.SetBinding(Label.TextProperty, new Binding("bar"), true);
Assert.AreEqual("Bar", label.Text);
2016-03-22 23:02:25 +03:00
}
[Test]
public void StyleValueIsOverridenByStyleDynResource()
2016-03-22 23:02:25 +03:00
{
var label = new Label();
2016-03-22 23:02:25 +03:00
label.Resources = new ResourceDictionary {
{"foo", "Foo"},
{"bar", "Bar"}
};
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
label.SetDynamicResource(Label.TextProperty, "bar", true);
Assert.AreEqual("Bar", label.Text);
2016-03-22 23:02:25 +03:00
}
[Test]
public void StyleBindingIsOverridenByStyleDynResource()
2016-03-22 23:02:25 +03:00
{
var label = new Label();
2016-03-22 23:02:25 +03:00
label.Resources = new ResourceDictionary {
{"foo", "Foo"},
{"bar", "Bar"}
};
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
label.SetDynamicResource(Label.TextProperty, "bar", true);
Assert.AreEqual("Bar", label.Text);
2016-03-22 23:02:25 +03:00
}
[Test]
public void StyleDynResourceIsOverridenByStyleDynResource()
2016-03-22 23:02:25 +03:00
{
var label = new Label();
2016-03-22 23:02:25 +03:00
label.Resources = new ResourceDictionary {
{"foo", "Foo"},
{"bar", "Bar"}
};
label.BindingContext = new { foo = "Foo", bar = "Bar" };
label.SetDynamicResource(Label.TextProperty, "foo", true);
2016-03-22 23:02:25 +03:00
Assert.AreEqual("Foo", label.Text);
2016-03-22 23:02:25 +03:00
label.SetDynamicResource(Label.TextProperty, "bar", true);
Assert.AreEqual("Bar", label.Text);
2016-03-22 23:02:25 +03:00
}
[Test]
public void SetValueCoreImplicitelyCastBasicType()
2016-03-22 23:02:25 +03:00
{
var prop = BindableProperty.Create("Foo", typeof(int), typeof(MockBindable), 0);
var bindable = new MockBindable();
2016-03-22 23:02:25 +03:00
Assert.DoesNotThrow(() => bindable.SetValue(prop, (object)(short)42));
Assert.AreEqual(42, bindable.GetValue(prop));
2016-03-22 23:02:25 +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; }
public static implicit operator CastFromString(string source)
2016-03-22 23:02:25 +03:00
{
var o = new CastFromString();
2016-03-22 23:02:25 +03:00
o.Result = source;
return o;
}
}
[Test]
public void SetValueCoreInvokesOpImplicitOnPropertyType()
2016-03-22 23:02:25 +03:00
{
var prop = BindableProperty.Create("Foo", typeof(CastFromString), typeof(MockBindable), null);
var bindable = new MockBindable();
2016-03-22 23:02:25 +03:00
Assert.Null(bindable.GetValue(prop));
bindable.SetValue(prop, "foo");
2016-03-22 23:02:25 +03:00
Assert.AreEqual("foo", ((CastFromString)bindable.GetValue(prop)).Result);
2016-03-22 23:02:25 +03:00
}
class CastToString
{
string Result { get; set; }
public CastToString(string result)
2016-03-22 23:02:25 +03:00
{
Result = result;
}
public static implicit operator string(CastToString source)
2016-03-22 23:02:25 +03:00
{
return source.Result;
}
public override string ToString()
2016-03-22 23:02:25 +03:00
{
throw new InvalidOperationException();
2016-03-22 23:02:25 +03:00
}
}
[Test]
public void SetValueCoreInvokesOpImplicitOnValue()
2016-03-22 23:02:25 +03:00
{
var prop = BindableProperty.Create("Foo", typeof(string), typeof(MockBindable), null);
var bindable = new MockBindable();
2016-03-22 23:02:25 +03:00
Assert.Null(bindable.GetValue(prop));
bindable.SetValue(prop, new CastToString("foo"));
2016-03-22 23:02:25 +03:00
Assert.AreEqual("foo", bindable.GetValue(prop));
2016-03-22 23:02:25 +03:00
}
[Test]
public void DefaultValueCreatorCalledForChangeDelegates()
2016-03-22 23:02:25 +03:00
{
int changedOld = -1;
int changedNew = -1;
int changingOld = -1;
int changingNew = -1;
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
});
var bindable = new MockBindable();
2016-03-22 23:02:25 +03:00
var defaultValue = (int)bindable.GetValue(prop);
2016-03-22 23:02:25 +03:00
Assert.AreEqual(10, defaultValue);
2016-03-22 23:02:25 +03:00
bindable.SetValue(prop, 5);
2016-03-22 23:02:25 +03:00
bindable.ClearValue(prop);
2016-03-22 23:02:25 +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()
{
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
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()
{
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
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
{
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" };
}
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";
bindable.SetBinding(BindableObject.BindingContextProperty, new Binding(".", converter: new BindingContextConverter()));
bindable.SetBinding(MockBindable.TextProperty, "Text");
2016-03-22 23:02:25 +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;
public object VM
{
get
{
2016-03-22 23:02:25 +03:00
Count++;
var eh = Invoked;
if (eh != null)
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
public void BindingOnBindingContextDoesntReapplyBindingContextBinding()
2016-03-22 23:02:25 +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]
//https://github.com/xamarin/Xamarin.Forms/issues/2019
public void EventSubscribingOnBindingContextChanged()
{
var source = new MockBindable();
var bindable = new MockBindable();
var property = BindableProperty.Create("foo", typeof(string), typeof(MockBindable), null);
bindable.SetBinding(property, new Binding("BindingContext", source: source));
Assert.That((string)bindable.GetValue(property), Is.EqualTo(null));
BindableObject.SetInheritedBindingContext(source, "bar"); //inherited BC, only trigger BCChanged
Assert.That((string)bindable.GetValue(property), Is.EqualTo("bar"));
}
2016-03-22 23:02:25 +03:00
[Test]
public void BindingsEditableAfterUnapplied()
{
var bindable = new MockBindable();
var binding = new Binding(".");
bindable.SetBinding(MockBindable.TextProperty, binding);
2016-03-22 23:02:25 +03:00
bindable.BindingContext = "foo";
Assume.That(bindable.Text, Is.EqualTo(bindable.BindingContext));
2016-03-22 23:02:25 +03:00
bindable.RemoveBinding(MockBindable.TextProperty);
2016-03-22 23:02:25 +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();
var binding = new Binding(".");
bindable.SetBinding(MockBindable.TextProperty, binding);
2016-03-22 23:02:25 +03:00
bindable.BindingContext = "foo";
Assume.That(bindable.Text, Is.EqualTo(bindable.BindingContext));
2016-03-22 23:02:25 +03:00
bindable.BindingContext = null;
Assume.That(bindable.Text, Is.EqualTo(bindable.BindingContext));
2016-03-22 23:02:25 +03:00
bindable.BindingContext = "bar";
Assume.That(bindable.Text, Is.EqualTo(bindable.BindingContext));
2016-03-22 23:02:25 +03:00
bindable.RemoveBinding(MockBindable.TextProperty);
2016-03-22 23:02:25 +03:00
Assert.That(() => binding.Path = "Foo", Throws.Nothing);
2016-03-22 23:02:25 +03:00
}
class InfoToString
{
public override string ToString() => "converted";
}
[Test]
//https://github.com/xamarin/Xamarin.Forms/issues/6281
public void SetValueToTextInvokesToString()
{
var prop = BindableProperty.Create("foo", typeof(string), typeof(MockBindable), null);
var bindable = new MockBindable();
bindable.SetValue(prop, new InfoToString());
Assert.That(bindable.GetValue(prop), Is.EqualTo("converted"));
}
[Test]
//https://github.com/xamarin/Xamarin.Forms/issues/6281
public void SetBindingToTextInvokesToString()
{
var prop = BindableProperty.Create("foo", typeof(string), typeof(MockBindable), null);
var bindable = new MockBindable() { BindingContext = new { info = new InfoToString() } };
bindable.SetBinding(prop, "info");
Assert.That(bindable.GetValue(prop), Is.EqualTo("converted"));
}
2016-03-22 23:02:25 +03:00
}
}