2016-05-02 11:32:24 -07:00
using System ;
using System.Collections.Generic ;
2016-05-02 19:51:12 -07:00
using System.IO ;
using System.Linq ;
2016-05-02 11:32:24 -07:00
using System.Reflection ;
using FluentAssertions ;
2016-05-02 19:51:12 -07:00
using Microsoft.DotNet.Tools.Test.Utilities ;
2016-05-02 11:32:24 -07:00
using NuGet.Frameworks ;
2016-09-26 13:47:55 -07:00
using NuGet.ProjectModel ;
2016-05-02 11:32:24 -07:00
using Xunit ;
namespace Microsoft.DotNet.ProjectModel.Tests
{
2016-05-02 19:51:12 -07:00
public class ProjectContextBuilderTests : TestBase
2016-05-02 11:32:24 -07:00
{
private static readonly HashSet < string > KnownProperties = new HashSet < string > ( StringComparer . Ordinal ) {
"Project" ,
"LockFile" ,
"TargetFramework" ,
"RuntimeIdentifiers" ,
"RootDirectory" ,
"ProjectDirectory" ,
"PackagesDirectory" ,
"ReferenceAssembliesPath" ,
"IsDesignTime" ,
"ProjectResolver" ,
"LockFileResolver" ,
"ProjectReaderSettings"
} ;
// This test ensures that Clone is always kept up-to-date to avoid hard-to-debug errors
// because someone added a property but didn't put it in Clone.
[Fact]
public void CloneTest ( )
{
// Initialize a test instance that we're going to clone. Make sure all properties are initialized here.
var initialBuilder = new ProjectContextBuilder ( )
. WithProject ( new Project ( ) )
2016-09-26 13:47:55 -07:00
. WithLockFile ( new LockFile ( ) )
2016-05-02 11:32:24 -07:00
. WithTargetFramework ( FrameworkConstants . CommonFrameworks . NetStandard10 )
. WithRuntimeIdentifiers ( new [ ] { "win7-x64" , "osx.10.10-x64" } )
. WithRootDirectory ( "C:\\The\\Root" )
. WithProjectDirectory ( "/where/the/project/at" )
. WithPackagesDirectory ( "D:\\My\\Awesome\\NuGet\\Packages" )
. WithReferenceAssembliesPath ( "/these/are/the/reference/assemblies" )
. WithProjectResolver ( _ = > new Project ( ) )
2016-09-26 13:47:55 -07:00
. WithLockFileResolver ( _ = > new LockFile ( ) )
2016-05-02 11:32:24 -07:00
. WithProjectReaderSettings ( new ProjectReaderSettings ( ) ) ;
// Clone the builder
var clonedBuilder = initialBuilder . Clone ( ) ;
// Compare all the properties. This is a shallow clone, so they should all be exactly ReferenceEqual
2016-05-02 19:51:12 -07:00
foreach ( var prop in typeof ( ProjectContextBuilder ) . GetTypeInfo ( ) . DeclaredProperties )
2016-05-02 11:32:24 -07:00
{
KnownProperties . Remove ( prop . Name ) . Should ( ) . BeTrue ( because : $"{prop.Name} should be listed in the known properties to ensure it is properly tested." ) ;
if ( prop . PropertyType . GetTypeInfo ( ) . IsValueType )
{
// Can't use reference equality on value types
prop . GetValue ( clonedBuilder ) . Should ( ) . Be ( prop . GetValue ( initialBuilder ) , because : $"clone should have duplicated the {prop.Name} property" ) ;
}
else
{
prop . GetValue ( clonedBuilder ) . Should ( ) . BeSameAs ( prop . GetValue ( initialBuilder ) , because : $"clone should have duplicated the {prop.Name} property" ) ;
}
}
KnownProperties . Should ( ) . BeEmpty ( because : "all properties should have been checked by the CloneTest" ) ;
}
2016-05-02 19:51:12 -07:00
[Fact]
public void BuildAllTargetsProperlyDeduplicatesTargets ( )
{
// Load all project contexts for the test project
var contexts = new ProjectContextBuilder ( )
. WithProjectDirectory ( Path . Combine ( TestAssetsManager . AssetsRoot , "TestProjectContextBuildAllDedupe" ) )
. BuildAllTargets ( )
. ToList ( ) ;
// This is a portable app, so even though RIDs are specified, BuildAllTargets should only produce one output.
Assert . Equal ( 1 , contexts . Count ) ;
}
2016-05-02 11:32:24 -07:00
}
}