public void DoNotMatchConfig()
        {
            // Collect nested dependencies that are not collapsible, should cause a DependencyException
            // Collect nested dependencies that are collapsible, should result in 1
            var config = new Config()
            {
                Info = new PackageInfo("MyMod", "asdf", new SemVer.Version("0.1.0"))
            };
            var dep      = new Dependency("id", new SemVer.Range("^0.1.0"));
            var otherDep = new Dependency("needed", new SemVer.Range("^0.1.4"));

            config.Dependencies.Add(dep);
            config.Dependencies.Add(otherDep);
            var depConfig = new SharedConfig {
                Config = new Config()
                {
                    Info = new PackageInfo("Cool Name", "id", new SemVer.Version("0.1.0"))
                }
            };
            var innerDep = new Dependency("needed", new SemVer.Range("0.1.0"));

            depConfig.Config.Dependencies.Add(innerDep);
            var innerDepConfig = new SharedConfig {
                Config = new Config {
                    Info = new PackageInfo("Needed by both", "needed", new SemVer.Version("0.1.4"))
                }
            };

            var configProvider = Utils.GetConfigProvider(config);
            var uriHandler     = Utils.GetUriHandler(new Dictionary <Dependency, SharedConfig>
            {
                { dep, depConfig }, { otherDep, innerDepConfig }, { innerDep, innerDepConfig }
            });

            var innerRestorer = new RestoreHandler(Utils.GetConfigProvider(depConfig.Config).Object, uriHandler.Object);

            // Should throw
            Assert.Throws <DependencyException>(() => innerRestorer.CollectDependencies());
            // Assume it DID NOT restore

            var restorer = new RestoreHandler(configProvider.Object, uriHandler.Object);
            // This should NOT throw, since the version we test here actually exists and is satisfiable.
            // and our dependency config DOES NOT contain a restored dependency that causes any problems.
            // TODO: We could add a test here to test for when one matches but they other doesn't too.
            var deps = restorer.CollectDependencies();

            Assert.Collection(deps,
                              kvp =>
            {
                Assert.True(kvp.Key.Dependency.Id == dep.Id);
                Assert.True(kvp.Key.Dependency.VersionRange == dep.VersionRange);
                Assert.True(kvp.Value.Config.Info.Version == depConfig.Config.Info.Version);
            },
                              kvp =>
            {
                Assert.True(kvp.Key.Dependency.Id == otherDep.Id);
                Assert.True(kvp.Key.Dependency.VersionRange == otherDep.VersionRange);
                Assert.True(kvp.Value.Config.Info.Version == innerDepConfig.Config.Info.Version);
            });
        }
        public void Recursive()
        {
            var config = new Config()
            {
                Info = new PackageInfo("MyMod", "id", new SemVer.Version("0.1.0"))
            };
            var dep = new Dependency("id", new SemVer.Range("^0.1.0"));

            config.Dependencies.Add(dep);
            var depConfig = new SharedConfig {
                Config = new Config()
                {
                    Info = new PackageInfo("Cool Name", "id", new SemVer.Version("0.1.0"))
                }
            };

            var configProvider = Utils.GetConfigProvider(config);
            var uriHandler     = Utils.GetUriHandler(new Dictionary <Dependency, SharedConfig> {
                { dep, depConfig }
            });

            var restorer = new RestoreHandler(configProvider.Object, uriHandler.Object);

            // Should throw a recursive exception (id cannot include id)
            Assert.Throws <DependencyException>(() => restorer.CollectDependencies());
            // Should never have made any GetConfig calls
            uriHandler.Verify(mocks => mocks.GetSharedConfig(It.IsAny <RestoredDependencyPair>()), Times.Never);
        }
        public void Simple()
        {
            var config = new Config()
            {
                Info = new PackageInfo("MyMod", "asdf", new SemVer.Version("0.1.0"))
            };
            var dep = new Dependency("id", new SemVer.Range("^0.1.0"));

            config.Dependencies.Add(dep);
            var depConfig = new SharedConfig {
                Config = new Config()
                {
                    Info = new PackageInfo("Cool Name", "id", new SemVer.Version("0.1.1"))
                }
            };

            var configProvider = Utils.GetConfigProvider(config);
            var uriHandler     = Utils.GetUriHandler(new Dictionary <Dependency, SharedConfig> {
                { dep, depConfig }
            });

            var restorer = new RestoreHandler(configProvider.Object, uriHandler.Object);
            // Should not throw
            var deps = restorer.CollectDependencies();

            // Ensure we still only have one dependency and nothing has changed
            Assert.Collection(deps,
                              kvp =>
            {
                Assert.True(kvp.Key.Dependency.Id == dep.Id);
                Assert.True(kvp.Key.Dependency.VersionRange == dep.VersionRange);
            });
        }
예제 #4
0
        public void SimpleCollapse()
        {
            // Collect a dependency, collapse it, and nothing should change
            var config = new Config()
            {
                Info = new PackageInfo("MyMod", "asdf", new SemVer.Version("0.1.0"))
            };
            var dep = new Dependency("id", new SemVer.Range("^0.1.0"));

            config.Dependencies.Add(dep);
            var depConfig = new SharedConfig {
                Config = new Config()
                {
                    Info = new PackageInfo("Cool Name", "id", new SemVer.Version("0.1.1"))
                }
            };

            var configProvider = Utils.GetConfigProvider(config);
            var uriHandler     = Utils.GetUriHandler(new Dictionary <Dependency, SharedConfig> {
                { dep, depConfig }
            });

            var restorer = new RestoreHandler(configProvider.Object, uriHandler.Object);
            // Should not throw
            var deps   = restorer.CollectDependencies();
            var result = RestoreHandler.CollapseDependencies(deps);

            Assert.All(deps, kvp =>
            {
                Assert.True(result.TryGetValue(kvp.Key, out var conf));
                Assert.True(kvp.Value == conf);
            });
        }
        public void NestedRecursive()
        {
            var config = new Config()
            {
                Info = new PackageInfo("MyMod", "id", new SemVer.Version("0.1.0"))
            };
            var dep = new Dependency("asdf", new SemVer.Range("^0.1.0"));

            config.Dependencies.Add(dep);
            var depConfig = new SharedConfig {
                Config = new Config()
                {
                    Info = new PackageInfo("Cool Name", "asdf", new SemVer.Version("0.1.0"))
                }
            };
            // It's undefined behavior to attempt to load a config that allows its dependencies to ask for itself
            // Therefore, we will test ourselves, and all other configs must follow this same principle
            var innerDep = new Dependency("id", new SemVer.Range("^0.1.0"));

            depConfig.Config.Dependencies.Add(innerDep);
            var innerDepConfig = new SharedConfig {
                Config = new Config {
                    Info = new PackageInfo("inner", "id", new SemVer.Version("0.1.0"))
                }
            };

            var configProvider = Utils.GetConfigProvider(config);
            var uriHandler     = Utils.GetUriHandler(new Dictionary <Dependency, SharedConfig> {
                { dep, depConfig }, { innerDep, innerDepConfig }
            });

            var innerRestorer = new RestoreHandler(Utils.GetConfigProvider(depConfig.Config).Object, uriHandler.Object);
            // Should not throw
            var innerDeps = innerRestorer.CollectDependencies();

            Assert.Collection(innerDeps,
                              kvp =>
            {
                Assert.True(kvp.Key.Dependency.Id == innerDep.Id);
                Assert.True(kvp.Key.Dependency.VersionRange == innerDep.VersionRange);
                Assert.True(kvp.Value.Config.Info.Version == innerDepConfig.Config.Info.Version);
            }
                              );
            uriHandler.Verify(mocks => mocks.GetSharedConfig(It.Is <RestoredDependencyPair>(p => p.Dependency == innerDep)), Times.Once);
            // Assume it restored
            depConfig.RestoredDependencies.Add(new RestoredDependencyPair {
                Dependency = innerDep, Version = innerDepConfig.Config.Info.Version
            });

            var restorer = new RestoreHandler(configProvider.Object, uriHandler.Object);

            // Should throw a recursive exception (id cannot include id)
            Assert.Throws <DependencyException>(() => restorer.CollectDependencies());
            // Should have tried to get asdf's config
            uriHandler.Verify(mocks => mocks.GetSharedConfig(It.Is <RestoredDependencyPair>(p => p.Dependency == dep)), Times.Once);
            // The inner dependency should have been attempted to have been gotten exactly once, from the innerRestorer collection
            // It should not have been collected again in our collection of dependencies
            uriHandler.Verify(mocks => mocks.GetSharedConfig(It.Is <RestoredDependencyPair>(p => p.Dependency == innerDep)), Times.Once);
        }
        public void NestedNew()
        {
            var config = new Config()
            {
                Info = new PackageInfo("MyMod", "asdf", new SemVer.Version("0.1.0"))
            };
            var dep = new Dependency("id", new SemVer.Range("^0.1.0"));

            config.Dependencies.Add(dep);
            var depConfig = new SharedConfig {
                Config = new Config()
                {
                    Info = new PackageInfo("Cool Name", "id", new SemVer.Version("0.1.1"))
                }
            };
            var innerDep = new Dependency("id2", new SemVer.Range("^0.1.0"));

            depConfig.Config.Dependencies.Add(innerDep);
            var innerDepConfig = new SharedConfig {
                Config = new Config {
                    Info = new PackageInfo("Cool Name", "id2", new SemVer.Version("0.1.1"))
                }
            };

            var configProvider = Utils.GetConfigProvider(config);
            var uriHandler     = Utils.GetUriHandler(new Dictionary <Dependency, SharedConfig> {
                { dep, depConfig }, { innerDep, innerDepConfig }
            });

            var innerRestorer = new RestoreHandler(Utils.GetConfigProvider(depConfig.Config).Object, uriHandler.Object);
            // Should not throw
            var innerDeps = innerRestorer.CollectDependencies();

            Assert.Collection(innerDeps,
                              kvp =>
            {
                Assert.True(kvp.Key.Dependency.Id == innerDep.Id);
                Assert.True(kvp.Key.Dependency.VersionRange == innerDep.VersionRange);
                Assert.True(kvp.Value.Config.Info.Version == innerDepConfig.Config.Info.Version);
            }
                              );
            // Assume it restored
            depConfig.RestoredDependencies.Add(new RestoredDependencyPair {
                Dependency = innerDep, Version = innerDepConfig.Config.Info.Version
            });

            var restorer = new RestoreHandler(configProvider.Object, uriHandler.Object);
            // Should not throw
            var deps = restorer.CollectDependencies();

            // We should now have TWO dependencies, one for id and one for id2
            // Order of these dependencies should not matter. They just both need to be in there.
            Assert.Collection(deps,
                              kvp =>
            {
                Assert.True(kvp.Key.Dependency.Id == dep.Id);
                Assert.True(kvp.Key.Dependency.VersionRange == dep.VersionRange);
                Assert.True(kvp.Value.Config.Info.Version == depConfig.Config.Info.Version);
            },
                              kvp =>
            {
                Assert.True(kvp.Key.Dependency.Id == innerDep.Id);
                Assert.True(kvp.Key.Dependency.VersionRange == innerDep.VersionRange);
                Assert.True(kvp.Value.Config.Info.Version == innerDepConfig.Config.Info.Version);
            });
        }
        public void NestedExistingDuplicate()
        {
            var config = new Config()
            {
                Info = new PackageInfo("MyMod", "asdf", new SemVer.Version("0.1.0"))
            };
            var dep      = new Dependency("id", new SemVer.Range("^0.1.0"));
            var otherDep = new Dependency("needed", new SemVer.Range("^0.1.4"));

            config.Dependencies.Add(dep);
            config.Dependencies.Add(otherDep);
            var depConfig = new SharedConfig {
                Config = new Config()
                {
                    Info = new PackageInfo("Cool Name", "id", new SemVer.Version("0.1.0"))
                }
            };
            var innerDep = new Dependency("needed", new SemVer.Range("^0.1.0"));

            depConfig.Config.Dependencies.Add(innerDep);

            //depConfig.RestoredDependencies.Add(new RestoredDependencyPair { Dependency = innerDep, Version = new SemVer.Version("0.1.4") });
            var innerDepConfig = new SharedConfig {
                Config = new Config {
                    Info = new PackageInfo("Needed by both", "needed", new SemVer.Version("0.1.4"))
                }
            };

            var configProvider = Utils.GetConfigProvider(config);
            var uriHandler     = Utils.GetUriHandler(new Dictionary <Dependency, SharedConfig>
            {
                { dep, depConfig }, { otherDep, innerDepConfig }, { innerDep, innerDepConfig }
            });

            var innerRestorer = new RestoreHandler(Utils.GetConfigProvider(depConfig.Config).Object, uriHandler.Object);
            // Should not throw
            var innerDeps = innerRestorer.CollectDependencies();

            Assert.Collection(innerDeps,
                              kvp =>
            {
                Assert.True(kvp.Key.Dependency.Id == innerDep.Id);
                Assert.True(kvp.Key.Dependency.VersionRange == innerDep.VersionRange);
                Assert.True(kvp.Value.Config.Info.Version == innerDepConfig.Config.Info.Version);
            }
                              );
            // Assume it restored
            depConfig.RestoredDependencies.Add(new RestoredDependencyPair {
                Dependency = innerDep, Version = innerDepConfig.Config.Info.Version
            });

            var restorer = new RestoreHandler(configProvider.Object, uriHandler.Object);
            // Should not throw
            var deps = restorer.CollectDependencies();

            // We should now ONLY HAVE TWO dependencies!
            // The two dependencies for "needed" should be auto-collapsed into one, because the Versions match
            Assert.Collection(deps,
                              kvp =>
            {
                // Dependency must match, so should the version range (the first dependency should be from ourselves, so it should match perfectly)
                Assert.True(kvp.Key.Dependency.Id == dep.Id);
                Assert.True(kvp.Key.Dependency.VersionRange == dep.VersionRange);
                // Config version must be the correctly resolved version
                Assert.True(kvp.Value.Config.Info.Version == depConfig.Config.Info.Version);
            },
                              kvp =>
            {
                // Dependency ID must match, version range doesn't matter, but theoretically should intersect
                Assert.True(kvp.Key.Dependency.Id == otherDep.Id);
                // Config version must be the correctly resolved version
                Assert.True(kvp.Value.Config.Info.Version == innerDepConfig.Config.Info.Version);
            }
                              );
        }
        public void NestedExistingUnique()
        {
            var config = new Config()
            {
                Info = new PackageInfo("MyMod", "asdf", new SemVer.Version("0.1.0"))
            };
            var dep      = new Dependency("id", new SemVer.Range("^0.1.0"));
            var otherDep = new Dependency("needed", new SemVer.Range("^0.1.4"));

            config.Dependencies.Add(dep);
            config.Dependencies.Add(otherDep);
            var depConfig = new SharedConfig {
                Config = new Config()
                {
                    Info = new PackageInfo("Cool Name", "id", new SemVer.Version("0.1.0"))
                }
            };
            var innerDep = new Dependency("needed", new SemVer.Range("^0.1.0"));

            depConfig.Config.Dependencies.Add(innerDep);

            //depConfig.RestoredDependencies.Add(new RestoredDependencyPair { Dependency = innerDep, Version = new SemVer.Version("0.1.4") });
            var otherDepConfig = new SharedConfig {
                Config = new Config {
                    Info = new PackageInfo("Needed by both", "needed", new SemVer.Version("0.1.4"))
                }
            };
            var innerDepConfig = new SharedConfig {
                Config = new Config {
                    Info = new PackageInfo("Needed by both", "needed", new SemVer.Version("0.1.3"))
                }
            };

            var configProvider = Utils.GetConfigProvider(config);
            var uriHandler     = Utils.GetUriHandler(new Dictionary <Dependency, SharedConfig>
            {
                { dep, depConfig }, { otherDep, otherDepConfig }, { innerDep, innerDepConfig }
            });

            var innerRestorer = new RestoreHandler(Utils.GetConfigProvider(depConfig.Config).Object, uriHandler.Object);
            // Should not throw
            var innerDeps = innerRestorer.CollectDependencies();

            Assert.Collection(innerDeps,
                              kvp =>
            {
                Assert.True(kvp.Key.Dependency.Id == innerDep.Id);
                Assert.True(kvp.Key.Dependency.VersionRange == innerDep.VersionRange);
                Assert.True(kvp.Value.Config.Info.Version == innerDepConfig.Config.Info.Version);
            }
                              );
            // Assume it restored
            depConfig.RestoredDependencies.Add(new RestoredDependencyPair {
                Dependency = innerDep, Version = innerDepConfig.Config.Info.Version
            });

            var restorer = new RestoreHandler(configProvider.Object, uriHandler.Object);
            // Should not throw
            var deps = restorer.CollectDependencies();

            // We should now HAVE THREE dependencies!
            // The two dependencies for "needed" (because they are unique versions) and the dependency for "id"
            Assert.Collection(deps,
                              kvp =>
            {
                // Dependency ID and VersionRange must match
                // This is because the first dependency must be the one from our config
                Assert.True(kvp.Key.Dependency.Id == dep.Id);
                Assert.True(kvp.Key.Dependency.VersionRange == dep.VersionRange);
                // Config version must be the correctly resolved version
                Assert.True(kvp.Value.Config.Info.Version == depConfig.Config.Info.Version);
            },
                              kvp =>
            {
                // Dependency ID must match
                Assert.True(kvp.Key.Dependency.Id == innerDep.Id);
                // Config version must be the correctly resolved version
                Assert.True(kvp.Value.Config.Info.Version == innerDepConfig.Config.Info.Version);
            },
                              kvp =>
            {
                // Dependency ID must match
                Assert.True(kvp.Key.Dependency.Id == otherDep.Id);
                // Config version must be the correctly resolved version
                Assert.True(kvp.Value.Config.Info.Version == otherDepConfig.Config.Info.Version);
            }
                              );
        }
예제 #9
0
        public void CollapseMatching()
        {
            // Collect nested dependencies that are collapsible, should result in 1
            var config = new Config()
            {
                Info = new PackageInfo("MyMod", "asdf", new SemVer.Version("0.1.0"))
            };
            var dep      = new Dependency("id", new SemVer.Range("^0.1.0"));
            var otherDep = new Dependency("needed", new SemVer.Range("^0.1.4"));

            config.Dependencies.Add(dep);
            config.Dependencies.Add(otherDep);
            var depConfig = new SharedConfig {
                Config = new Config()
                {
                    Info = new PackageInfo("Cool Name", "id", new SemVer.Version("0.1.0"))
                }
            };
            var innerDep = new Dependency("needed", new SemVer.Range("^0.1.0"));

            depConfig.Config.Dependencies.Add(innerDep);
            var otherDepConfig = new SharedConfig {
                Config = new Config {
                    Info = new PackageInfo("Needed by both", "needed", new SemVer.Version("0.1.4"))
                }
            };
            var innerDepConfig = new SharedConfig {
                Config = new Config {
                    Info = new PackageInfo("Needed by both", "needed", new SemVer.Version("0.1.2"))
                }
            };

            var configProvider = Utils.GetConfigProvider(config);
            var uriHandler     = Utils.GetUriHandler(new Dictionary <Dependency, SharedConfig>
            {
                { dep, depConfig }, { otherDep, otherDepConfig }, { innerDep, innerDepConfig }
            });

            var innerRestorer = new RestoreHandler(Utils.GetConfigProvider(depConfig.Config).Object, uriHandler.Object);
            // Should not throw
            var innerDeps = innerRestorer.CollectDependencies();

            Assert.Collection(innerDeps,
                              kvp =>
            {
                Assert.True(kvp.Key.Dependency.Id == innerDep.Id);
                Assert.True(kvp.Key.Dependency.VersionRange == innerDep.VersionRange);
                Assert.True(kvp.Value.Config.Info.Version == innerDepConfig.Config.Info.Version);
            }
                              );
            // Assume it restored
            depConfig.RestoredDependencies.Add(new RestoredDependencyPair {
                Dependency = innerDep, Version = innerDepConfig.Config.Info.Version
            });

            var restorer = new RestoreHandler(configProvider.Object, uriHandler.Object);
            // Should not throw
            var deps = restorer.CollectDependencies();

            // We should now HAVE THREE dependencies!
            // The two dependencies for "needed" (because they are unique versions) and the dependency for "id"
            Assert.Collection(deps,
                              kvp =>
            {
                // Dependency ID and VersionRange must match
                // This is because the first dependency must be the one from our config
                Assert.True(kvp.Key.Dependency.Id == dep.Id);
                Assert.True(kvp.Key.Dependency.VersionRange == dep.VersionRange);
                // Config version must be the correctly resolved version
                Assert.True(kvp.Value.Config.Info.Version == depConfig.Config.Info.Version);
            },
                              kvp =>
            {
                // Dependency ID must match
                Assert.True(kvp.Key.Dependency.Id == innerDep.Id);
                // Config version must be the correctly resolved version
                Assert.True(kvp.Value.Config.Info.Version == innerDepConfig.Config.Info.Version);
            },
                              kvp =>
            {
                // Dependency ID must match
                Assert.True(kvp.Key.Dependency.Id == otherDep.Id);
                // Config version must be the correctly resolved version
                Assert.True(kvp.Value.Config.Info.Version == otherDepConfig.Config.Info.Version);
            }
                              );
            var result = RestoreHandler.CollapseDependencies(deps);

            // After collapsing, we should have the exact same version.
            // This is an easy case, since their config objects are literally identical.
            Assert.Collection(result,
                              kvp =>
            {
                // Dependency ID and VersionRange must match
                // This is because the first dependency must be the one from our config
                Assert.True(kvp.Key.Dependency.Id == dep.Id);
                Assert.True(kvp.Key.Dependency.VersionRange == dep.VersionRange);
                // Config version must be the correctly resolved version
                Assert.True(kvp.Value.Config.Info.Version == depConfig.Config.Info.Version);
            },
                              kvp =>
            {
                // Dependency ID must match
                Assert.True(kvp.Key.Dependency.Id == innerDep.Id);
                // Config version should be the HIGHEST version. In this case, otherDepConfig
                Assert.True(kvp.Value.Config.Info.Version == otherDepConfig.Config.Info.Version);
            }
                              );
        }