using System; using System.IO; using System.Linq; using LibGit2Sharp.Tests.TestHelpers; using Xunit; namespace LibGit2Sharp.Tests { public class ConfigurationFixture : BaseFixture { private static void AssertValueInLocalConfigFile(string repoPath, string regex) { var configFilePath = Path.Combine(repoPath, ".git/config"); AssertValueInConfigFile(configFilePath, regex); } private static string RetrieveGlobalConfigLocation() { string[] variables = { "HOME", "USERPROFILE", }; foreach (string variable in variables) { string potentialLocation = Environment.GetEnvironmentVariable(variable); if (string.IsNullOrEmpty(potentialLocation)) { continue; } string potentialPath = Path.Combine(potentialLocation, ".gitconfig"); if (File.Exists(potentialPath)) { return potentialPath; } } throw new InvalidOperationException("Unable to determine the location of '.gitconfig' file."); } private static void AssertValueInGlobalConfigFile(string regex) { string configFilePath = RetrieveGlobalConfigLocation(); AssertValueInConfigFile(configFilePath, regex); } [Fact] public void CanUnsetAnEntryFromTheLocalConfiguration() { string path = CloneStandardTestRepo(); using (var repo = new Repository(path)) { Assert.Null(repo.Config.Get("unittests.boolsetting")); repo.Config.Set("unittests.boolsetting", true); Assert.True(repo.Config.Get("unittests.boolsetting").Value); repo.Config.Unset("unittests.boolsetting"); Assert.Null(repo.Config.Get("unittests.boolsetting")); } } [Fact] public void CanUnsetAnEntryFromTheGlobalConfiguration() { SelfCleaningDirectory scd = BuildSelfCleaningDirectory(); var options = BuildFakeConfigs(scd); using (var repo = new Repository(BareTestRepoPath, options)) { Assert.True(repo.Config.HasConfig(ConfigurationLevel.Global)); Assert.Equal(42, repo.Config.Get("Wow.Man-I-am-totally-global").Value); repo.Config.Unset("Wow.Man-I-am-totally-global"); Assert.Equal(42, repo.Config.Get("Wow.Man-I-am-totally-global").Value); repo.Config.Unset("Wow.Man-I-am-totally-global", ConfigurationLevel.Global); Assert.Null(repo.Config.Get("Wow.Man-I-am-totally-global")); } } [SkippableFact] public void CanGetGlobalStringValue() { using (var repo = new Repository(StandardTestRepoPath)) { InconclusiveIf(() => !repo.Config.HasConfig(ConfigurationLevel.Global), "No Git global configuration available"); Assert.NotNull(repo.Config.Get("user.name")); } } [SkippableFact] public void CanGetGlobalStringValueWithoutRepo() { using (var config = new Configuration()) { InconclusiveIf(() => !config.HasConfig(ConfigurationLevel.Global), "No Git global configuration available"); Assert.NotNull(config.Get("user.name")); } } [Fact] public void CanReadBooleanValue() { using (var repo = new Repository(StandardTestRepoPath)) { Assert.True(repo.Config.Get("core.ignorecase").Value); } } [Fact] public void CanReadIntValue() { using (var repo = new Repository(StandardTestRepoPath)) { Assert.Equal(2, repo.Config.Get("unittests.intsetting").Value); } } [Fact] public void CanReadLongValue() { using (var repo = new Repository(StandardTestRepoPath)) { Assert.Equal(15234, repo.Config.Get("unittests.longsetting").Value); } } [Fact] public void CanReadStringValue() { using (var repo = new Repository(StandardTestRepoPath)) { Assert.Equal("+refs/heads/*:refs/remotes/origin/*", repo.Config.Get("remote.origin.fetch").Value); Assert.Equal("+refs/heads/*:refs/remotes/origin/*", repo.Config.Get("remote", "origin", "fetch").Value); } } [SkippableFact] public void CanEnumerateGlobalConfig() { using (var repo = new Repository(StandardTestRepoPath)) { InconclusiveIf(() => !repo.Config.HasConfig(ConfigurationLevel.Global), "No Git global configuration available"); var entry = repo.Config.FirstOrDefault>(e => e.Key == "user.name"); Assert.NotNull(entry); Assert.NotNull(entry.Value); } } [Fact] public void CanEnumerateLocalConfig() { using (var repo = new Repository(StandardTestRepoPath)) { var entry = repo.Config.FirstOrDefault>(e => e.Key == "core.ignorecase"); Assert.NotNull(entry); Assert.Equal("true", entry.Value); } } [Fact] public void CanEnumerateLocalConfigContainingAKeyWithNoValue() { using (var repo = new Repository(BareTestRepoPath)) { var entry = repo.Config .Single>(c => c.Level == ConfigurationLevel.Local && c.Key == "core.pager"); Assert.Equal(string.Empty, entry.Value); } } [Fact] public void CanSetBooleanValue() { string path = CloneStandardTestRepo(); using (var repo = new Repository(path)) { repo.Config.Set("unittests.boolsetting", true); AssertValueInLocalConfigFile(path, "boolsetting = true$"); } } [SkippableFact] public void CanSetGlobalStringValue() { using (var repo = new Repository(StandardTestRepoPath)) { InconclusiveIf(() => !repo.Config.HasConfig(ConfigurationLevel.Global), "No Git global configuration available"); var existing = repo.Config.Get("user.name"); Assert.NotNull(existing); try { repo.Config.Set("user.name", "Unit Test", ConfigurationLevel.Global); AssertValueInGlobalConfigFile("name = Unit Test$"); } finally { repo.Config.Set("user.name", existing.Value, ConfigurationLevel.Global); } } } [SkippableFact] public void CanSetGlobalStringValueWithoutRepo() { using(var config = new Configuration()) { InconclusiveIf(() => !config.HasConfig(ConfigurationLevel.Global), "No Git global configuration available"); var existing = config.Get("user.name"); Assert.NotNull(existing); try { config.Set("user.name", "Unit Test", ConfigurationLevel.Global); AssertValueInGlobalConfigFile("name = Unit Test$"); } finally { config.Set("user.name", existing.Value, ConfigurationLevel.Global); } } } [Fact] public void SettingLocalConfigurationOutsideAReposThrows() { using (var config = new Configuration()) { Assert.Throws(() => config.Set("unittests.intsetting", 3)); } } [Fact] public void CanSetIntValue() { string path = CloneStandardTestRepo(); using (var repo = new Repository(path)) { repo.Config.Set("unittests.intsetting", 3); AssertValueInLocalConfigFile(path, "intsetting = 3$"); } } [Fact] public void CanSetLongValue() { string path = CloneStandardTestRepo(); using (var repo = new Repository(path)) { repo.Config.Set("unittests.longsetting", (long)451); AssertValueInLocalConfigFile(path, "longsetting = 451"); } } [Fact] public void CanSetStringValue() { string path = CloneStandardTestRepo(); using (var repo = new Repository(path)) { repo.Config.Set("unittests.stringsetting", "val"); AssertValueInLocalConfigFile(path, "stringsetting = val$"); } } [Fact] public void CanSetAndReadUnicodeStringValue() { string path = CloneStandardTestRepo(); using (var repo = new Repository(path)) { repo.Config.Set("unittests.stringsetting", "Juliën"); AssertValueInLocalConfigFile(path, "stringsetting = Juliën$"); string val = repo.Config.Get("unittests.stringsetting").Value; Assert.Equal("Juliën", val); } // Make sure the change is permanent using (var repo = new Repository(path)) { string val = repo.Config.Get("unittests.stringsetting").Value; Assert.Equal("Juliën", val); } } [Fact] public void ReadingUnsupportedTypeThrows() { using (var repo = new Repository(StandardTestRepoPath)) { Assert.Throws(() => repo.Config.Get("unittests.setting")); Assert.Throws(() => repo.Config.Get("unittests.setting")); } } [Fact] public void ReadingValueThatDoesntExistReturnsNull() { using (var repo = new Repository(StandardTestRepoPath)) { Assert.Null(repo.Config.Get("unittests.ghostsetting")); Assert.Null(repo.Config.Get("unittests.ghostsetting")); Assert.Null(repo.Config.Get("unittests.ghostsetting")); Assert.Null(repo.Config.Get("unittests.ghostsetting")); } } [Fact] public void SettingUnsupportedTypeThrows() { using (var repo = new Repository(StandardTestRepoPath)) { Assert.Throws(() => repo.Config.Set("unittests.setting", (short)123)); Assert.Throws(() => repo.Config.Set("unittests.setting", repo.Config)); } } [Fact] public void CanGetAnEntryFromASpecificStore() { SelfCleaningDirectory scd = BuildSelfCleaningDirectory(); var options = BuildFakeConfigs(scd); string path = CloneStandardTestRepo(); using (var repo = new Repository(path, options)) { Assert.True(repo.Config.HasConfig(ConfigurationLevel.Local)); Assert.True(repo.Config.HasConfig(ConfigurationLevel.Global)); Assert.True(repo.Config.HasConfig(ConfigurationLevel.System)); Assert.Null(repo.Config.Get("Woot.global-rocks", ConfigurationLevel.Local)); repo.Config.Set("Woot.this-rocks", "local"); Assert.Equal("global", repo.Config.Get("Woot.this-rocks", ConfigurationLevel.Global).Value); Assert.Equal("xdg", repo.Config.Get("Woot.this-rocks", ConfigurationLevel.Xdg).Value); Assert.Equal("system", repo.Config.Get("Woot.this-rocks", ConfigurationLevel.System).Value); Assert.Equal("local", repo.Config.Get("Woot.this-rocks", ConfigurationLevel.Local).Value); } } [Fact] public void CanTellIfASpecificStoreContainsAKey() { SelfCleaningDirectory scd = BuildSelfCleaningDirectory(); var options = BuildFakeConfigs(scd); using (var repo = new Repository(BareTestRepoPath, options)) { Assert.True(repo.Config.HasConfig(ConfigurationLevel.System)); Assert.Null(repo.Config.Get("MCHammer.You-cant-touch-this", ConfigurationLevel.System)); } } } }