예제 #1
0
        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));
        }
예제 #2
0
        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));
        }
예제 #3
0
        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();
        }
예제 #4
0
        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);
        }
예제 #5
0
        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();
        }
예제 #6
0
        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);
        }
예제 #7
0
        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);
        }
예제 #8
0
        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();
        }
예제 #9
0
        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);
            }
        }
예제 #10
0
        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));
        }
예제 #11
0
        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);
        }