[iOS] Add missing null check to `SelectableItemsViewRenderer.SetupNewElement`. (#6057)

* Reproduction

* Automate test

* Handle null element in SetupElement in the SelectableItemsViewRenderer
Fixes #5949

* Add manual test instructions

* Fix build errors
This commit is contained in:
E.Z. Hart 2019-05-06 11:05:29 -06:00 коммит произвёл GitHub
Родитель 23cfdd0e69
Коммит 03266f580a
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 4AEE18F83AFDEB23
9 изменённых файлов: 223 добавлений и 1 удалений

Просмотреть файл

@ -0,0 +1,17 @@
using System.Collections.Generic;
namespace Xamarin.Forms.Controls.Issues
{
internal static class FlagTestHelpers
{
public static void SetTestFlag(string flag)
{
Device.SetFlags(new List<string>(Device.Flags ?? new List<string>()) { flag });
}
public static void SetCollectionViewTestFlag()
{
SetTestFlag("CollectionView_Experimental");
}
}
}

Просмотреть файл

@ -23,7 +23,7 @@ namespace Xamarin.Forms.Controls.Issues
protected override void Init()
{
#if APP
Device.SetFlags(new List<string>(Device.Flags ?? new List<string>()) { "CollectionView_Experimental" });
FlagTestHelpers.SetCollectionViewTestFlag();
PushAsync(new GalleryPages.CollectionViewGalleries.EmptyViewGalleries.EmptyViewSwapGallery());
#endif

Просмотреть файл

@ -0,0 +1,52 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Xamarin.Forms;
using Xamarin.Forms.CustomAttributes;
using Xamarin.Forms.Internals;
#if UITEST
using Xamarin.Forms.Core.UITests;
using Xamarin.UITest;
using NUnit.Framework;
#endif
namespace Xamarin.Forms.Controls.Issues
{
#if UITEST
[Category(UITestCategories.CollectionView)]
#endif
[Preserve(AllMembers = true)]
[Issue(IssueTracker.Github, 5949, "CollectionView cannot access a disposed object.",
PlatformAffected.iOS)]
public class Issue5949 : TestContentPage
{
protected override void Init()
{
FlagTestHelpers.SetCollectionViewTestFlag();
Appearing += Issue5949Appearing;
}
private void Issue5949Appearing(object sender, EventArgs e)
{
Application.Current.MainPage = new Issue5949_1();
}
#if UITEST
[Test]
public void DoNotAccessDisposedCollectionView()
{
RunningApp.WaitForElement("Login");
RunningApp.Tap("Login");
RunningApp.WaitForElement(Issue5949_2.BackButton);
RunningApp.Tap(Issue5949_2.BackButton);
RunningApp.WaitForElement("Login");
}
#endif
}
}

Просмотреть файл

@ -0,0 +1,20 @@
<?xml version="1.0" encoding="utf-8" ?>
<MasterDetailPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:local="clr-namespace:Xamarin.Forms.Controls.Issues"
x:Class="Xamarin.Forms.Controls.Issues.Issue5949_1"
Title="Issue 5949">
<MasterDetailPage.Master>
<ContentPage Title="Issue 5949">
<Label Text="Detail"></Label>
</ContentPage>
</MasterDetailPage.Master>
<MasterDetailPage.Detail>
<NavigationPage>
<x:Arguments>
<local:Issue5949_2 />
</x:Arguments>
</NavigationPage>
</MasterDetailPage.Detail>
</MasterDetailPage>

Просмотреть файл

@ -0,0 +1,26 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Xamarin.Forms;
using Xamarin.Forms.Internals;
using Xamarin.Forms.Xaml;
namespace Xamarin.Forms.Controls.Issues
{
#if APP
[XamlCompilation(XamlCompilationOptions.Compile)]
#endif
[Preserve(AllMembers = true)]
public partial class Issue5949_1 : MasterDetailPage
{
public Issue5949_1()
{
#if APP
InitializeComponent();
#endif
}
}
}

Просмотреть файл

@ -0,0 +1,19 @@
<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="Xamarin.Forms.Controls.Issues.Issue5949_2"
Title="Issue 5949">
<StackLayout>
<Label Text="Tap the 'Login' toolbar item. On the next page, tap the 'Back' button. If the application crashes, this test has failed." />
<CollectionView
ItemsSource="{Binding Items}"
VerticalOptions="FillAndExpand" >
<CollectionView.ItemTemplate>
<DataTemplate>
<Label Text="{Binding}"></Label>
</DataTemplate>
</CollectionView.ItemTemplate>
</CollectionView>
</StackLayout>
</ContentPage>

Просмотреть файл

@ -0,0 +1,61 @@
using System;
using System.Collections.Generic;
using Xamarin.Forms.Internals;
using Xamarin.Forms.Xaml;
namespace Xamarin.Forms.Controls.Issues
{
#if APP
[XamlCompilation(XamlCompilationOptions.Compile)]
#endif
[Preserve(AllMembers = true)]
public partial class Issue5949_2 : ContentPage
{
public const string BackButton = "5949GoBack";
public const string ToolBarItem = "Login";
public Issue5949_2()
{
#if APP
InitializeComponent();
ToolbarItems.Add(new ToolbarItem(ToolBarItem, null, () => Navigation.PushAsync(LoginPage())));
BindingContext = new _5949ViewModel();
#endif
}
[Preserve(AllMembers = true)]
class _5949ViewModel
{
public _5949ViewModel()
{
Items = new List<string>
{
"one", "two", "three"
};
}
public List<string> Items { get; set; }
}
ContentPage LoginPage()
{
var page = new ContentPage
{
Title = "Issue 5949"
};
var button = new Button { Text = "Back", AutomationId = BackButton };
button.Clicked += ButtonClicked;
page.Content = button;
return page;
}
private void ButtonClicked(object sender, EventArgs e)
{
Application.Current.MainPage = new Issue5949_1();
}
}
}

Просмотреть файл

@ -12,6 +12,7 @@
<Compile Include="$(MSBuildThisFileDirectory)Helpers\GarbageCollectionHelper.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Issue5555.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Bugzilla59172.cs" />
<Compile Include="$(MSBuildThisFileDirectory)FlagTestHelpers.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Issue4684.xaml.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Issue4915.xaml.cs">
<SubType>Code</SubType>
@ -461,6 +462,15 @@
<SubType>Code</SubType>
</Compile>
<Compile Include="$(MSBuildThisFileDirectory)Issue5535.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Issue5949.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Issue5949_1.xaml.cs">
<DependentUpon>Issue5949_1.xaml</DependentUpon>
<SubType>Code</SubType>
</Compile>
<Compile Include="$(MSBuildThisFileDirectory)Issue5949_2.xaml.cs">
<DependentUpon>Issue5949_2.xaml</DependentUpon>
<SubType>Code</SubType>
</Compile>
<Compile Include="$(MSBuildThisFileDirectory)LegacyComponents\NonAppCompatSwitch.cs" />
<Compile Include="$(MSBuildThisFileDirectory)MapsModalCrash.cs" />
<Compile Include="$(MSBuildThisFileDirectory)ModalActivityIndicatorTest.cs" />
@ -1180,4 +1190,16 @@
<Generator>MSBuild:UpdateDesignTimeXaml</Generator>
</EmbeddedResource>
</ItemGroup>
<ItemGroup>
<EmbeddedResource Include="$(MSBuildThisFileDirectory)Issue5949_1.xaml">
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>
</EmbeddedResource>
</ItemGroup>
<ItemGroup>
<EmbeddedResource Include="$(MSBuildThisFileDirectory)Issue5949_2.xaml">
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>
</EmbeddedResource>
</ItemGroup>
</Project>

Просмотреть файл

@ -36,6 +36,11 @@ namespace Xamarin.Forms.Platform.iOS
base.SetUpNewElement(newElement);
if (newElement == null)
{
return;
}
SelectableItemsViewController.UpdateSelectionMode();
SelectableItemsViewController.UpdateNativeSelection();
}