Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/xamarin/Xamarin.PropertyEditing.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'Xamarin.PropertyEditing.Tests')
-rw-r--r--Xamarin.PropertyEditing.Tests/AddValueConverterViewModelTests.cs3
-rw-r--r--Xamarin.PropertyEditing.Tests/CreateBindingViewModelTests.cs709
-rw-r--r--Xamarin.PropertyEditing.Tests/CreateResourceViewModelTests.cs3
-rw-r--r--Xamarin.PropertyEditing.Tests/MockBindingEditor.cs66
-rw-r--r--Xamarin.PropertyEditing.Tests/MockBindingProvider.cs123
-rw-r--r--Xamarin.PropertyEditing.Tests/MockControls/MockControl.cs2
-rw-r--r--Xamarin.PropertyEditing.Tests/MockControls/MockResourceProvider.cs26
-rw-r--r--Xamarin.PropertyEditing.Tests/MockControls/MockSampleControl.cs4
-rw-r--r--Xamarin.PropertyEditing.Tests/MockEditorProvider.cs46
-rw-r--r--Xamarin.PropertyEditing.Tests/MockObjectEditor.cs33
-rw-r--r--Xamarin.PropertyEditing.Tests/MockValueConverter.cs12
-rw-r--r--Xamarin.PropertyEditing.Tests/PropertiesViewModelTests.cs1
-rw-r--r--Xamarin.PropertyEditing.Tests/Xamarin.PropertyEditing.Tests.csproj4
13 files changed, 1013 insertions, 19 deletions
diff --git a/Xamarin.PropertyEditing.Tests/AddValueConverterViewModelTests.cs b/Xamarin.PropertyEditing.Tests/AddValueConverterViewModelTests.cs
index 61be5c5..c323cc2 100644
--- a/Xamarin.PropertyEditing.Tests/AddValueConverterViewModelTests.cs
+++ b/Xamarin.PropertyEditing.Tests/AddValueConverterViewModelTests.cs
@@ -1,12 +1,9 @@
-using System;
using System.Collections.Generic;
using System.Linq;
-using System.Text;
using System.Threading;
using System.Threading.Tasks;
using Moq;
using NUnit.Framework;
-using NUnit.Framework.Internal;
using Xamarin.PropertyEditing.ViewModels;
namespace Xamarin.PropertyEditing.Tests
diff --git a/Xamarin.PropertyEditing.Tests/CreateBindingViewModelTests.cs b/Xamarin.PropertyEditing.Tests/CreateBindingViewModelTests.cs
new file mode 100644
index 0000000..2cf707b
--- /dev/null
+++ b/Xamarin.PropertyEditing.Tests/CreateBindingViewModelTests.cs
@@ -0,0 +1,709 @@
+using System;
+using System.Collections.Generic;
+using System.Collections.ObjectModel;
+using System.Collections.Specialized;
+using System.Linq;
+using System.Reflection;
+using System.Text;
+using System.Threading;
+using System.Threading.Tasks;
+using Moq;
+using NUnit.Framework;
+using Xamarin.PropertyEditing.Drawing;
+using Xamarin.PropertyEditing.Reflection;
+using Xamarin.PropertyEditing.Tests.MockControls;
+using Xamarin.PropertyEditing.ViewModels;
+
+namespace Xamarin.PropertyEditing.Tests
+{
+ [TestFixture]
+ internal class CreateBindingViewModelTests
+ {
+ [SetUp]
+ public void Setup ()
+ {
+ AppDomain.CurrentDomain.UnhandledException += CurrentDomainOnUnhandledException;
+ this.syncContext = new AsyncSynchronizationContext ();
+ SynchronizationContext.SetSynchronizationContext (this.syncContext);
+ }
+
+ private Exception unhandled;
+
+ private void CurrentDomainOnUnhandledException (object sender, UnhandledExceptionEventArgs e)
+ {
+ this.unhandled = e.ExceptionObject as Exception;
+ }
+
+ [TearDown]
+ public void TearDown ()
+ {
+ this.syncContext.WaitForPendingOperationsToComplete ();
+ SynchronizationContext.SetSynchronizationContext (null);
+
+ AppDomain.CurrentDomain.UnhandledException -= CurrentDomainOnUnhandledException;
+
+ if (this.unhandled != null) {
+ var ex = this.unhandled;
+ this.unhandled = null;
+ Assert.Fail ("Unhandled exception: {0}", ex);
+ }
+ }
+
+ [Test]
+ public void PropertyDisplayType ()
+ {
+ var target = new object();
+
+ const string propName = "propertyName";
+ var property = GetBasicProperty (propName);
+
+ var editor = new Mock<IObjectEditor> ();
+ editor.SetupGet (e => e.Properties).Returns (new[] { property.Object });
+ editor.SetupGet (e => e.Target).Returns (target);
+ editor.SetupGet (e => e.TargetType).Returns (typeof(object).ToTypeInfo ());
+
+ var editorProvider = new MockEditorProvider (editor.Object);
+
+ var bpmock = new Mock<IBindingProvider> ();
+
+ var vm = new CreateBindingViewModel (new TargetPlatform (editorProvider, bpmock.Object), editor.Object, property.Object);
+ Assert.That (vm.PropertyDisplay, Contains.Substring ("Object"));
+ Assert.That (vm.PropertyDisplay, Contains.Substring (propName));
+ }
+
+ [Test]
+ public void PropertyDisplayNameable ()
+ {
+ var target = new object ();
+ const string propName = "propertyName";
+ var property = GetBasicProperty (propName);
+ var editor = GetBasicEditor (target, property.Object);
+
+ const string objName = "objName";
+ var nameable = editor.As<INameableObject> ();
+ nameable.Setup (n => n.GetNameAsync ()).ReturnsAsync (objName);
+
+ var editorProvider = new MockEditorProvider (editor.Object);
+
+ var bpmock = new Mock<IBindingProvider> ();
+
+ var vm = new CreateBindingViewModel (new TargetPlatform (editorProvider, bpmock.Object), editor.Object, property.Object);
+ Assert.That (vm.PropertyDisplay, Does.Not.Contains ("Object"));
+ Assert.That (vm.PropertyDisplay, Contains.Substring (objName));
+ Assert.That (vm.PropertyDisplay, Contains.Substring (propName));
+ }
+
+ [Test]
+ public async Task BindingSources ()
+ {
+ var target = new object ();
+ var property = GetBasicProperty ();
+ var editor = GetBasicEditor (target, property.Object);
+
+ var editorProvider = new MockEditorProvider (editor.Object);
+
+ var sources = new[] {
+ new BindingSource ("Short Description", BindingSourceType.Object, "Short Description"),
+ new BindingSource ("Long Description", BindingSourceType.Object, "Long Description"),
+ };
+
+ var bpmock = new Mock<IBindingProvider> ();
+ bpmock.Setup (bp => bp.GetBindingSourcesAsync (target, property.Object)).ReturnsAsync (sources);
+ bpmock.Setup (bp => bp.GetRootElementsAsync (sources[0], target)).ReturnsAsync (new[] { new object (), new object () });
+ bpmock.Setup (bp => bp.GetRootElementsAsync (sources[1], target)).ReturnsAsync (new[] { new object () });
+ bpmock.Setup (bp => bp.GetValueConverterResourcesAsync (It.IsAny<object> ())).ReturnsAsync (new Resource[0]);
+
+ var vm = new CreateBindingViewModel (new TargetPlatform (editorProvider, bpmock.Object), editor.Object, property.Object);
+
+ Assert.That (vm.BindingSources, Is.Not.Null);
+
+ var requested = await vm.BindingSources.Task;
+ CollectionAssert.AreEqual (sources, requested);
+
+ Assert.That (vm.SelectedBindingSource, Is.EqualTo (sources[0]));
+ }
+
+ [Test]
+ public async Task BindingSourceObjectRoots ()
+ {
+ var target = new object ();
+ var property = GetBasicProperty ();
+ var editor = GetBasicEditor (target, property.Object);
+
+ var editorProvider = new MockEditorProvider (editor.Object);
+
+ var sources = new[] {
+ new BindingSource ("Short Description", BindingSourceType.Object, "Short Description"),
+ new BindingSource ("Long Description", BindingSourceType.Object, "Long Description"),
+ };
+
+ var shortRoots = new[] { new object (), new object () };
+
+ var bpmock = new Mock<IBindingProvider> ();
+ bpmock.Setup (bp => bp.GetBindingSourcesAsync (target, property.Object)).ReturnsAsync (sources);
+ bpmock.Setup (bp => bp.GetRootElementsAsync (sources[0], target)).ReturnsAsync (shortRoots);
+ bpmock.Setup (bp => bp.GetRootElementsAsync (sources[1], target)).ReturnsAsync (new[] { new object () });
+ bpmock.Setup (bp => bp.GetValueConverterResourcesAsync (It.IsAny<object> ())).ReturnsAsync (new Resource[0]);
+
+ var vm = new CreateBindingViewModel (new TargetPlatform (editorProvider, bpmock.Object), editor.Object, property.Object);
+ await vm.BindingSources.Task;
+ Assume.That (vm.SelectedBindingSource, Is.EqualTo (sources[0]));
+
+ bpmock.Verify (bp => bp.GetRootElementsAsync (sources[0], target));
+ IReadOnlyList<ObjectTreeElement> roots = await vm.ObjectElementRoots.Task;
+ Assert.That (roots.Count, Is.EqualTo (2), "Unexpected number of roots");
+ CollectionAssert.AreEqual (roots.Select (r => r.Editor.Target), shortRoots);
+ }
+
+ [Test]
+ [Description ("If the source has a description, we're on object type source and it's the only one, use a long description")]
+ public async Task ShowLongDescription ()
+ {
+ var sources = new[] {
+ new BindingSource ("Short Description", BindingSourceType.Object, "Short Description"),
+ new BindingSource ("Long Description", BindingSourceType.SingleObject, "Long Description"),
+ };
+ var vm = CreateBasicViewModel (sources: sources);
+ await vm.BindingSources.Task;
+
+ Assume.That (vm.SelectedBindingSource, Is.EqualTo (sources[0]));
+ Assume.That (vm.ShowObjectSelector, Is.True, "Object selector should be showing");
+ Assert.That (vm.ShowLongDescription, Is.False);
+
+ vm.SelectedBindingSource = sources[1];
+ await vm.ObjectElementRoots.Task;
+ Assert.That (vm.ShowLongDescription, Is.True);
+ Assert.That (vm.ShowObjectSelector, Is.False);
+ }
+
+ [Test]
+ public async Task ValueConverters ()
+ {
+ var target = new object ();
+
+ var property = GetBasicProperty ();
+ var editor = GetBasicEditor (target, property.Object);
+
+ const string objName = "objName";
+ var nameable = editor.As<INameableObject> ();
+ nameable.Setup (n => n.GetNameAsync ()).ReturnsAsync (objName);
+
+ var editorProvider = new MockEditorProvider (editor.Object);
+
+ var sources = new[] {
+ new BindingSource ("Short Description", BindingSourceType.Object, "Short Description"),
+ new BindingSource ("Long Description", BindingSourceType.Object, "Long Description"),
+ };
+
+ var visi = new Resource ("BooleanToVisibilityConverter");
+
+ var bpmock = new Mock<IBindingProvider> ();
+ bpmock.Setup (bp => bp.GetBindingSourcesAsync (target, property.Object)).ReturnsAsync (sources);
+ bpmock.Setup (bp => bp.GetRootElementsAsync (sources[0], target)).ReturnsAsync (new[] { new object (), new object () });
+ bpmock.Setup (bp => bp.GetRootElementsAsync (sources[1], target)).ReturnsAsync (new[] { new object () });
+ bpmock.Setup (bp => bp.GetValueConverterResourcesAsync (It.IsAny<object> ())).ReturnsAsync (new [] { visi });
+
+ var vm = new CreateBindingViewModel (new TargetPlatform (editorProvider, bpmock.Object), editor.Object, property.Object);
+ Assert.That (vm.ValueConverters, Is.Not.Null);
+
+ await vm.ValueConverters.Task;
+ Assert.That (vm.ValueConverters.Value, Contains.Item (visi));
+ Assert.That (vm.ValueConverters.Value.Count, Is.EqualTo (3)); // visi, No Converter, Request Converter
+ }
+
+ [Test]
+ public async Task RequestValueConverter ()
+ {
+ var target = new object();
+
+ var vm = CreateBasicViewModel (target: target);
+ Assume.That (vm.ValueConverters, Is.Not.Null);
+
+ await vm.ValueConverters.Task;
+
+ Assume.That (vm.SelectedValueConverter, Is.EqualTo (vm.ValueConverters.Value[0]));
+ Assume.That (vm.ValueConverters.Value.Count, Is.EqualTo (2));
+
+ const string name = "NewConverter";
+ bool requested = false;
+ vm.CreateValueConverterRequested += (o, e) => {
+ e.ConverterType = typeof(object).ToTypeInfo ();
+ e.Name = name;
+ e.Source = MockResourceProvider.ApplicationResourcesSource;
+ requested = true;
+ };
+
+ Assume.That (vm.ValueConverters.Value, Is.InstanceOf (typeof(INotifyCollectionChanged)));
+
+ object newItem = null;
+ ((INotifyCollectionChanged) vm.ValueConverters.Value).CollectionChanged += (o, e) => {
+ if (e.Action == NotifyCollectionChangedAction.Add && e.NewItems.Count == 1) {
+ newItem = e.NewItems[0];
+ Assert.That (e.NewStartingIndex, Is.EqualTo (1), "New converter was not added below none and above request");
+ }
+ };
+
+ int selectedChanged = 0;
+ vm.PropertyChanged += (o, e) => {
+ if (e.PropertyName == nameof(CreateBindingViewModel.SelectedValueConverter))
+ selectedChanged++;
+ };
+
+ vm.SelectedValueConverter = vm.ValueConverters.Value[1];
+
+ Assert.That (requested, Is.True);
+ Assert.That (selectedChanged, Is.EqualTo (2), "SelectedValueConverter did not fire INPC for request and result changes");
+ Assert.That (newItem, Is.Not.Null);
+ Assert.That (vm.SelectedValueConverter, Is.EqualTo (newItem));
+ }
+
+ [Test]
+ public async Task RequestValueConverterCanceled ()
+ {
+ var vm = CreateBasicViewModel ();
+ Assume.That (vm.ValueConverters, Is.Not.Null);
+
+ await vm.ValueConverters.Task;
+
+ Assume.That (vm.SelectedValueConverter, Is.EqualTo (vm.ValueConverters.Value[0]));
+ Assume.That (vm.ValueConverters.Value.Count, Is.EqualTo (2));
+
+ bool requested = false;
+ vm.CreateValueConverterRequested += (o, e) => {
+ requested = true;
+ };
+
+ vm.SelectedValueConverter = vm.ValueConverters.Value[1];
+
+ Assert.That (requested, Is.True);
+ Assert.That (vm.SelectedValueConverter, Is.EqualTo (vm.ValueConverters.Value[0]),
+ "SelectedValueConverter wasn't set back to No Converter after canceled request");
+ }
+
+ [Test]
+ public async Task PropertyRoot ()
+ {
+ var target = new object ();
+
+ var property = new Mock<IPropertyInfo> ();
+ property.SetupGet (p => p.ValueSources).Returns (ValueSources.Local | ValueSources.Binding);
+ property.SetupGet (p => p.Type).Returns (typeof (object));
+ property.SetupGet (p => p.Name).Returns ("name");
+ property.SetupGet (p => p.RealType).Returns (typeof (object).ToTypeInfo ());
+ property.SetupGet (p => p.CanWrite).Returns (true);
+
+ var editor = GetBasicEditor (target, property.Object);
+
+ var controlTarget = new MockWpfControl ();
+ var controlEditor = new MockObjectEditor (controlTarget);
+ var provider = new MockEditorProvider (controlEditor);
+
+ var source = new BindingSource ("Control", BindingSourceType.Object);
+ var bpmock = new Mock<IBindingProvider> ();
+ bpmock.Setup (bp => bp.GetBindingSourcesAsync (target, property.Object)).ReturnsAsync (new[] { source });
+ bpmock.Setup (bp => bp.GetRootElementsAsync (source, target)).ReturnsAsync (new[] { controlTarget });
+ bpmock.Setup (bp => bp.GetValueConverterResourcesAsync (It.IsAny<object> ())).ReturnsAsync (new Resource[0]);
+
+ var vm = new CreateBindingViewModel (new TargetPlatform (provider, bpmock.Object), editor.Object, property.Object);
+ Assume.That (vm.SelectedBindingSource, Is.EqualTo (source));
+
+ Assert.That (vm.PropertyRoot, Is.Not.Null);
+ await vm.PropertyRoot.Task;
+
+ var targetType = typeof(MockWpfControl).ToTypeInfo ();
+ Assert.That (vm.PropertyRoot.Value.TargetType, Is.EqualTo (targetType));
+ CollectionAssert.AreEqual (controlEditor.Properties, vm.PropertyRoot.Value.Children.Select (te => te.Property));
+ }
+
+ [Test]
+ public async Task PropertyRootChildren ()
+ {
+ var target = new object();
+
+ var property = new Mock<IPropertyInfo> ();
+ property.SetupGet (p => p.ValueSources).Returns (ValueSources.Local | ValueSources.Binding);
+ property.SetupGet (p => p.Type).Returns (typeof (object));
+ property.SetupGet (p => p.Name).Returns ("name");
+ property.SetupGet (p => p.RealType).Returns (typeof (object).ToTypeInfo ());
+ property.SetupGet (p => p.CanWrite).Returns (true);
+
+ var editor = GetBasicEditor (target, property.Object);
+
+ var controlTarget = new MockWpfControl();
+ var controlEditor = new MockObjectEditor (controlTarget);
+ var provider = new MockEditorProvider (controlEditor);
+
+ var source = new BindingSource ("Control", BindingSourceType.Object);
+ var bpmock = new Mock<IBindingProvider> ();
+ bpmock.Setup (bp => bp.GetBindingSourcesAsync (target, property.Object)).ReturnsAsync (new[] { source });
+ bpmock.Setup (bp => bp.GetRootElementsAsync (source, target)).ReturnsAsync (new[] { controlTarget });
+ bpmock.Setup (bp => bp.GetValueConverterResourcesAsync (It.IsAny<object> ())).ReturnsAsync (new Resource[0]);
+
+ var vm = new CreateBindingViewModel (new TargetPlatform (provider, bpmock.Object), editor.Object, property.Object);
+ Assume.That (vm.SelectedBindingSource, Is.EqualTo (source));
+ Assume.That (vm.PropertyRoot, Is.Not.Null);
+ await vm.PropertyRoot.Task;
+
+ var childrenProperty = controlEditor.Properties.First (p => p.Type == typeof(CommonThickness));
+ var element = vm.PropertyRoot.Value.Children.First (p => Equals (p.Property, childrenProperty));
+
+ Assert.That (element.Children, Is.Not.Null);
+
+ await element.Children.Task;
+ var expected = await provider.GetPropertiesForTypeAsync (typeof(CommonThickness).ToTypeInfo ());
+ CollectionAssert.AreEqual (expected, element.Children.Value.Select (te => te.Property));
+ }
+
+ [Test]
+ public async Task Path ()
+ {
+ var target = new object ();
+
+ var property = new Mock<IPropertyInfo> ();
+ property.SetupGet (p => p.ValueSources).Returns (ValueSources.Local | ValueSources.Binding);
+ property.SetupGet (p => p.Type).Returns (typeof (object));
+ property.SetupGet (p => p.Name).Returns ("name");
+ property.SetupGet (p => p.RealType).Returns (typeof (object).ToTypeInfo ());
+ property.SetupGet (p => p.CanWrite).Returns (true);
+
+ var editor = GetBasicEditor (target, property.Object);
+
+ var controlTarget = new MockWpfControl ();
+ var controlEditor = new MockObjectEditor (controlTarget);
+ var provider = new MockEditorProvider (controlEditor);
+
+ var source = new BindingSource ("Control", BindingSourceType.Object);
+ var bpmock = new Mock<IBindingProvider> ();
+ bpmock.Setup (bp => bp.GetBindingSourcesAsync (target, property.Object)).ReturnsAsync (new[] { source });
+ bpmock.Setup (bp => bp.GetRootElementsAsync (source, target)).ReturnsAsync (new[] { controlTarget });
+ bpmock.Setup (bp => bp.GetValueConverterResourcesAsync (It.IsAny<object> ())).ReturnsAsync (new Resource[0]);
+
+ var vm = new CreateBindingViewModel (new TargetPlatform (provider, bpmock.Object), editor.Object, property.Object);
+ Assume.That (vm.SelectedBindingSource, Is.EqualTo (source));
+ Assume.That (vm.PropertyRoot, Is.Not.Null);
+ await vm.PropertyRoot.Task;
+
+ var element = vm.PropertyRoot.Value.Children.First (p => p.Property.Type == typeof(CommonThickness));
+ await element.Children.Task;
+ var sub = element.Children.Value.First ();
+ vm.SelectedPropertyElement = sub;
+
+ Assert.That (vm.Path, Is.EqualTo ($"{element.Property.Name}.{sub.Property.Name}"));
+ }
+
+ [Test]
+ public async Task SelectedBindingSource ()
+ {
+ BindingSource[] sources = new[] {
+ new BindingSource ("First", BindingSourceType.Object),
+ new BindingSource ("Second", BindingSourceType.Resource),
+ new BindingSource ("Third", BindingSourceType.Type),
+ };
+
+ var vm = CreateBasicViewModel (sources);
+
+ while (vm.SelectedObjects.Count == 0) {
+ await Task.Delay (1);
+ }
+
+ var binding = (MockBinding)vm.SelectedObjects.First ();
+
+ Assert.That (vm.SelectedBindingSource, Is.EqualTo (sources[0]));
+ Assert.That (binding.Source, Is.EqualTo (sources[0]), "Backing binding object property didn't update");
+
+ bool propertyChanged = false, objectRootsChanged = false, resourceRootsChanged = false, typeRootsChanged = false;
+ vm.PropertyChanged += (o, e) => {
+ if (e.PropertyName == nameof(CreateBindingViewModel.SelectedBindingSource))
+ propertyChanged = true;
+ else if (e.PropertyName == nameof(CreateBindingViewModel.ObjectElementRoots))
+ objectRootsChanged = true;
+ else if (e.PropertyName == nameof(CreateBindingViewModel.SourceResources))
+ resourceRootsChanged = true;
+ else if (e.PropertyName == nameof(CreateBindingViewModel.TypeSelector))
+ typeRootsChanged = true;
+ };
+
+ vm.SelectedBindingSource = sources[1];
+ Assert.That (propertyChanged, Is.True, "INPC did not fire for SelectedBindingSource");
+ Assert.That (binding.Source, Is.EqualTo (sources[1]), "Backing binding object property didn't update");
+ Assert.That (resourceRootsChanged, Is.True, "SourceResources did not update when selected");
+ Assert.That (vm.SourceResources, Is.Not.Null);
+ Assert.That (objectRootsChanged, Is.False);
+ Assert.That (typeRootsChanged, Is.False);
+
+ propertyChanged = objectRootsChanged = resourceRootsChanged = typeRootsChanged = false;
+ vm.SelectedBindingSource = sources[2];
+ Assert.That (propertyChanged, Is.True, "INPC did not fire for SelectedBindingSource");
+ Assert.That (binding.Source, Is.EqualTo (sources[2]), "Backing binding object property didn't update");
+ Assert.That (resourceRootsChanged, Is.False);
+ Assert.That (objectRootsChanged, Is.False);
+ Assert.That (typeRootsChanged, Is.True, "TypeSelector didn't update when selected");
+ Assert.That (vm.TypeSelector, Is.Not.Null);
+
+ propertyChanged = objectRootsChanged = resourceRootsChanged = typeRootsChanged = false;
+ vm.SelectedBindingSource = sources[0];
+ Assert.That (propertyChanged, Is.True, "INPC did not fire for SelectedBindingSource");
+ Assert.That (binding.Source, Is.EqualTo (sources[0]), "Backing binding object property didn't update");
+ Assert.That (resourceRootsChanged, Is.False);
+ Assert.That (objectRootsChanged, Is.True, "ObjectElementRoots didn't update when selected");
+ Assert.That (vm.ObjectElementRoots, Is.Not.Null);
+ Assert.That (typeRootsChanged, Is.False);
+ }
+
+ [Test]
+ public async Task ShowSourceParameterSelectors ()
+ {
+ BindingSource[] sources = new[] {
+ new BindingSource ("First", BindingSourceType.Object),
+ new BindingSource ("Second", BindingSourceType.Resource),
+ new BindingSource ("Third", BindingSourceType.Type),
+ };
+
+ var vm = CreateBasicViewModel (sources);
+
+ while (vm.SelectedObjects.Count == 0) {
+ await Task.Delay (1);
+ }
+
+ Assume.That (vm.SelectedBindingSource, Is.EqualTo (sources[0]));
+
+ bool objectChanged = false, resourceChanged = false, typeChanged = false;
+ vm.PropertyChanged += (o, e) => {
+ if (e.PropertyName == nameof (CreateBindingViewModel.ShowObjectSelector))
+ objectChanged = true;
+ else if (e.PropertyName == nameof (CreateBindingViewModel.ShowResourceSelector))
+ resourceChanged = true;
+ else if (e.PropertyName == nameof (CreateBindingViewModel.ShowTypeSelector))
+ typeChanged = true;
+ };
+
+ vm.SelectedBindingSource = sources[1];
+ Assert.That (resourceChanged, Is.True);
+ Assert.That (vm.ShowResourceSelector, Is.True);
+ Assert.That (objectChanged, Is.True, "Did not signal old selector changed");
+ Assert.That (vm.ShowObjectSelector, Is.False);
+ Assert.That (vm.ShowTypeSelector, Is.False);
+
+ objectChanged = resourceChanged = typeChanged = false;
+ vm.SelectedBindingSource = sources[2];
+ Assert.That (resourceChanged, Is.True);
+ Assert.That (vm.ShowResourceSelector, Is.False);
+ Assert.That (objectChanged, Is.True, "Did not signal old selector changed");
+ Assert.That (vm.ShowObjectSelector, Is.False);
+ Assert.That (vm.ShowTypeSelector, Is.True);
+
+ objectChanged = resourceChanged = typeChanged = false;
+ vm.SelectedBindingSource = sources[0];
+ Assert.That (vm.ShowResourceSelector, Is.False);
+ Assert.That (objectChanged, Is.True);
+ Assert.That (vm.ShowObjectSelector, Is.True);
+ Assert.That (typeChanged, Is.True, "Did not signal old selector changed");
+ Assert.That (vm.ShowTypeSelector, Is.False);
+ }
+
+ [Test]
+ public async Task ResourceRoots ()
+ {
+ object target = new object();
+ var property = GetBasicProperty ();
+ var editor = GetBasicEditor (target, property.Object);
+ var resources = new MockResourceProvider ();
+ var bindings = GetBasicBindingProvider (target, property.Object);
+ var source = new BindingSource ("Resources", BindingSourceType.Resource);
+ bindings.Setup (bp => bp.GetBindingSourcesAsync (target, property.Object)).ReturnsAsync (new[] { source });
+ bindings.Setup (bp => bp.GetResourcesAsync (source, target))
+ .Returns<BindingSource,object> (async (bs, t) => {
+ var rs = await resources.GetResourcesAsync (target, CancellationToken.None);
+ return rs.ToLookup (r => r.Source);
+ });
+
+ var vm = new CreateBindingViewModel (
+ new TargetPlatform (new MockEditorProvider (editor.Object), resources, bindings.Object), editor.Object,
+ property.Object);
+
+ Assume.That (vm.SelectedBindingSource, Is.EqualTo (source));
+
+ Assert.That (vm.SourceResources, Is.Not.Null);
+ await vm.SourceResources.Task;
+ Assert.That (vm.SourceResources.Value.First().Key, Is.EqualTo (DefaultResourceSources[0]));
+ }
+
+ [Test]
+ public async Task ResourceProperties ()
+ {
+ object target = new object ();
+ var property = GetBasicProperty ();
+ var editor = GetBasicEditor (target, property.Object);
+ var resources = new MockResourceProvider ();
+ var source = new BindingSource ("Resources", BindingSourceType.Resource);
+ var bindings = GetBasicBindingProvider (target, property.Object, sources: new [] { source });
+ bindings.Setup (bp => bp.GetResourcesAsync (source, target))
+ .Returns<BindingSource, object> (async (bs, t) => {
+ var rs = await resources.GetResourcesAsync (target, CancellationToken.None);
+ return rs.ToLookup (r => r.Source);
+ });
+
+ var vm = new CreateBindingViewModel (
+ new TargetPlatform (new MockEditorProvider (editor.Object), resources, bindings.Object), editor.Object,
+ property.Object);
+
+ Assume.That (vm.SelectedBindingSource, Is.EqualTo (source));
+ Assume.That (vm.SourceResources, Is.Not.Null);
+ await vm.SourceResources.Task;
+
+ while (vm.SelectedObjects.Count == 0) {
+ await Task.Delay (1);
+ }
+
+ var binding = (MockBinding)vm.SelectedObjects.First();
+ vm.SelectedResource = vm.SourceResources.Value.First ().OfType<Resource<CommonSolidBrush>>().First ();
+ Assert.That (binding.SourceParameter, Is.EqualTo (vm.SelectedResource));
+ Assume.That (vm.PropertyRoot, Is.Not.Null);
+ await vm.PropertyRoot.Task;
+
+ Assert.That (vm.PropertyRoot.Value.TargetType, Is.EqualTo (typeof(CommonSolidBrush).ToTypeInfo ()));
+ CollectionAssert.AreEqual (ReflectionEditorProvider.GetPropertiesForType (typeof(CommonSolidBrush)),
+ vm.PropertyRoot.Value.Children.Select (pe => pe.Property));
+ }
+
+ [Test]
+ public async Task Types ()
+ {
+ object target = new object ();
+ var property = GetBasicProperty ();
+ var editor = GetBasicEditor (target, property.Object);
+ var resources = new MockResourceProvider ();
+ var source = new BindingSource ("Resources", BindingSourceType.Type);
+
+ var type = typeof(MockSampleControl).ToTypeInfo ();
+ var bindings = GetBasicBindingProvider (target, property.Object, sources: new[] { source });
+ bindings.Setup (bp => bp.GetSourceTypesAsync (source, target))
+ .ReturnsAsync (new AssignableTypesResult (new[] { type }));
+
+ var provider = new MockEditorProvider (editor.Object);
+ var vm = new CreateBindingViewModel (new TargetPlatform (provider, resources, bindings.Object), editor.Object, property.Object);
+
+ Assume.That (vm.SelectedBindingSource, Is.EqualTo (source));
+ Assume.That (vm.TypeSelector, Is.Not.Null);
+
+ while (vm.SelectedObjects.Count == 0 && vm.TypeSelector.IsLoading) {
+ await Task.Delay (1);
+ }
+
+ var binding = (MockBinding) vm.SelectedObjects.First ();
+
+ Assert.That (vm.TypeSelector.SelectedType, Is.Null);
+
+ bool propertyChanged = false;
+ vm.PropertyChanged += (o, e) => {
+ if (e.PropertyName == nameof(CreateBindingViewModel.PropertyRoot))
+ propertyChanged = true;
+ };
+
+ vm.TypeSelector.SelectedType = type;
+ Assert.That (propertyChanged, Is.True, "INPC didn't change for PropertyRoot on selected source param");
+ Assert.That (vm.PropertyRoot, Is.Not.Null);
+ Assert.That (binding.SourceParameter, Is.EqualTo (type));
+
+ await vm.PropertyRoot.Task;
+ CollectionAssert.AreEqual (provider.GetPropertiesForTypeAsync (type).Result,
+ vm.PropertyRoot.Value.Children.Select (pe => pe.Property));
+ }
+
+ [Test]
+ public async Task ExtraProperties ()
+ {
+ var provider = new MockEditorProvider();
+ var vm = CreateBasicViewModel ();
+
+ var editors = (IList<IObjectEditor>)typeof(CreateBindingViewModel).GetProperty ("ObjectEditors", BindingFlags.NonPublic | BindingFlags.Instance)
+ .GetValue (vm); // Shortcut
+ var editor = editors[0];
+
+ IEnumerable<IPropertyInfo> properties = (await provider.GetPropertiesForTypeAsync (typeof(MockBinding).ToTypeInfo ()));
+ CollectionAssert.AreEqual (properties, vm.Properties.Cast<PropertyViewModel> ().Select (pvm => pvm.Property));
+
+ properties = properties.Where (p => !editor.KnownProperties.ContainsKey (p));
+ CollectionAssert.AreEqual (properties.Where (p => p.Type == typeof(bool)),
+ vm.FlagsProperties.Cast<PropertyViewModel> ().Select (pvm => pvm.Property));
+ CollectionAssert.AreEqual (properties.Where (p => p.Type != typeof (bool)),
+ vm.BindingProperties.Cast<PropertyViewModel> ().Select (pvm => pvm.Property));
+ }
+
+ private AsyncSynchronizationContext syncContext;
+ private static readonly ResourceSource[] DefaultResourceSources = new[] { MockResourceProvider.SystemResourcesSource, MockResourceProvider.ApplicationResourcesSource };
+
+ private Mock<IPropertyInfo> GetBasicProperty (string name = "propertyName")
+ {
+ var property = new Mock<IPropertyInfo> ();
+ property.SetupGet (p => p.ValueSources).Returns (ValueSources.Local | ValueSources.Binding);
+ property.SetupGet (p => p.Type).Returns (typeof (string));
+ property.SetupGet (p => p.Name).Returns (name);
+ property.SetupGet (p => p.RealType).Returns (typeof (string).ToTypeInfo ());
+ property.SetupGet (p => p.CanWrite).Returns (true);
+
+ return property;
+ }
+
+ private Mock<IObjectEditor> GetBasicEditor (object target, IPropertyInfo property)
+ {
+ var editor = new Mock<IObjectEditor> ();
+ editor.SetupGet (e => e.Properties).Returns (new[] { property });
+ editor.SetupGet (e => e.Target).Returns (target);
+ editor.SetupGet (e => e.TargetType).Returns (typeof (object).ToTypeInfo ());
+
+ return editor;
+ }
+
+ private Mock<IResourceProvider> GetBasicResourceProvider (object target, ResourceSource[] sources = null)
+ {
+ sources = sources ?? DefaultResourceSources;
+
+ var resources = new Mock<IResourceProvider> ();
+ resources.Setup (r => r.GetResourceSourcesAsync (target)).ReturnsAsync (sources);
+ resources.Setup (r => r.CreateResourceAsync (It.IsAny<ResourceSource> (), It.IsAny<string> (), It.IsAny<object> ()))
+ .ReturnsAsync ((Func<ResourceSource, string, object, Resource>) ((s, n, v) => new Resource (s, n)));
+ return resources;
+ }
+
+ private Mock<IBindingProvider> GetBasicBindingProvider (object target, IPropertyInfo property, BindingSource[] sources = null)
+ {
+ var bpmock = new Mock<IBindingProvider> ();
+
+ if (sources == null) {
+ sources = new[] {
+ new BindingSource ("Short Description", BindingSourceType.Object, "Short Description"),
+ new BindingSource ("Long Description", BindingSourceType.SingleObject, "Long Description"),
+ };
+
+ bpmock.Setup (bp => bp.GetRootElementsAsync (sources[0], target)).ReturnsAsync (new[] { new object (), new object () });
+ bpmock.Setup (bp => bp.GetRootElementsAsync (sources[1], target)).ReturnsAsync (new[] { new object () });
+ } else {
+ for (int i = 0; i < sources.Length; i++) {
+ int index = i;
+ if (sources[i].Type == BindingSourceType.SingleObject)
+ bpmock.Setup (bp => bp.GetRootElementsAsync (sources[index], target)).ReturnsAsync (new[] { new object () });
+ else
+ bpmock.Setup (bp => bp.GetRootElementsAsync (sources[index], target)).ReturnsAsync (new[] { new object (), new object() });
+ }
+ }
+
+ bpmock.Setup (bp => bp.GetBindingSourcesAsync (target, property)).ReturnsAsync (sources);
+ bpmock.Setup (bp => bp.GetValueConverterResourcesAsync (It.IsAny<object> ())).ReturnsAsync (new Resource[0]);
+ return bpmock;
+ }
+
+ private CreateBindingViewModel CreateBasicViewModel (BindingSource[] sources = null, object target = null)
+ {
+ target = target ?? new object ();
+ Mock<IPropertyInfo> property = GetBasicProperty ();
+ Mock<IObjectEditor> editor = GetBasicEditor (target, property.Object);
+
+ var editorProvider = new MockEditorProvider (editor.Object);
+ Mock<IResourceProvider> resourceProvider = GetBasicResourceProvider (target);
+ Mock<IBindingProvider> bpmock = GetBasicBindingProvider (target, property.Object, sources);
+
+ return new CreateBindingViewModel (new TargetPlatform (editorProvider, resourceProvider.Object, bpmock.Object), editor.Object, property.Object);
+ }
+ }
+} \ No newline at end of file
diff --git a/Xamarin.PropertyEditing.Tests/CreateResourceViewModelTests.cs b/Xamarin.PropertyEditing.Tests/CreateResourceViewModelTests.cs
index c3c4192..fd70270 100644
--- a/Xamarin.PropertyEditing.Tests/CreateResourceViewModelTests.cs
+++ b/Xamarin.PropertyEditing.Tests/CreateResourceViewModelTests.cs
@@ -1,9 +1,6 @@
using System;
using System.Collections.Generic;
-<<<<<<< HEAD
using System.Linq;
-=======
->>>>>>> [Core/Win] Create resource core/window
using System.Threading;
using System.Threading.Tasks;
using Moq;
diff --git a/Xamarin.PropertyEditing.Tests/MockBindingEditor.cs b/Xamarin.PropertyEditing.Tests/MockBindingEditor.cs
new file mode 100644
index 0000000..45ab099
--- /dev/null
+++ b/Xamarin.PropertyEditing.Tests/MockBindingEditor.cs
@@ -0,0 +1,66 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Threading.Tasks;
+using Xamarin.PropertyEditing.Reflection;
+
+namespace Xamarin.PropertyEditing.Tests
+{
+ internal class MockBindingEditor
+ : IObjectEditor
+ {
+ public MockBindingEditor (MockBinding binding)
+ {
+ Target = binding;
+ this.editor = new ReflectionObjectEditor (binding);
+ this.editor.PropertyChanged += (sender, args) => {
+ PropertyChanged?.Invoke (this, args);
+ };
+
+ KnownProperties = new Dictionary<IPropertyInfo, KnownProperty> {
+ { this.editor.Properties.Single (pi => pi.Name == nameof(MockBinding.Source)), PropertyBinding.SourceProperty },
+ { this.editor.Properties.Single (pi => pi.Name == nameof(MockBinding.SourceParameter)), PropertyBinding.SourceParameterProperty },
+ { this.editor.Properties.Single (pi => pi.Name == nameof(MockBinding.Path)), PropertyBinding.PathProperty },
+ { this.editor.Properties.Single (pi => pi.Name == nameof(MockBinding.Converter)), PropertyBinding.ConverterProperty },
+ { this.editor.Properties.Single (pi => pi.Name == nameof(MockBinding.TypeLevel)), PropertyBinding.TypeLevelProperty }
+ };
+ }
+
+ public event EventHandler<EditorPropertyChangedEventArgs> PropertyChanged;
+
+ public object Target
+ {
+ get;
+ }
+
+ public ITypeInfo TargetType => this.editor.TargetType;
+
+ public IReadOnlyCollection<IPropertyInfo> Properties => this.editor.Properties;
+
+ public IReadOnlyDictionary<IPropertyInfo, KnownProperty> KnownProperties
+ {
+ get;
+ }
+
+ public IObjectEditor Parent => null;
+
+ public IReadOnlyList<IObjectEditor> DirectChildren => null;
+
+ public Task<AssignableTypesResult> GetAssignableTypesAsync (IPropertyInfo property, bool childTypes)
+ {
+ return this.editor.GetAssignableTypesAsync (property, childTypes);
+ }
+
+ public Task SetValueAsync<T> (IPropertyInfo property, ValueInfo<T> value, PropertyVariation variation = null)
+ {
+ return this.editor.SetValueAsync (property, value, variation);
+ }
+
+ public Task<ValueInfo<T>> GetValueAsync<T> (IPropertyInfo property, PropertyVariation variation = null)
+ {
+ return this.editor.GetValueAsync<T> (property, variation);
+ }
+
+ private readonly ReflectionObjectEditor editor;
+ }
+} \ No newline at end of file
diff --git a/Xamarin.PropertyEditing.Tests/MockBindingProvider.cs b/Xamarin.PropertyEditing.Tests/MockBindingProvider.cs
new file mode 100644
index 0000000..8077ed4
--- /dev/null
+++ b/Xamarin.PropertyEditing.Tests/MockBindingProvider.cs
@@ -0,0 +1,123 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Threading;
+using System.Threading.Tasks;
+using Xamarin.PropertyEditing.Reflection;
+using Xamarin.PropertyEditing.Tests.MockControls;
+
+namespace Xamarin.PropertyEditing.Tests
+{
+ public class MockBindingProvider
+ : IBindingProvider
+ {
+ public Task<IReadOnlyList<BindingSource>> GetBindingSourcesAsync (object target, IPropertyInfo property)
+ {
+ return Task.FromResult<IReadOnlyList<BindingSource>> (new[] {
+ new BindingSourceInstance (RelativeSelf, $"Bind [{target.GetType().Name}] to itself."),
+ StaticResource,
+ Ancestor
+ });
+ }
+
+ public Task<AssignableTypesResult> GetSourceTypesAsync (BindingSource source, object target)
+ {
+ return ReflectionObjectEditor.GetAssignableTypes (typeof(MockControl).ToTypeInfo (), childTypes: false);
+ }
+
+ public Task<IReadOnlyList<object>> GetRootElementsAsync (BindingSource source, object target)
+ {
+ if (source == null)
+ throw new ArgumentNullException (nameof(source));
+ if (source.Type != BindingSourceType.Object && source.Type != BindingSourceType.SingleObject)
+ throw new ArgumentException ("source.Type was not Object", nameof(source));
+
+ if (source is BindingSourceInstance instance)
+ source = instance.Original;
+
+ if (source == RelativeSelf)
+ return Task.FromResult<IReadOnlyList<object>> (new [] { target });
+ if (source == StaticResource)
+ return MockResourceProvider.GetResourceSourcesAsync (target).ContinueWith (t => (IReadOnlyList<object>) t.Result);
+
+ throw new NotImplementedException();
+ }
+
+ public async Task<ILookup<ResourceSource, Resource>> GetResourcesAsync (BindingSource source, object target)
+ {
+ var results = await this.resources.GetResourcesAsync (target, CancellationToken.None).ConfigureAwait (false);
+ return results.ToLookup (r => r.Source);
+ }
+
+ public Task<IReadOnlyList<Resource>> GetValueConverterResourcesAsync (object target)
+ {
+ return Task.FromResult<IReadOnlyList<Resource>> (Array.Empty<Resource> ());
+ }
+
+ private readonly MockResourceProvider resources = new MockResourceProvider();
+
+ private static readonly BindingSource Ancestor = new BindingSource ("RelativeSource FindAncestor", BindingSourceType.Type);
+ private static readonly BindingSource RelativeSelf = new BindingSource ("RelativeSource Self", BindingSourceType.SingleObject);
+ private static readonly BindingSource StaticResource = new BindingSource ("StaticResource", BindingSourceType.Resource);
+
+ private class BindingSourceInstance
+ : BindingSource
+ {
+ public BindingSourceInstance (BindingSource original, string description)
+ : base (original.Name, original.Type, description)
+ {
+ Original = original;
+ }
+
+ public BindingSource Original
+ {
+ get;
+ }
+ }
+ }
+
+ public class MockBinding
+ {
+ public string Path
+ {
+ get;
+ set;
+ }
+
+ public BindingSource Source
+ {
+ get;
+ set;
+ }
+
+ public object SourceParameter
+ {
+ get;
+ set;
+ }
+
+ public Resource Converter
+ {
+ get;
+ set;
+ }
+
+ public string StringFormat
+ {
+ get;
+ set;
+ }
+
+ public bool IsAsync
+ {
+ get;
+ set;
+ }
+
+ public int TypeLevel
+ {
+ get;
+ set;
+ }
+ }
+} \ No newline at end of file
diff --git a/Xamarin.PropertyEditing.Tests/MockControls/MockControl.cs b/Xamarin.PropertyEditing.Tests/MockControls/MockControl.cs
index dbc30a6..b7685ba 100644
--- a/Xamarin.PropertyEditing.Tests/MockControls/MockControl.cs
+++ b/Xamarin.PropertyEditing.Tests/MockControls/MockControl.cs
@@ -14,7 +14,7 @@ namespace Xamarin.PropertyEditing.Tests.MockControls
public void AddProperty<T> (string name, string category = null,
bool canWrite = true, bool flag = false,
IEnumerable<Type> converterTypes = null,
- string description = null, ValueSources valueSources = ValueSources.Local | ValueSources.Default)
+ string description = null, ValueSources valueSources = ValueSources.Local | ValueSources.Default | ValueSources.Binding)
{
IPropertyInfo propertyInfo;
if (typeof(T).IsEnum) {
diff --git a/Xamarin.PropertyEditing.Tests/MockControls/MockResourceProvider.cs b/Xamarin.PropertyEditing.Tests/MockControls/MockResourceProvider.cs
index cadded8..8d5e458 100644
--- a/Xamarin.PropertyEditing.Tests/MockControls/MockResourceProvider.cs
+++ b/Xamarin.PropertyEditing.Tests/MockControls/MockResourceProvider.cs
@@ -45,6 +45,13 @@ namespace Xamarin.PropertyEditing.Tests
return Task.FromResult<Resource> (r);
}
+ public Task<IReadOnlyList<Resource>> GetResourcesAsync (object target, CancellationToken cancelToken)
+ {
+ return Task.FromResult<IReadOnlyList<Resource>> (this.resources.SelectMany (g => g)
+ .Where (r => !(r.Source is ObjectResourceSource ors) || ReferenceEquals (target, ors.Target))
+ .ToList ());
+ }
+
public Task<IReadOnlyList<Resource>> GetResourcesAsync (object target, IPropertyInfo property, CancellationToken cancelToken)
{
return Task.FromResult<IReadOnlyList<Resource>> (this.resources.SelectMany (g => g)
@@ -52,8 +59,18 @@ namespace Xamarin.PropertyEditing.Tests
.ToList());
}
+ Task<IReadOnlyList<ResourceSource>> IResourceProvider.GetResourceSourcesAsync (object target)
+ {
+ return MockResourceProvider.GetResourceSourcesAsync (target);
+ }
+
public Task<IReadOnlyList<ResourceSource>> GetResourceSourcesAsync (object target, IPropertyInfo property)
{
+ return GetResourceSourcesAsync (target);
+ }
+
+ public static Task<IReadOnlyList<ResourceSource>> GetResourceSourcesAsync (object target)
+ {
return Task.FromResult<IReadOnlyList<ResourceSource>> (new[] { SystemResourcesSource, ApplicationResourcesSource, Resources, Window, new ObjectResourceSource (target, target.GetType ().Name, ResourceSourceType.Document) });
}
@@ -118,6 +135,15 @@ namespace Xamarin.PropertyEditing.Tests
new Resource<CommonSolidBrush> (SystemResourcesSource, "ControlTextBrush", new CommonSolidBrush (0, 0, 0)),
new Resource<CommonSolidBrush> (SystemResourcesSource, "HighlightBrush", new CommonSolidBrush (51, 153, 255)),
new Resource<CommonSolidBrush> (SystemResourcesSource, "TransparentBrush", new CommonSolidBrush (0, 0, 0, 0)),
+ new Resource<CommonSolidBrush> (SystemResourcesSource, "ATextBrush", new CommonSolidBrush (0, 0, 0)),
+ new Resource<CommonSolidBrush> (SystemResourcesSource, "ATransparentBrush", new CommonSolidBrush (51, 153, 255)),
+ new Resource<CommonSolidBrush> (SystemResourcesSource, "AHighlightBrush", new CommonSolidBrush (0, 0, 0, 0)),
+ new Resource<CommonSolidBrush> (SystemResourcesSource, "BTextBrush", new CommonSolidBrush (0, 0, 0)),
+ new Resource<CommonSolidBrush> (SystemResourcesSource, "BHighlightBrush", new CommonSolidBrush (51, 153, 255)),
+ new Resource<CommonSolidBrush> (SystemResourcesSource, "BTransparentBrush", new CommonSolidBrush (0, 0, 0, 0)),
+ new Resource<CommonSolidBrush> (SystemResourcesSource, "CTextBrush", new CommonSolidBrush (0, 0, 0)),
+ new Resource<CommonSolidBrush> (SystemResourcesSource, "CHighlightBrush", new CommonSolidBrush (51, 153, 255)),
+ new Resource<CommonSolidBrush> (SystemResourcesSource, "CTransparentBrush", new CommonSolidBrush (0, 0, 0, 0)),
new Resource<CommonColor> (SystemResourcesSource, "ControlTextColor", new CommonColor (0, 0, 0)),
new Resource<CommonColor> (SystemResourcesSource, "HighlightColor", new CommonColor (51, 153, 255))
},
diff --git a/Xamarin.PropertyEditing.Tests/MockControls/MockSampleControl.cs b/Xamarin.PropertyEditing.Tests/MockControls/MockSampleControl.cs
index 1f41595..3d8acde 100644
--- a/Xamarin.PropertyEditing.Tests/MockControls/MockSampleControl.cs
+++ b/Xamarin.PropertyEditing.Tests/MockControls/MockSampleControl.cs
@@ -8,12 +8,12 @@ namespace Xamarin.PropertyEditing.Tests.MockControls
{
public MockSampleControl()
{
- AddProperty<bool> ("Boolean", ReadWrite);
+ AddProperty<bool> ("Boolean", ReadWrite, valueSources: ValueSources.Local | ValueSources.Resource | ValueSources.Binding);
AddProperty<bool> ("UnsetBoolean", ReadWrite, valueSources: ValueSources.Local);
AddProperty<int> ("Integer", ReadWrite);
AddProperty<int> ("UnsetInteger", ReadWrite, valueSources: ValueSources.Local);
AddProperty<float> ("FloatingPoint", ReadWrite);
- AddProperty<string> ("String", ReadWrite);
+ AddProperty<string> ("String", ReadWrite, valueSources: ValueSources.Local | ValueSources.Resource | ValueSources.Binding);
AddProperty<Enumeration> ("Enumeration", ReadWrite);
AddProperty<FlagsNoValues> ("FlagsNoValues", ReadWrite, canWrite: true, flag: true);
AddProperty<FlagsWithValues> ("FlagsWithValues", ReadWrite, canWrite: true, flag: true);
diff --git a/Xamarin.PropertyEditing.Tests/MockEditorProvider.cs b/Xamarin.PropertyEditing.Tests/MockEditorProvider.cs
index e2ca470..2225bca 100644
--- a/Xamarin.PropertyEditing.Tests/MockEditorProvider.cs
+++ b/Xamarin.PropertyEditing.Tests/MockEditorProvider.cs
@@ -1,6 +1,8 @@
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
+using Xamarin.PropertyEditing.Common;
+using Xamarin.PropertyEditing.Drawing;
using Xamarin.PropertyEditing.Reflection;
using Xamarin.PropertyEditing.Tests.MockControls;
@@ -11,6 +13,26 @@ namespace Xamarin.PropertyEditing.Tests
{
public static readonly TargetPlatform MockPlatform = new TargetPlatform (new MockEditorProvider ());
+ public MockEditorProvider ()
+ {
+ }
+
+ public MockEditorProvider (IObjectEditor editor)
+ {
+ this.editorCache.Add (editor.Target, editor);
+ }
+
+ public IReadOnlyDictionary<Type, ITypeInfo> KnownTypes
+ {
+ get;
+ } = new Dictionary<Type, ITypeInfo> {
+ { typeof(PropertyBinding), typeof(MockBinding).ToTypeInfo() },
+ { typeof(CommonValueConverter), typeof(MockValueConverter).ToTypeInfo() },
+ { typeof(CommonBrush), typeof(CommonBrush).ToTypeInfo() },
+ { typeof(CommonSolidBrush), typeof(CommonSolidBrush).ToTypeInfo() },
+ { typeof(CommonColor), typeof(CommonColor).ToTypeInfo() }
+ };
+
public Task<IObjectEditor> GetObjectEditorAsync (object item)
{
if (this.editorCache.TryGetValue (item, out IObjectEditor cachedEditor)) {
@@ -23,9 +45,25 @@ namespace Xamarin.PropertyEditing.Tests
public async Task<IReadOnlyCollection<IPropertyInfo>> GetPropertiesForTypeAsync (ITypeInfo type)
{
- object obj = await CreateObjectAsync (type).ConfigureAwait (false);
- IObjectEditor editor = ChooseEditor (obj);
- return editor.Properties;
+ Type realType = ReflectionEditorProvider.GetRealType (type);
+ if (realType == null)
+ return Array.Empty<IPropertyInfo> ();
+
+ if (typeof(MockControl).IsAssignableFrom (realType)) {
+ object item = await CreateObjectAsync (type);
+ IObjectEditor editor = ChooseEditor (item);
+ return editor.Properties;
+ }
+
+ return ReflectionEditorProvider.GetPropertiesForType (realType);
+ }
+
+ public Task<AssignableTypesResult> GetAssignableTypesAsync (ITypeInfo type, bool childTypes)
+ {
+ if (type == KnownTypes[typeof(CommonValueConverter)])
+ return Task.FromResult (new AssignableTypesResult (new[] { type }));
+
+ return ReflectionObjectEditor.GetAssignableTypes (type, childTypes);
}
IObjectEditor ChooseEditor (object item)
@@ -35,6 +73,8 @@ namespace Xamarin.PropertyEditing.Tests
return new MockObjectEditor (msc);
case MockControl mc:
return new MockNameableEditor (mc);
+ case MockBinding mb:
+ return new MockBindingEditor (mb);
default:
return new ReflectionObjectEditor (item);
}
diff --git a/Xamarin.PropertyEditing.Tests/MockObjectEditor.cs b/Xamarin.PropertyEditing.Tests/MockObjectEditor.cs
index aa193df..8da782c 100644
--- a/Xamarin.PropertyEditing.Tests/MockObjectEditor.cs
+++ b/Xamarin.PropertyEditing.Tests/MockObjectEditor.cs
@@ -144,12 +144,14 @@ namespace Xamarin.PropertyEditing.Tests
public Task<AssignableTypesResult> GetAssignableTypesAsync (IPropertyInfo property, bool childTypes)
{
- if (this.assignableTypes == null) {
- return ReflectionObjectEditor.GetAssignableTypes (property, childTypes);
- } else if (!this.assignableTypes.TryGetValue (property, out IReadOnlyList<ITypeInfo> types))
- return Task.FromResult (new AssignableTypesResult (Enumerable.Empty<ITypeInfo> ().ToArray ()));
- else
- return Task.FromResult (new AssignableTypesResult (types));
+ if (this.assignableTypes != null) {
+ if (!this.assignableTypes.TryGetValue (property, out IReadOnlyList<ITypeInfo> types))
+ return Task.FromResult (new AssignableTypesResult (Enumerable.Empty<ITypeInfo> ().ToArray ()));
+ else
+ return Task.FromResult (new AssignableTypesResult (types));
+ }
+
+ return ReflectionObjectEditor.GetAssignableTypes (property.RealType, childTypes);
}
#pragma warning disable CS1998 // Async method lacks 'await' operators and will run synchronously
@@ -310,6 +312,25 @@ namespace Xamarin.PropertyEditing.Tests
Value = default(T)
};
}
+
+ public Task<ITypeInfo> GetValueTypeAsync (IPropertyInfo property, PropertyVariation variation = null)
+ {
+ if (variation != null)
+ throw new NotImplementedException();
+
+ Type type = property.Type;
+ if (this.values.TryGetValue (property, out object value)) {
+ Type valueType = value.GetType ();
+ if (valueType.IsConstructedGenericType && valueType.GetGenericTypeDefinition () == typeof(ValueInfo<>)) {
+ value = valueType.GetProperty ("Value").GetValue (value);
+ type = value.GetType ();
+ } else
+ type = valueType;
+ }
+
+ var asm = new AssemblyInfo (type.Assembly.FullName, true);
+ return Task.FromResult<ITypeInfo> (new TypeInfo (asm, type.Namespace, type.Name));
+ }
#pragma warning restore CS1998
internal readonly IDictionary<IPropertyInfo, object> values = new Dictionary<IPropertyInfo, object> ();
diff --git a/Xamarin.PropertyEditing.Tests/MockValueConverter.cs b/Xamarin.PropertyEditing.Tests/MockValueConverter.cs
new file mode 100644
index 0000000..65d2bf9
--- /dev/null
+++ b/Xamarin.PropertyEditing.Tests/MockValueConverter.cs
@@ -0,0 +1,12 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace Xamarin.PropertyEditing.Tests
+{
+ internal class MockValueConverter
+ {
+ }
+} \ No newline at end of file
diff --git a/Xamarin.PropertyEditing.Tests/PropertiesViewModelTests.cs b/Xamarin.PropertyEditing.Tests/PropertiesViewModelTests.cs
index 713b3eb..8bd7ae2 100644
--- a/Xamarin.PropertyEditing.Tests/PropertiesViewModelTests.cs
+++ b/Xamarin.PropertyEditing.Tests/PropertiesViewModelTests.cs
@@ -674,7 +674,6 @@ namespace Xamarin.PropertyEditing.Tests
Assert.That (property.Editors.Count, Is.EqualTo (1));
}
-
[Test]
public void PropertiesListItemRemoved ()
{
diff --git a/Xamarin.PropertyEditing.Tests/Xamarin.PropertyEditing.Tests.csproj b/Xamarin.PropertyEditing.Tests/Xamarin.PropertyEditing.Tests.csproj
index ddcdd7d..ba02175 100644
--- a/Xamarin.PropertyEditing.Tests/Xamarin.PropertyEditing.Tests.csproj
+++ b/Xamarin.PropertyEditing.Tests/Xamarin.PropertyEditing.Tests.csproj
@@ -65,11 +65,15 @@
<Compile Include="BrushPropertyViewModelTests.cs" />
<Compile Include="BytePropertyViewModelTests.cs" />
<Compile Include="CollectionPropertyViewModelTests.cs" />
+ <Compile Include="CreateBindingViewModelTests.cs" />
<Compile Include="CreateResourceViewModelTests.cs" />
<Compile Include="MaterialDesignColorViewModelTests.cs" />
<Compile Include="CombinablePredefinedViewModelTests.cs" />
+ <Compile Include="MockBindingEditor.cs" />
+ <Compile Include="MockBindingProvider.cs" />
<Compile Include="MockControls\MockResourceProvider.cs" />
<Compile Include="MockPropertyInfo\MockBrushPropertyInfo.cs" />
+ <Compile Include="MockValueConverter.cs" />
<Compile Include="NumericTests.cs" />
<Compile Include="NumericViewModelTests.cs" />
<Compile Include="ResourceSelectorViewModelTests.cs" />