Browse Source
Using JetBrains' dotMemory Unit testing framework. Currently shows that TreeView does not get freed.pull/346/head
8 changed files with 425 additions and 0 deletions
@ -0,0 +1,106 @@ |
|||
// Copyright (c) The Perspex Project. All rights reserved.
|
|||
// Licensed under the MIT license. See licence.md file in the project root for full license information.
|
|||
|
|||
using System; |
|||
using System.Collections.Generic; |
|||
using System.Linq; |
|||
using JetBrains.dotMemoryUnit; |
|||
using Perspex.Controls; |
|||
using Perspex.Controls.Templates; |
|||
using Xunit; |
|||
using Xunit.Abstractions; |
|||
|
|||
namespace Perspex.LeakTests |
|||
{ |
|||
[DotMemoryUnit(FailIfRunWithoutSupport = false)] |
|||
public class ControlTests |
|||
{ |
|||
public ControlTests(ITestOutputHelper atr) |
|||
{ |
|||
TestApp.Initialize(); |
|||
DotMemoryUnitTestOutput.SetOutputMethod(atr.WriteLine); |
|||
} |
|||
|
|||
[Fact] |
|||
public void Canvas_Is_Freed() |
|||
{ |
|||
Func<Window> run = () => |
|||
{ |
|||
var window = new Window |
|||
{ |
|||
Content = new Canvas() |
|||
}; |
|||
|
|||
// Do a layout and make sure that Canvas gets added to visual tree.
|
|||
window.LayoutManager.ExecuteLayoutPass(); |
|||
Assert.IsType<Canvas>(window.Presenter.Child); |
|||
|
|||
// Clear the content and ensure the Canvas is removed.
|
|||
window.Content = null; |
|||
window.LayoutManager.ExecuteLayoutPass(); |
|||
Assert.Null(window.Presenter.Child); |
|||
|
|||
return window; |
|||
}; |
|||
|
|||
var result = run(); |
|||
|
|||
dotMemory.Check(memory => |
|||
Assert.Equal(0, memory.GetObjects(where => where.Type.Is<Canvas>()).ObjectsCount)); |
|||
} |
|||
|
|||
[Fact] |
|||
public void TreeView_Is_Freed() |
|||
{ |
|||
Func<Window> run = () => |
|||
{ |
|||
var nodes = new[] |
|||
{ |
|||
new Node |
|||
{ |
|||
Children = new[] { new Node() }, |
|||
} |
|||
}; |
|||
|
|||
TreeView target; |
|||
|
|||
var window = new Window |
|||
{ |
|||
Content = target = new TreeView |
|||
{ |
|||
DataTemplates = new DataTemplates |
|||
{ |
|||
new FuncTreeDataTemplate<Node>( |
|||
x => new TextBlock { Text = x.Name }, |
|||
x => x.Children, |
|||
x => true) |
|||
}, |
|||
Items = nodes |
|||
} |
|||
}; |
|||
|
|||
// Do a layout and make sure that TreeViewItems get realized.
|
|||
window.LayoutManager.ExecuteLayoutPass(); |
|||
Assert.Equal(1, target.ItemContainerGenerator.Containers.Count()); |
|||
|
|||
// Clear the content and ensure the TreeView is removed.
|
|||
window.Content = null; |
|||
window.LayoutManager.ExecuteLayoutPass(); |
|||
Assert.Null(window.Presenter.Child); |
|||
|
|||
return window; |
|||
}; |
|||
|
|||
var result = run(); |
|||
|
|||
dotMemory.Check(memory => |
|||
Assert.Equal(0, memory.GetObjects(where => where.Type.Is<TreeView>()).ObjectsCount)); |
|||
} |
|||
|
|||
private class Node |
|||
{ |
|||
public string Name { get; set; } |
|||
public IEnumerable<Node> Children { get; set; } |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,174 @@ |
|||
<?xml version="1.0" encoding="utf-8"?> |
|||
<Project ToolsVersion="14.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> |
|||
<Import Project="..\..\packages\xunit.core.2.0.0\build\portable-net45+win+wpa81+wp80+monotouch+monoandroid+Xamarin.iOS\xunit.core.props" Condition="Exists('..\..\packages\xunit.core.2.0.0\build\portable-net45+win+wpa81+wp80+monotouch+monoandroid+Xamarin.iOS\xunit.core.props')" /> |
|||
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" /> |
|||
<PropertyGroup> |
|||
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration> |
|||
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform> |
|||
<ProjectGuid>{E1AA3DBF-9056-4530-9376-18119A7A3FFE}</ProjectGuid> |
|||
<OutputType>Library</OutputType> |
|||
<AppDesignerFolder>Properties</AppDesignerFolder> |
|||
<RootNamespace>Perspex.LeakTests</RootNamespace> |
|||
<AssemblyName>Perspex.LeakTests</AssemblyName> |
|||
<TargetFrameworkVersion>v4.5</TargetFrameworkVersion> |
|||
<FileAlignment>512</FileAlignment> |
|||
<NuGetPackageImportStamp> |
|||
</NuGetPackageImportStamp> |
|||
<TargetFrameworkProfile /> |
|||
</PropertyGroup> |
|||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' "> |
|||
<DebugSymbols>true</DebugSymbols> |
|||
<DebugType>full</DebugType> |
|||
<Optimize>false</Optimize> |
|||
<OutputPath>bin\Debug\</OutputPath> |
|||
<DefineConstants>DEBUG;TRACE</DefineConstants> |
|||
<ErrorReport>prompt</ErrorReport> |
|||
<WarningLevel>4</WarningLevel> |
|||
</PropertyGroup> |
|||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' "> |
|||
<DebugType>pdbonly</DebugType> |
|||
<Optimize>true</Optimize> |
|||
<OutputPath>bin\Release\</OutputPath> |
|||
<DefineConstants>TRACE</DefineConstants> |
|||
<ErrorReport>prompt</ErrorReport> |
|||
<WarningLevel>4</WarningLevel> |
|||
</PropertyGroup> |
|||
<ItemGroup> |
|||
<Reference Include="dotMemory.Unit, Version=103.0.0.0, Culture=neutral, PublicKeyToken=1010a0d8d6380325, processorArchitecture=MSIL"> |
|||
<HintPath>..\..\packages\JetBrains.dotMemoryUnit.2.1.20150828.125449\lib\dotMemory.Unit.dll</HintPath> |
|||
<Private>True</Private> |
|||
</Reference> |
|||
<Reference Include="Moq, Version=4.2.1507.118, Culture=neutral, PublicKeyToken=69f491c39445e920, processorArchitecture=MSIL"> |
|||
<HintPath>..\..\packages\Moq.4.2.1507.0118\lib\net40\Moq.dll</HintPath> |
|||
<Private>True</Private> |
|||
</Reference> |
|||
<Reference Include="Ploeh.AutoFixture, Version=3.31.3.0, Culture=neutral, PublicKeyToken=b24654c590009d4f, processorArchitecture=MSIL"> |
|||
<HintPath>..\..\packages\AutoFixture.3.31.3\lib\net40\Ploeh.AutoFixture.dll</HintPath> |
|||
<Private>True</Private> |
|||
</Reference> |
|||
<Reference Include="Ploeh.AutoFixture.AutoMoq, Version=3.31.1.0, Culture=neutral, PublicKeyToken=b24654c590009d4f, processorArchitecture=MSIL"> |
|||
<HintPath>..\..\packages\AutoFixture.AutoMoq.3.31.1\lib\net40\Ploeh.AutoFixture.AutoMoq.dll</HintPath> |
|||
<Private>True</Private> |
|||
</Reference> |
|||
<Reference Include="System" /> |
|||
<Reference Include="System.Core" /> |
|||
<Reference Include="System.Reactive.Core, Version=2.2.5.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL"> |
|||
<HintPath>..\..\packages\Rx-Core.2.2.5\lib\net45\System.Reactive.Core.dll</HintPath> |
|||
<Private>True</Private> |
|||
</Reference> |
|||
<Reference Include="System.Reactive.Interfaces, Version=2.2.5.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL"> |
|||
<HintPath>..\..\packages\Rx-Interfaces.2.2.5\lib\net45\System.Reactive.Interfaces.dll</HintPath> |
|||
<Private>True</Private> |
|||
</Reference> |
|||
<Reference Include="System.Reactive.Linq, Version=2.2.5.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL"> |
|||
<HintPath>..\..\packages\Rx-Linq.2.2.5\lib\net45\System.Reactive.Linq.dll</HintPath> |
|||
<Private>True</Private> |
|||
</Reference> |
|||
<Reference Include="System.Reactive.PlatformServices, Version=2.2.5.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL"> |
|||
<HintPath>..\..\packages\Rx-PlatformServices.2.2.5\lib\net45\System.Reactive.PlatformServices.dll</HintPath> |
|||
<Private>True</Private> |
|||
</Reference> |
|||
<Reference Include="System.Xml.Linq" /> |
|||
<Reference Include="System.Data.DataSetExtensions" /> |
|||
<Reference Include="Microsoft.CSharp" /> |
|||
<Reference Include="System.Data" /> |
|||
<Reference Include="System.Net.Http" /> |
|||
<Reference Include="System.Xml" /> |
|||
<Reference Include="xunit.abstractions, Version=2.0.0.0, Culture=neutral, PublicKeyToken=8d05b1bb7a6fdb6c, processorArchitecture=MSIL"> |
|||
<HintPath>..\..\packages\xunit.abstractions.2.0.0\lib\net35\xunit.abstractions.dll</HintPath> |
|||
<Private>True</Private> |
|||
</Reference> |
|||
<Reference Include="xunit.assert, Version=2.0.0.2929, Culture=neutral, PublicKeyToken=8d05b1bb7a6fdb6c, processorArchitecture=MSIL"> |
|||
<HintPath>..\..\packages\xunit.assert.2.0.0\lib\portable-net45+win+wpa81+wp80+monotouch+monoandroid+Xamarin.iOS\xunit.assert.dll</HintPath> |
|||
<Private>True</Private> |
|||
</Reference> |
|||
<Reference Include="xunit.core, Version=2.0.0.2929, Culture=neutral, PublicKeyToken=8d05b1bb7a6fdb6c, processorArchitecture=MSIL"> |
|||
<HintPath>..\..\packages\xunit.extensibility.core.2.0.0\lib\portable-net45+win+wpa81+wp80+monotouch+monoandroid+Xamarin.iOS\xunit.core.dll</HintPath> |
|||
<Private>True</Private> |
|||
</Reference> |
|||
</ItemGroup> |
|||
<ItemGroup> |
|||
<Compile Include="ControlTests.cs" /> |
|||
<Compile Include="Properties\AssemblyInfo.cs" /> |
|||
<Compile Include="TestApp.cs" /> |
|||
</ItemGroup> |
|||
<ItemGroup> |
|||
<None Include="app.config" /> |
|||
<None Include="packages.config" /> |
|||
</ItemGroup> |
|||
<ItemGroup> |
|||
<ProjectReference Include="..\..\src\Markup\Perspex.Markup.Xaml\Perspex.Markup.Xaml.csproj"> |
|||
<Project>{3e53a01a-b331-47f3-b828-4a5717e77a24}</Project> |
|||
<Name>Perspex.Markup.Xaml</Name> |
|||
</ProjectReference> |
|||
<ProjectReference Include="..\..\src\Markup\Perspex.Markup\Perspex.Markup.csproj"> |
|||
<Project>{6417e941-21bc-467b-a771-0de389353ce6}</Project> |
|||
<Name>Perspex.Markup</Name> |
|||
</ProjectReference> |
|||
<ProjectReference Include="..\..\src\Perspex.Animation\Perspex.Animation.csproj"> |
|||
<Project>{d211e587-d8bc-45b9-95a4-f297c8fa5200}</Project> |
|||
<Name>Perspex.Animation</Name> |
|||
</ProjectReference> |
|||
<ProjectReference Include="..\..\src\Perspex.Application\Perspex.Application.csproj"> |
|||
<Project>{799a7bb5-3c2c-48b6-85a7-406a12c420da}</Project> |
|||
<Name>Perspex.Application</Name> |
|||
</ProjectReference> |
|||
<ProjectReference Include="..\..\src\Perspex.Base\Perspex.Base.csproj"> |
|||
<Project>{b09b78d8-9b26-48b0-9149-d64a2f120f3f}</Project> |
|||
<Name>Perspex.Base</Name> |
|||
</ProjectReference> |
|||
<ProjectReference Include="..\..\src\Perspex.Controls\Perspex.Controls.csproj"> |
|||
<Project>{d2221c82-4a25-4583-9b43-d791e3f6820c}</Project> |
|||
<Name>Perspex.Controls</Name> |
|||
</ProjectReference> |
|||
<ProjectReference Include="..\..\src\Perspex.Input\Perspex.Input.csproj"> |
|||
<Project>{62024b2d-53eb-4638-b26b-85eeaa54866e}</Project> |
|||
<Name>Perspex.Input</Name> |
|||
</ProjectReference> |
|||
<ProjectReference Include="..\..\src\Perspex.Interactivity\Perspex.Interactivity.csproj"> |
|||
<Project>{6b0ed19d-a08b-461c-a9d9-a9ee40b0c06b}</Project> |
|||
<Name>Perspex.Interactivity</Name> |
|||
</ProjectReference> |
|||
<ProjectReference Include="..\..\src\Perspex.Layout\Perspex.Layout.csproj"> |
|||
<Project>{42472427-4774-4c81-8aff-9f27b8e31721}</Project> |
|||
<Name>Perspex.Layout</Name> |
|||
</ProjectReference> |
|||
<ProjectReference Include="..\..\src\Perspex.SceneGraph\Perspex.SceneGraph.csproj"> |
|||
<Project>{eb582467-6abb-43a1-b052-e981ba910e3a}</Project> |
|||
<Name>Perspex.SceneGraph</Name> |
|||
</ProjectReference> |
|||
<ProjectReference Include="..\..\src\Perspex.Styling\Perspex.Styling.csproj"> |
|||
<Project>{f1baa01a-f176-4c6a-b39d-5b40bb1b148f}</Project> |
|||
<Name>Perspex.Styling</Name> |
|||
</ProjectReference> |
|||
<ProjectReference Include="..\..\src\Perspex.Themes.Default\Perspex.Themes.Default.csproj"> |
|||
<Project>{3e10a5fa-e8da-48b1-ad44-6a5b6cb7750f}</Project> |
|||
<Name>Perspex.Themes.Default</Name> |
|||
</ProjectReference> |
|||
<ProjectReference Include="..\Perspex.Controls.UnitTests\Perspex.Controls.UnitTests.csproj"> |
|||
<Project>{5ccb5571-7c30-4e7d-967d-0e2158ebd91f}</Project> |
|||
<Name>Perspex.Controls.UnitTests</Name> |
|||
</ProjectReference> |
|||
</ItemGroup> |
|||
<ItemGroup> |
|||
<Service Include="{82A7F48D-3B50-4B1E-B82E-3ADA8210C358}" /> |
|||
</ItemGroup> |
|||
<ItemGroup> |
|||
<Content Include="Readme.txt" /> |
|||
</ItemGroup> |
|||
<Import Project="..\..\src\Shared\PlatformSupport\PlatformSupport.projitems" Label="Shared" /> |
|||
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" /> |
|||
<Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild"> |
|||
<PropertyGroup> |
|||
<ErrorText>This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.</ErrorText> |
|||
</PropertyGroup> |
|||
<Error Condition="!Exists('..\..\packages\xunit.core.2.0.0\build\portable-net45+win+wpa81+wp80+monotouch+monoandroid+Xamarin.iOS\xunit.core.props')" Text="$([System.String]::Format('$(ErrorText)', '..\..\packages\xunit.core.2.0.0\build\portable-net45+win+wpa81+wp80+monotouch+monoandroid+Xamarin.iOS\xunit.core.props'))" /> |
|||
</Target> |
|||
<!-- To modify your build process, add your task inside one of the targets below and uncomment it. |
|||
Other similar extension points exist, see Microsoft.Common.targets. |
|||
<Target Name="BeforeBuild"> |
|||
</Target> |
|||
<Target Name="AfterBuild"> |
|||
</Target> |
|||
--> |
|||
</Project> |
|||
@ -0,0 +1,36 @@ |
|||
using System.Reflection; |
|||
using System.Runtime.CompilerServices; |
|||
using System.Runtime.InteropServices; |
|||
|
|||
// General Information about an assembly is controlled through the following
|
|||
// set of attributes. Change these attribute values to modify the information
|
|||
// associated with an assembly.
|
|||
[assembly: AssemblyTitle("Perspex.LeakTests")] |
|||
[assembly: AssemblyDescription("")] |
|||
[assembly: AssemblyConfiguration("")] |
|||
[assembly: AssemblyCompany("")] |
|||
[assembly: AssemblyProduct("Perspex.LeakTests")] |
|||
[assembly: AssemblyCopyright("Copyright © 2015")] |
|||
[assembly: AssemblyTrademark("")] |
|||
[assembly: AssemblyCulture("")] |
|||
|
|||
// Setting ComVisible to false makes the types in this assembly not visible
|
|||
// to COM components. If you need to access a type in this assembly from
|
|||
// COM, set the ComVisible attribute to true on that type.
|
|||
[assembly: ComVisible(false)] |
|||
|
|||
// The following GUID is for the ID of the typelib if this project is exposed to COM
|
|||
[assembly: Guid("e1aa3dbf-9056-4530-9376-18119a7a3ffe")] |
|||
|
|||
// Version information for an assembly consists of the following four values:
|
|||
//
|
|||
// Major Version
|
|||
// Minor Version
|
|||
// Build Number
|
|||
// Revision
|
|||
//
|
|||
// You can specify all the values or you can default the Build and Revision Numbers
|
|||
// by using the '*' as shown below:
|
|||
// [assembly: AssemblyVersion("1.0.*")]
|
|||
[assembly: AssemblyVersion("1.0.0.0")] |
|||
[assembly: AssemblyFileVersion("1.0.0.0")] |
|||
@ -0,0 +1,8 @@ |
|||
Memory Leak Tests |
|||
----------------- |
|||
|
|||
These tests use JetBrains' dotMemory Unit. When run in a normal test runner, they will always pass. |
|||
|
|||
To run the tests, you need to have dotMemory/ReSharper and install the XUnit plugin. You should |
|||
then be able to run the tests using Resharper -> Unit Tests -> Run all tests from solution under |
|||
dotMemory Unit. |
|||
@ -0,0 +1,41 @@ |
|||
// Copyright (c) The Perspex Project. All rights reserved.
|
|||
// Licensed under the MIT license. See licence.md file in the project root for full license information.
|
|||
|
|||
using Moq; |
|||
using Perspex.Controls.UnitTests; |
|||
using Perspex.Platform; |
|||
using Perspex.Shared.PlatformSupport; |
|||
using Perspex.Themes.Default; |
|||
using Ploeh.AutoFixture; |
|||
using Ploeh.AutoFixture.AutoMoq; |
|||
|
|||
namespace Perspex.LeakTests |
|||
{ |
|||
internal class TestApp : Application |
|||
{ |
|||
private TestApp() |
|||
{ |
|||
RegisterServices(); |
|||
|
|||
var fixture = new Fixture().Customize(new AutoMoqCustomization()); |
|||
var windowImpl = new Mock<IWindowImpl>(); |
|||
var renderInterface = fixture.Create<IPlatformRenderInterface>(); |
|||
|
|||
PerspexLocator.CurrentMutable |
|||
.Bind<IAssetLoader>().ToConstant(new AssetLoader()) |
|||
.Bind<IPclPlatformWrapper>().ToConstant(new PclPlatformWrapper()) |
|||
.Bind<IPlatformRenderInterface>().ToConstant(renderInterface) |
|||
.Bind<IWindowingPlatform>().ToConstant(new WindowingPlatformMock(() => windowImpl.Object)); |
|||
|
|||
Styles = new DefaultTheme(); |
|||
} |
|||
|
|||
public static void Initialize() |
|||
{ |
|||
if (Current == null) |
|||
{ |
|||
new TestApp(); |
|||
} |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,15 @@ |
|||
<?xml version="1.0" encoding="utf-8"?> |
|||
<configuration> |
|||
<runtime> |
|||
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1"> |
|||
<dependentAssembly> |
|||
<assemblyIdentity name="Ploeh.AutoFixture" publicKeyToken="b24654c590009d4f" culture="neutral" /> |
|||
<bindingRedirect oldVersion="0.0.0.0-3.31.3.0" newVersion="3.31.3.0" /> |
|||
</dependentAssembly> |
|||
<dependentAssembly> |
|||
<assemblyIdentity name="Moq" publicKeyToken="69f491c39445e920" culture="neutral" /> |
|||
<bindingRedirect oldVersion="0.0.0.0-4.2.1507.118" newVersion="4.2.1507.118" /> |
|||
</dependentAssembly> |
|||
</assemblyBinding> |
|||
</runtime> |
|||
</configuration> |
|||
@ -0,0 +1,17 @@ |
|||
<?xml version="1.0" encoding="utf-8"?> |
|||
<packages> |
|||
<package id="AutoFixture" version="3.31.3" targetFramework="net45" /> |
|||
<package id="AutoFixture.AutoMoq" version="3.31.1" targetFramework="net45" /> |
|||
<package id="JetBrains.dotMemoryUnit" version="2.1.20150828.125449" targetFramework="net45" /> |
|||
<package id="Moq" version="4.2.1507.0118" targetFramework="net45" /> |
|||
<package id="Rx-Core" version="2.2.5" targetFramework="net45" /> |
|||
<package id="Rx-Interfaces" version="2.2.5" targetFramework="net45" /> |
|||
<package id="Rx-Linq" version="2.2.5" targetFramework="net45" /> |
|||
<package id="Rx-Main" version="2.2.5" targetFramework="net45" /> |
|||
<package id="Rx-PlatformServices" version="2.2.5" targetFramework="net45" /> |
|||
<package id="xunit" version="2.0.0" targetFramework="net46" /> |
|||
<package id="xunit.abstractions" version="2.0.0" targetFramework="net46" /> |
|||
<package id="xunit.assert" version="2.0.0" targetFramework="net46" /> |
|||
<package id="xunit.core" version="2.0.0" targetFramework="net46" /> |
|||
<package id="xunit.extensibility.core" version="2.0.0" targetFramework="net46" /> |
|||
</packages> |
|||
Loading…
Reference in new issue