public void BeforeRemove_WhenPackageRemoving_ShouldCleanupSdk() { const string packageName = "packageName"; var targetFramework = new TargetFramework("tfm"); var sdkDependency = new TestDependency { Id = Dependency.GetID(targetFramework, SdkRuleHandler.ProviderTypeString, packageName), TopLevel = false, Resolved = true, Flags = DependencyTreeFlags.SdkSubTreeNodeFlags.Union(DependencyTreeFlags.ResolvedFlags) }; var packageDependency = new TestDependency { Id = "packageId", Name = packageName, Flags = DependencyTreeFlags.PackageNodeFlags, TopLevel = true, Resolved = true }; var worldBuilder = new IDependency[] { packageDependency, sdkDependency }.ToImmutableDictionary(d => d.Id).ToBuilder(); var context = new RemoveDependencyContext(worldBuilder); var filter = new SdkAndPackagesDependenciesSnapshotFilter(); filter.BeforeRemove( projectPath: null, targetFramework: targetFramework, dependency: packageDependency, context); // Accepts removal Assert.True(context.GetResult(filter)); // Makes other changes too Assert.True(context.Changed); Assert.True(worldBuilder.TryGetValue(packageDependency.Id, out var afterPackageDependency)); Assert.Same(packageDependency, afterPackageDependency); Assert.True(worldBuilder.TryGetValue(sdkDependency.Id, out var afterSdkDependency)); afterSdkDependency.AssertEqualTo( afterSdkDependency.ToUnresolved( SdkReference.SchemaName, dependencyIDs: ImmutableList <string> .Empty)); }
public async Task WheEmptySnapshotAndVisibilityMarkerProvided_ShouldDisplaySubTreeRoot() { var dependencyRootYyy = new TestDependency { ProviderType = "Yyy", Id = "YyyDependencyRoot", Name = "YyyDependencyRoot", Caption = "YyyDependencyRoot", Resolved = true }; var dependencyVisibilityMarker = new TestDependency { ProviderType = "Yyy", Id = "someid", Name = "someid", Caption = "someid", Resolved = false, Visible = false, Flags = DependencyTreeFlags.ShowEmptyProviderRootNode }; var dependenciesRoot = new TestProjectTree { Caption = "MyDependencies", Children = { new TestProjectTree { Caption = "YyyDependencyRoot", FilePath = "YyyDependencyRoot" } } }; var provider = CreateProvider(rootModels: new[] { dependencyRootYyy }); var snapshot = GetSnapshot((_tfm1, new[] { dependencyVisibilityMarker })); // Act var resultTree = await provider.BuildTreeAsync(dependenciesRoot, snapshot); // Assert var expectedFlatHierarchy = @"Caption=MyDependencies, FilePath=, IconHash=325248080, ExpandedIconHash=325248080, Rule=, IsProjectItem=False, CustomTag= Caption=YyyDependencyRoot, FilePath=YyyDependencyRoot, IconHash=0, ExpandedIconHash=0, Rule=, IsProjectItem=False, CustomTag="; Assert.Equal(expectedFlatHierarchy, ToTestDataString((TestProjectTree)resultTree)); }
public void BeforeAddOrUpdate_WhenProjectSnapshotFoundAndNoUnresolvedDependencies_ShouldDoNothing() { const string projectPath = @"c:\project\project.csproj"; var targetFramework = ITargetFrameworkFactory.Implement(moniker: "tfm1"); var targetedSnapshot = ITargetedDependenciesSnapshotFactory.Implement(hasUnresolvedDependency: false); var targets = new Dictionary <ITargetFramework, ITargetedDependenciesSnapshot> { { targetFramework, targetedSnapshot } }; var snapshot = IDependenciesSnapshotFactory.Implement(targets: targets); var snapshotProvider = IDependenciesSnapshotProviderFactory.Implement(currentSnapshot: snapshot); var aggregateSnapshotProvider = new Mock <IAggregateDependenciesSnapshotProvider>(MockBehavior.Strict); aggregateSnapshotProvider.Setup(x => x.GetSnapshotProvider(projectPath)).Returns(snapshotProvider); var targetFrameworkProvider = ITargetFrameworkProviderFactory.Implement(getNearestFramework: targetFramework); var dependency = new TestDependency { Id = "dependency1", TopLevel = true, Resolved = true, Flags = DependencyTreeFlags.ProjectNodeFlags.Union(DependencyTreeFlags.ResolvedFlags), FullPath = projectPath, TargetFramework = targetFramework }; var worldBuilder = ImmutableDictionary <string, IDependency> .Empty.ToBuilder(); var context = new AddDependencyContext(worldBuilder); var filter = new UnsupportedProjectsSnapshotFilter(aggregateSnapshotProvider.Object, targetFrameworkProvider); filter.BeforeAddOrUpdate( null, null, dependency, null, null, context); // Accepts unchanged dependency Assert.Same(dependency, context.GetResult(filter)); // No other changes made Assert.False(context.Changed); aggregateSnapshotProvider.VerifyAll(); }
public void BeforeAddOrUpdate_WhenThereIsMatchingDependency_WithSubstringCaption() { // Both top level // Same provider type // Duplicate caption prefix // -> No change const string providerType = "provider"; const string caption = "caption"; var dependency = new TestDependency { Id = "dependency1", ProviderType = providerType, Caption = caption, TopLevel = true }; var otherDependency = new TestDependency { ClonePropertiesFrom = dependency, Id = "dependency2", OriginalItemSpec = "dependency2ItemSpec", Caption = $"{caption}X" // identical caption prefix }; // TODO test a longer suffix here -- looks like the implementation might not handle it correctly var worldBuilder = new IDependency[] { dependency, otherDependency }.ToImmutableDictionary(d => d.Id).ToBuilder(); var context = new AddDependencyContext(worldBuilder); var filter = new DuplicatedDependenciesSnapshotFilter(); filter.BeforeAddOrUpdate( null, null, dependency, null, null, context); // Accepts unchanged dependency Assert.Same(dependency, context.GetResult(filter)); // No other changes made Assert.False(context.Changed); }
public void BeforeAddOrUpdate_WhenProjectSnapshotFoundAndHasUnresolvedDependencies_ShouldMakeUnresolved() { const string projectPath = @"c:\project\project.csproj"; var targetFramework = ITargetFrameworkFactory.Implement(moniker: "tfm1"); var dependency = new TestDependency { Id = "dependency1", TopLevel = true, Resolved = true, Flags = DependencyTreeFlags.ProjectNodeFlags.Union(DependencyTreeFlags.ResolvedFlags), TargetFramework = targetFramework, FullPath = projectPath }; var targetedSnapshot = ITargetedDependenciesSnapshotFactory.Implement(hasUnresolvedDependency: true); var aggregateSnapshotProvider = new Mock <IAggregateDependenciesSnapshotProvider>(MockBehavior.Strict); aggregateSnapshotProvider.Setup(x => x.GetSnapshot(dependency)).Returns(targetedSnapshot); var worldBuilder = ImmutableDictionary <string, IDependency> .Empty.ToBuilder(); var context = new AddDependencyContext(worldBuilder); var filter = new UnsupportedProjectsSnapshotFilter(aggregateSnapshotProvider.Object); filter.BeforeAddOrUpdate( null, null, dependency, null, null, context); // Accepts unresolved version var acceptedDependency = context.GetResult(filter); acceptedDependency.AssertEqualTo( dependency.ToUnresolved(ProjectReference.SchemaName)); // No other changes made Assert.False(context.Changed); aggregateSnapshotProvider.VerifyAll(); }
public void BeforeAddOrUpdate_NoDuplicate_ShouldNotUpdateCaption() { // Both top level // Same provider type // Different captions // -> No change const string providerType = "provider"; var dependency = new TestDependency { Id = "dependency1", Caption = "caption1", ProviderType = providerType, TopLevel = true }; var otherDependency = new TestDependency { Id = "dependency2", Caption = "caption2", ProviderType = providerType, TopLevel = true }; var worldBuilder = new IDependency[] { dependency, otherDependency }.ToImmutableDictionary(d => d.Id).ToBuilder(); var context = new AddDependencyContext(worldBuilder); var filter = new DuplicatedDependenciesSnapshotFilter(); filter.BeforeAddOrUpdate( null, null, dependency, null, null, context); // Accepts unchanged dependency Assert.Same(dependency, context.GetResult(filter)); // No other changes made Assert.False(context.Changed); }
public void BeforeAddOrUpdate_WhenSdkAndPackageUnresolved_ShouldDoNothing() { var targetFramework = new TargetFramework("tfm"); const string sdkName = "sdkName"; var sdkDependency = new TestDependency { Id = "dependency1", Name = sdkName, TopLevel = false, Resolved = true, Flags = DependencyTreeFlags.SdkSubTreeNodeFlags }; var packageDependency = new TestDependency { Id = Dependency.GetID(targetFramework, PackageRuleHandler.ProviderTypeString, sdkName), Resolved = false, Flags = DependencyTreeFlags.PackageNodeFlags }; var worldBuilder = new IDependency[] { sdkDependency, packageDependency }.ToImmutableDictionary(d => d.Id).ToBuilder(); var context = new AddDependencyContext(worldBuilder); var filter = new SdkAndPackagesDependenciesSnapshotFilter(); filter.BeforeAddOrUpdate( null, targetFramework, sdkDependency, null, null, context); // Accepts unchanged dependency Assert.Same(sdkDependency, context.GetResult(filter)); // No other changes made Assert.False(context.Changed); }
public void BeforeAddOrUpdate_WhenProjectSnapshotNotFound_ShouldDoNothing() { const string projectPath = @"c:\project\project.csproj"; var dependency = new TestDependency { Id = "dependency1", TopLevel = true, Resolved = true, Flags = DependencyTreeFlags.ProjectNodeFlags.Union(DependencyTreeFlags.ResolvedFlags), FullPath = projectPath }; var aggregateSnapshotProvider = new Mock <IAggregateDependenciesSnapshotProvider>(MockBehavior.Strict); aggregateSnapshotProvider.Setup(x => x.GetSnapshot(dependency)).Returns((ITargetedDependenciesSnapshot)null); var worldBuilder = ImmutableDictionary <string, IDependency> .Empty.ToBuilder(); var context = new AddDependencyContext(worldBuilder); var filter = new UnsupportedProjectsSnapshotFilter(aggregateSnapshotProvider.Object); filter.BeforeAddOrUpdate( null, null, dependency, null, null, context); // Accepts unchanged dependency Assert.Same(dependency, context.GetResult(filter)); // No other changes made Assert.False(context.Changed); aggregateSnapshotProvider.VerifyAll(); }
public void BeforeAddOrUpdate_WhenDependencyNotRecognized_ShouldDoNothing() { var acceptable = new TestDependency { Id = "dependency1", TopLevel = true, Resolved = true, Flags = DependencyTreeFlags.ProjectNodeFlags }; AssertNoChange(new TestDependency { ClonePropertiesFrom = acceptable, TopLevel = false }); AssertNoChange(new TestDependency { ClonePropertiesFrom = acceptable, Resolved = false }); AssertNoChange(new TestDependency { ClonePropertiesFrom = acceptable, Flags = ProjectTreeFlags.Empty }); AssertNoChange(new TestDependency { ClonePropertiesFrom = acceptable, Flags = DependencyTreeFlags.ProjectNodeFlags.Union(DependencyTreeFlags.SharedProjectFlags) }); return; void AssertNoChange(IDependency dependency) { var aggregateSnapshotProvider = IAggregateDependenciesSnapshotProviderFactory.Create(); var worldBuilder = new[] { dependency }.ToImmutableDictionary(d => d.Id).ToBuilder(); var context = new AddDependencyContext(worldBuilder); var filter = new UnsupportedProjectsSnapshotFilter(aggregateSnapshotProvider); filter.BeforeAddOrUpdate( null, null, dependency, null, null, context); // Accepts unchanged dependency Assert.Same(dependency, context.GetResult(filter)); // No other changes made Assert.False(context.Changed); } }
public async Task WhenOneTargetSnapshotWithExistingDependencies_ShouldApplyChanges() { var dependencyModelRootXxx = new TestDependencyModel { ProviderType = "Xxx", Id = "XxxDependencyRoot", Name = "XxxDependencyRoot", Caption = "XxxDependencyRoot", Resolved = true }; var dependencyModelRootYyy = new TestDependencyModel { ProviderType = "Yyy", Id = "YyyDependencyRoot", Name = "YyyDependencyRoot", Caption = "YyyDependencyRoot" }; var dependencyXxx1 = new TestDependency { ProviderType = "Xxx", Id = "tfm1\\xxx\\dependency1", Name = "dependency1", Path = "dependencyXxxpath", Caption = "Dependency1", SchemaItemType = "Xxx", Resolved = true, Icon = KnownMonikers.Uninstall, ExpandedIcon = KnownMonikers.Uninstall, TargetFramework = _tfm1 }; var dependencyYyy1 = new TestDependency { ProviderType = "Yyy", Id = "tfm1\\yyy\\dependency1", Name = "dependency1", Path = "dependencyYyypath", Caption = "Dependency1", SchemaItemType = "Yyy", Resolved = true, Icon = KnownMonikers.Uninstall, ExpandedIcon = KnownMonikers.Uninstall, TargetFramework = _tfm1 }; var dependencyYyyExisting = new TestDependency { ProviderType = "Yyy", Id = "tfm1\\yyy\\dependencyExisting", Name = "dependencyExisting", Path = "dependencyExistingPath", Caption = "DependencyExisting", SchemaItemType = "Yyy", Resolved = true, Icon = KnownMonikers.Uninstall, ExpandedIcon = KnownMonikers.Uninstall, TargetFramework = _tfm1 }; var dependenciesRoot = new TestProjectTree { Caption = "MyDependencies", Children = { new TestProjectTree { Caption = "OldRootChildToBeRemoved" }, new TestProjectTree { Caption = "YyyDependencyRoot", FilePath = "YyyDependencyRoot", Children = { new TestProjectTree { Caption = "DependencyExisting", FilePath = "tfm1\\yyy\\dependencyExisting" } } } } }; var provider = CreateProvider(rootModels: new[] { dependencyModelRootXxx, dependencyModelRootYyy }); var snapshot = GetSnapshot((_tfm1, new[] { dependencyXxx1, dependencyYyy1, dependencyYyyExisting })); // Act var resultTree = await provider.BuildTreeAsync(dependenciesRoot, snapshot); // Assert var expectedFlatHierarchy = @"Caption=MyDependencies, FilePath=, IconHash=325248080, ExpandedIconHash=325248080, Rule=, IsProjectItem=False, CustomTag= Caption=YyyDependencyRoot, FilePath=YyyDependencyRoot, IconHash=0, ExpandedIconHash=0, Rule=, IsProjectItem=False, CustomTag= Caption=DependencyExisting, FilePath=tfm1\yyy\dependencyExisting, IconHash=325249260, ExpandedIconHash=325249260, Rule=, IsProjectItem=False, CustomTag= Caption=Dependency1, FilePath=tfm1\Yyy\dependencyYyypath, IconHash=325249260, ExpandedIconHash=325249260, Rule=, IsProjectItem=True, CustomTag= Caption=XxxDependencyRoot, FilePath=XxxDependencyRoot, IconHash=0, ExpandedIconHash=0, Rule=, IsProjectItem=False, CustomTag= Caption=Dependency1, FilePath=tfm1\Xxx\dependencyXxxpath, IconHash=325249260, ExpandedIconHash=325249260, Rule=, IsProjectItem=True, CustomTag="; Assert.Equal(expectedFlatHierarchy, ToTestDataString((TestProjectTree)resultTree)); }
public async Task WhenOneTargetSnapshotAndDependencySupportsRule_ShouldCreateRule() { var dependencyRootYyy = new TestDependency { ProviderType = "Yyy", Id = "YyyDependencyRoot", Name = "YyyDependencyRoot", Caption = "YyyDependencyRoot", Resolved = true }; var dependencyYyyExisting = new TestDependency { ProviderType = "Yyy", Id = "tfm1\\yyy\\dependencyExisting", Name = "dependencyExisting", Caption = "DependencyExisting", SchemaItemType = "Yyy", Resolved = true, Icon = KnownMonikers.Uninstall, ExpandedIcon = KnownMonikers.Uninstall, Flags = DependencyTreeFlags.SupportsRuleProperties }; var dependenciesRoot = new TestProjectTree { Caption = "MyDependencies", Children = { new TestProjectTree { Caption = "YyyDependencyRoot", FilePath = "YyyDependencyRoot", Children = { new TestProjectTree { Caption = "DependencyExisting", FilePath = "tfm1\\yyy\\dependencyExisting", Flags = DependencyTreeFlags.ResolvedFlags } } } } }; var provider = CreateProvider(rootModels: new[] { dependencyRootYyy }); var snapshot = GetSnapshot((_tfm1, new[] { dependencyYyyExisting })); // Act var resultTree = await provider.BuildTreeAsync(dependenciesRoot, snapshot); // Assert var expectedFlatHierarchy = @"Caption=MyDependencies, FilePath=, IconHash=325248080, ExpandedIconHash=325248080, Rule=, IsProjectItem=False, CustomTag= Caption=YyyDependencyRoot, FilePath=YyyDependencyRoot, IconHash=0, ExpandedIconHash=0, Rule=, IsProjectItem=False, CustomTag= Caption=DependencyExisting, FilePath=tfm1\yyy\dependencyExisting, IconHash=325249260, ExpandedIconHash=325249260, Rule=Yyy, IsProjectItem=False, CustomTag="; Assert.Equal(expectedFlatHierarchy, ToTestDataString((TestProjectTree)resultTree)); }
public void TFromChanges_ReportedChangesAfterBeforeAddFilterDeclinedChange() { const string projectPath = @"c:\somefolder\someproject\a.csproj"; var targetFramework = new TargetFramework("tfm1"); var dependencyTop1 = IDependencyFactory.FromJson(@" { ""ProviderType"": ""Xxx"", ""Id"": ""tfm1\\xxx\\topdependency1"", ""Name"":""TopDependency1"", ""Caption"":""TopDependency1"", ""SchemaItemType"":""Xxx"", ""Resolved"":""true"", ""TopLevel"":""true"" }", icon: KnownMonikers.Uninstall, expandedIcon: KnownMonikers.Uninstall); var dependencyChild1 = IDependencyFactory.FromJson(@" { ""ProviderType"": ""Xxx"", ""Id"": ""tfm1\\xxx\\childdependency1"", ""Name"":""ChildDependency1"", ""Caption"":""ChildDependency1"", ""SchemaItemType"":""Xxx"", ""Resolved"":""true"", ""TopLevel"":""false"" }", icon: KnownMonikers.Uninstall, expandedIcon: KnownMonikers.Uninstall); var dependencyModelNew1 = IDependencyModelFactory.FromJson(@" { ""ProviderType"": ""Xxx"", ""Id"": ""newdependency1"", ""Name"":""NewDependency1"", ""Caption"":""NewDependency1"", ""SchemaItemType"":""Xxx"", ""Resolved"":""true"" }", icon: KnownMonikers.Uninstall, expandedIcon: KnownMonikers.Uninstall); var catalogs = IProjectCatalogSnapshotFactory.Create(); var previousSnapshot = ITargetedDependenciesSnapshotFactory.Implement( projectPath: projectPath, targetFramework: targetFramework, catalogs: catalogs, dependenciesWorld: new [] { dependencyTop1, dependencyChild1 }, topLevelDependencies: new [] { dependencyTop1 }); var changes = new DependenciesChangesBuilder(); changes.Added(dependencyModelNew1); var filterAddedDependency = new TestDependency { Id = "unexpected", TopLevel = true }; var snapshotFilter = new TestDependenciesSnapshotFilter() .BeforeAddReject(@"tfm1\xxx\newdependency1", addOrUpdate: filterAddedDependency); var snapshot = TargetedDependenciesSnapshot.FromChanges( projectPath, previousSnapshot, changes.Build(), catalogs, ImmutableArray.Create <IDependenciesSnapshotFilter>(snapshotFilter), new Dictionary <string, IProjectDependenciesSubTreeProvider>(), null); Assert.NotSame(previousSnapshot, snapshot); Assert.Same(previousSnapshot.TargetFramework, snapshot.TargetFramework); Assert.Same(previousSnapshot.ProjectPath, snapshot.ProjectPath); Assert.Same(previousSnapshot.Catalogs, snapshot.Catalogs); AssertEx.CollectionLength(snapshot.TopLevelDependencies, 2); Assert.Contains(dependencyTop1, snapshot.TopLevelDependencies); Assert.Contains(filterAddedDependency, snapshot.TopLevelDependencies); AssertEx.CollectionLength(snapshot.DependenciesWorld, 3); Assert.Contains(dependencyTop1, snapshot.DependenciesWorld.Values); Assert.Contains(dependencyChild1, snapshot.DependenciesWorld.Values); Assert.Contains(filterAddedDependency, snapshot.DependenciesWorld.Values); }