diff --git a/appveyor.yml b/appveyor.yml index 9bb74ce89..a5d0c4580 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -56,7 +56,6 @@ test: categories: except: - DoNotRunOnAppVeyor - - TimeSensitive artifacts: - path: unity\PackageProject type: zip diff --git a/src/GitHub.Api/Events/RepositoryWatcher.cs b/src/GitHub.Api/Events/RepositoryWatcher.cs index 6528b0d3a..cf7b4379a 100644 --- a/src/GitHub.Api/Events/RepositoryWatcher.cs +++ b/src/GitHub.Api/Events/RepositoryWatcher.cs @@ -14,12 +14,10 @@ interface IRepositoryWatcher : IDisposable event Action HeadChanged; event Action IndexChanged; event Action ConfigChanged; - event Action LocalBranchChanged; - event Action LocalBranchCreated; - event Action LocalBranchDeleted; + event Action RepositoryCommitted; event Action RepositoryChanged; - event Action RemoteBranchCreated; - event Action RemoteBranchDeleted; + event Action LocalBranchesChanged; + event Action RemoteBranchesChanged; void Initialize(); int CheckAndProcessEvents(); } @@ -39,12 +37,10 @@ class RepositoryWatcher : IRepositoryWatcher public event Action HeadChanged; public event Action IndexChanged; public event Action ConfigChanged; - public event Action LocalBranchChanged; - public event Action LocalBranchCreated; - public event Action LocalBranchDeleted; + public event Action RepositoryCommitted; public event Action RepositoryChanged; - public event Action RemoteBranchCreated; - public event Action RemoteBranchDeleted; + public event Action LocalBranchesChanged; + public event Action RemoteBranchesChanged; public RepositoryWatcher(IPlatform platform, RepositoryPathConfiguration paths, CancellationToken cancellationToken) { @@ -193,118 +189,17 @@ private int ProcessEvents(Event[] fileEvents) { events.Add(EventType.IndexChanged, null); } - else if (fileA.IsChildOf(paths.RemotesPath)) + else if (!events.ContainsKey(EventType.RemoteBranchesChanged) && fileA.IsChildOf(paths.RemotesPath)) { - var relativePath = fileA.RelativeTo(paths.RemotesPath); - var relativePathElements = relativePath.Elements.ToArray(); - - if (!relativePathElements.Any()) - { - continue; - } - - var origin = relativePathElements[0]; - - if (fileEvent.Type == sfw.net.EventType.DELETED) - { - if (fileA.ExtensionWithDot == ".lock") - { - continue; - } - - var branch = string.Join(@"/", relativePathElements.Skip(1).ToArray()); - AddOrUpdateEventData(events, EventType.RemoteBranchDeleted, new EventData { Origin = origin, Branch = branch }); - } - else if (fileEvent.Type == sfw.net.EventType.RENAMED) - { - if (fileA.ExtensionWithDot != ".lock") - { - continue; - } - - if (fileB != null && fileB.FileExists()) - { - if (fileA.FileNameWithoutExtension == fileB.FileNameWithoutExtension) - { - var branchPathElement = relativePathElements - .Skip(1).Take(relativePathElements.Length - 2) - .Union(new[] { fileA.FileNameWithoutExtension }).ToArray(); - - var branch = string.Join(@"/", branchPathElement); - AddOrUpdateEventData(events, EventType.RemoteBranchCreated, new EventData { Origin = origin, Branch = branch }); - } - } - } + events.Add(EventType.RemoteBranchesChanged, null); } - else if (fileA.IsChildOf(paths.BranchesPath)) + else if (!events.ContainsKey(EventType.LocalBranchesChanged) && fileA.IsChildOf(paths.BranchesPath)) { - if (fileEvent.Type == sfw.net.EventType.MODIFIED) - { - if (fileA.DirectoryExists()) - { - continue; - } - - if (fileA.ExtensionWithDot == ".lock") - { - continue; - } - - var relativePath = fileA.RelativeTo(paths.BranchesPath); - var relativePathElements = relativePath.Elements.ToArray(); - - if (!relativePathElements.Any()) - { - continue; - } - - var branch = string.Join(@"/", relativePathElements.ToArray()); - - AddOrUpdateEventData(events, EventType.LocalBranchChanged, new EventData { Branch = branch }); - - } - else if (fileEvent.Type == sfw.net.EventType.DELETED) - { - if (fileA.ExtensionWithDot == ".lock") - { - continue; - } - - var relativePath = fileA.RelativeTo(paths.BranchesPath); - var relativePathElements = relativePath.Elements.ToArray(); - - if (!relativePathElements.Any()) - { - continue; - } - - var branch = string.Join(@"/", relativePathElements.ToArray()); - AddOrUpdateEventData(events, EventType.LocalBranchDeleted, new EventData { Branch = branch }); - } - else if (fileEvent.Type == sfw.net.EventType.RENAMED) - { - if (fileA.ExtensionWithDot != ".lock") - { - continue; - } - - if (fileB != null && fileB.FileExists()) - { - if (fileA.FileNameWithoutExtension == fileB.FileNameWithoutExtension) - { - var relativePath = fileB.RelativeTo(paths.BranchesPath); - var relativePathElements = relativePath.Elements.ToArray(); - - if (!relativePathElements.Any()) - { - continue; - } - - var branch = string.Join(@"/", relativePathElements.ToArray()); - AddOrUpdateEventData(events, EventType.LocalBranchCreated, new EventData { Branch = branch }); - } - } - } + events.Add(EventType.LocalBranchesChanged, null); + } + else if (!events.ContainsKey(EventType.RepositoryCommitted) && fileA.IsChildOf(paths.DotGitCommitEditMsg)) + { + events.Add(EventType.RepositoryCommitted, null); } } else @@ -320,13 +215,6 @@ private int ProcessEvents(Event[] fileEvents) return FireEvents(events); } - private void AddOrUpdateEventData(Dictionary> events, EventType type, EventData data) - { - if (!events.ContainsKey(type)) - events.Add(type, new List()); - events[type].Add(data); - } - private int FireEvents(Dictionary> events) { int eventsProcessed = 0; @@ -344,74 +232,41 @@ private int FireEvents(Dictionary> events) eventsProcessed++; } - if (events.ContainsKey(EventType.IndexChanged)) + if (events.ContainsKey(EventType.LocalBranchesChanged)) { - Logger.Trace("IndexChanged"); - IndexChanged?.Invoke(); + Logger.Trace("LocalBranchesChanged"); + LocalBranchesChanged?.Invoke(); eventsProcessed++; } - if (events.ContainsKey(EventType.RepositoryChanged)) + if (events.ContainsKey(EventType.RemoteBranchesChanged)) { - Logger.Trace("RepositoryChanged"); - RepositoryChanged?.Invoke(); + Logger.Trace("RemoteBranchesChanged"); + RemoteBranchesChanged?.Invoke(); eventsProcessed++; } - List localBranchesCreated; - if (events.TryGetValue(EventType.LocalBranchCreated, out localBranchesCreated)) - { - foreach (var evt in localBranchesCreated) - { - Logger.Trace($"LocalBranchCreated: {evt.Branch}"); - LocalBranchCreated?.Invoke(evt.Branch); - eventsProcessed++; - } - } - - List localBranchesChanged; - if (events.TryGetValue(EventType.LocalBranchChanged, out localBranchesChanged)) + if (events.ContainsKey(EventType.IndexChanged)) { - foreach (var evt in localBranchesChanged) - { - Logger.Trace($"LocalBranchChanged: {evt.Branch}"); - LocalBranchChanged?.Invoke(evt.Branch); - eventsProcessed++; - } + Logger.Trace("IndexChanged"); + IndexChanged?.Invoke(); + eventsProcessed++; } - List localBranchesDeleted; - if (events.TryGetValue(EventType.LocalBranchDeleted, out localBranchesDeleted)) + if (events.ContainsKey(EventType.RepositoryChanged)) { - foreach (var evt in localBranchesDeleted) - { - Logger.Trace($"LocalBranchDeleted: {evt.Branch}"); - LocalBranchDeleted?.Invoke(evt.Branch); - eventsProcessed++; - } + Logger.Trace("RepositoryChanged"); + RepositoryChanged?.Invoke(); + eventsProcessed++; } - List remoteBranchesCreated; - if (events.TryGetValue(EventType.RemoteBranchCreated, out remoteBranchesCreated)) + if (events.ContainsKey(EventType.RepositoryCommitted)) { - foreach (var evt in remoteBranchesCreated) - { - Logger.Trace($"RemoteBranchCreated: {evt.Origin}/{evt.Branch}"); - RemoteBranchCreated?.Invoke(evt.Origin, evt.Branch); - eventsProcessed++; - } + Logger.Trace("RepositoryCommitted"); + RepositoryCommitted?.Invoke(); + eventsProcessed++; } - List remoteBranchesDeleted; - if (events.TryGetValue(EventType.RemoteBranchDeleted, out remoteBranchesDeleted)) - { - foreach (var evt in remoteBranchesDeleted) - { - Logger.Trace($"RemoteBranchDeleted: {evt.Origin}/{evt.Branch}"); - RemoteBranchDeleted?.Invoke(evt.Origin, evt.Branch); - eventsProcessed++; - } - } return eventsProcessed; } @@ -445,13 +300,11 @@ private enum EventType None, ConfigChanged, HeadChanged, - RepositoryChanged, IndexChanged, - RemoteBranchDeleted, - RemoteBranchCreated, - LocalBranchDeleted, - LocalBranchCreated, - LocalBranchChanged + LocalBranchesChanged, + RemoteBranchesChanged, + RepositoryChanged, + RepositoryCommitted } private class EventData diff --git a/src/GitHub.Api/Git/Repository.cs b/src/GitHub.Api/Git/Repository.cs index bb9ecbe68..adb749c5b 100644 --- a/src/GitHub.Api/Git/Repository.cs +++ b/src/GitHub.Api/Git/Repository.cs @@ -47,15 +47,11 @@ public void Initialize(IRepositoryManager initRepositoryManager) Guard.ArgumentNotNull(initRepositoryManager, nameof(initRepositoryManager)); repositoryManager = initRepositoryManager; - repositoryManager.OnCurrentBranchAndRemoteUpdated += RepositoryManager_OnCurrentBranchAndRemoteUpdated; - repositoryManager.OnRepositoryUpdated += RepositoryManager_OnRepositoryUpdated; - repositoryManager.OnLocalBranchListUpdated += RepositoryManager_OnLocalBranchListUpdated; - repositoryManager.OnRemoteBranchListUpdated += RepositoryManager_OnRemoteBranchListUpdated; - repositoryManager.OnLocalBranchUpdated += RepositoryManager_OnLocalBranchUpdated; - repositoryManager.OnLocalBranchAdded += RepositoryManager_OnLocalBranchAdded; - repositoryManager.OnLocalBranchRemoved += RepositoryManager_OnLocalBranchRemoved; - repositoryManager.OnRemoteBranchAdded += RepositoryManager_OnRemoteBranchAdded; - repositoryManager.OnRemoteBranchRemoved += RepositoryManager_OnRemoteBranchRemoved; + repositoryManager.CurrentBranchUpdated += RepositoryManagerOnCurrentBranchUpdated; + repositoryManager.GitStatusUpdated += RepositoryManagerOnGitStatusUpdated; + repositoryManager.GitLogUpdated += RepositoryManagerOnGitLogUpdated; + repositoryManager.LocalBranchesUpdated += RepositoryManagerOnLocalBranchesUpdated; + repositoryManager.RemoteBranchesUpdated += RepositoryManagerOnRemoteBranchesUpdated; } public ITask SetupRemote(string remote, string remoteUrl) @@ -89,8 +85,7 @@ public ITask Pull() public ITask Push() { - return repositoryManager.Push(CurrentRemote.Value.Name, CurrentBranch?.Name) - .Then(UpdateGitStatus); + return repositoryManager.Push(CurrentRemote.Value.Name, CurrentBranch?.Name); } public ITask Fetch() @@ -105,14 +100,12 @@ public ITask Revert(string changeset) public ITask RequestLock(string file) { - return repositoryManager.LockFile(file) - .Then(UpdateLocks); + return repositoryManager.LockFile(file); } public ITask ReleaseLock(string file, bool force) { - return repositoryManager.UnlockFile(file, force) - .Then(UpdateLocks); + return repositoryManager.UnlockFile(file, force); } public void CheckLogChangedEvent(CacheUpdateEvent cacheUpdateEvent) @@ -266,15 +259,15 @@ private void CacheContainer_OnCacheInvalidated(CacheType cacheType) break; case CacheType.GitLogCache: - UpdateGitLog(); + repositoryManager?.UpdateGitLog(); break; case CacheType.GitStatusCache: - UpdateGitStatus(); + repositoryManager?.UpdateGitStatus(); break; case CacheType.GitLocksCache: - UpdateLocks(); + repositoryManager?.UpdateLocks(); break; case CacheType.GitUserCache: @@ -355,38 +348,7 @@ private void HandleBranchCacheUpdatedEvent(CacheUpdateEvent cacheUpdateEvent) LocalAndRemoteBranchListChanged?.Invoke(cacheUpdateEvent); } - private void RepositoryManager_OnRepositoryUpdated() - { - Logger.Trace("OnRepositoryUpdated"); - UpdateGitStatus(); - UpdateGitLog(); - } - - private void UpdateGitStatus() - { - repositoryManager?.Status() - .ThenInUI((b, status) => { CurrentStatus = status; }) - .Start(); - } - - private void UpdateGitLog() - { - repositoryManager?.Log() - .ThenInUI((b, log) => { CurrentLog = log; }) - .Start(); - } - - private void UpdateLocks() - { - if (CurrentRemote.HasValue) - { - repositoryManager?.ListLocks(false) - .ThenInUI((b, locks) => { CurrentLocks = locks; }) - .Start(); - } - } - - private void RepositoryManager_OnCurrentBranchAndRemoteUpdated(ConfigBranch? branch, ConfigRemote? remote) + private void RepositoryManagerOnCurrentBranchUpdated(ConfigBranch? branch, ConfigRemote? remote) { new ActionTask(CancellationToken.None, () => { if (!Nullable.Equals(CurrentConfigBranch, branch)) @@ -407,32 +369,31 @@ private void RepositoryManager_OnCurrentBranchAndRemoteUpdated(ConfigBranch? bra }) { Affinity = TaskAffinity.UI }.Start(); } - private void RepositoryManager_OnLocalBranchUpdated(string name) + private void RepositoryManagerOnGitStatusUpdated(GitStatus gitStatus) { - if (name == CurrentConfigBranch?.Name) - { - UpdateGitStatus(); - UpdateGitLog(); - } + new ActionTask(CancellationToken.None, () => { + CurrentStatus = gitStatus; + }) { Affinity = TaskAffinity.UI }.Start(); } - private void RepositoryManager_OnRemoteBranchListUpdated(Dictionary remotes, - Dictionary> branches) + private void RepositoryManagerOnGitLogUpdated(List gitLogEntries) { new ActionTask(CancellationToken.None, () => { - cacheContainer.BranchCache.SetRemotes(remotes, branches); - UpdateRemoteAndRemoteBranches(); + CurrentLog = gitLogEntries; }) { Affinity = TaskAffinity.UI }.Start(); } - private void UpdateRemoteAndRemoteBranches() + private void RepositoryManagerOnRemoteBranchesUpdated(Dictionary remotes, + Dictionary> branches) { - Remotes = ConfigRemotes.Values.Select(GetGitRemote).ToArray(); - - RemoteBranches = RemoteConfigBranches.Values.SelectMany(x => x.Values).Select(GetRemoteGitBranch).ToArray(); + new ActionTask(CancellationToken.None, () => { + cacheContainer.BranchCache.SetRemotes(remotes, branches); + Remotes = ConfigRemotes.Values.Select(GetGitRemote).ToArray(); + RemoteBranches = RemoteConfigBranches.Values.SelectMany(x => x.Values).Select(GetRemoteGitBranch).ToArray(); + }) { Affinity = TaskAffinity.UI }.Start(); } - private void RepositoryManager_OnLocalBranchListUpdated(Dictionary branches) + private void RepositoryManagerOnLocalBranchesUpdated(Dictionary branches) { new ActionTask(CancellationToken.None, () => { cacheContainer.BranchCache.SetLocals(branches); @@ -451,38 +412,6 @@ private void ClearRepositoryInfo() Name = null; } - private void RepositoryManager_OnLocalBranchRemoved(string name) - { - new ActionTask(CancellationToken.None, () => { - cacheContainer.BranchCache.RemoveLocalBranch(name); - UpdateLocalBranches(); - }) { Affinity = TaskAffinity.UI }.Start(); - } - - private void RepositoryManager_OnLocalBranchAdded(string name) - { - new ActionTask(CancellationToken.None, () => { - cacheContainer.BranchCache.AddLocalBranch(name); - UpdateLocalBranches(); - }) { Affinity = TaskAffinity.UI }.Start(); - } - - private void RepositoryManager_OnRemoteBranchAdded(string remote, string name) - { - new ActionTask(CancellationToken.None, () => { - cacheContainer.BranchCache.AddRemoteBranch(remote, name); - UpdateRemoteAndRemoteBranches(); - }) { Affinity = TaskAffinity.UI }.Start(); - } - - private void RepositoryManager_OnRemoteBranchRemoved(string remote, string name) - { - new ActionTask(CancellationToken.None, () => { - cacheContainer.BranchCache.RemoveRemoteBranch(remote, name); - UpdateRemoteAndRemoteBranches(); - }) { Affinity = TaskAffinity.UI }.Start(); - } - private GitBranch GetLocalGitBranch(ConfigBranch x) { var name = x.Name; @@ -678,7 +607,6 @@ public void Initialize(IGitClient client) Logger.Trace("Initialize"); gitClient = client; - UpdateUserAndEmail(); } public void SetNameAndEmail(string name, string email) diff --git a/src/GitHub.Api/Git/RepositoryManager.cs b/src/GitHub.Api/Git/RepositoryManager.cs index f7b094456..9094d626c 100644 --- a/src/GitHub.Api/Git/RepositoryManager.cs +++ b/src/GitHub.Api/Git/RepositoryManager.cs @@ -8,24 +8,19 @@ namespace GitHub.Unity { public interface IRepositoryManager : IDisposable { - event Action OnCurrentBranchAndRemoteUpdated; - event Action OnIsBusyChanged; - event Action OnLocalBranchAdded; - event Action> OnLocalBranchListUpdated; - event Action OnLocalBranchRemoved; - event Action OnLocalBranchUpdated; - event Action OnRemoteBranchAdded; - event Action, Dictionary>> OnRemoteBranchListUpdated; - event Action OnRemoteBranchRemoved; - event Action OnRepositoryUpdated; + event Action IsBusyChanged; + event Action CurrentBranchUpdated; + event Action GitStatusUpdated; + event Action> GitLocksUpdated; + event Action> GitLogUpdated; + event Action> LocalBranchesUpdated; + event Action, Dictionary>> RemoteBranchesUpdated; void Initialize(); void Start(); void Stop(); ITask CommitAllFiles(string message, string body); ITask CommitFiles(List files, string message, string body); - ITask> Log(); - ITask Status(); ITask Fetch(string remote); ITask Pull(string remote, string branch); ITask Push(string remote, string branch); @@ -36,9 +31,11 @@ public interface IRepositoryManager : IDisposable ITask SwitchBranch(string branch); ITask DeleteBranch(string branch, bool deleteUnmerged = false); ITask CreateBranch(string branch, string baseBranch); - ITask> ListLocks(bool local); ITask LockFile(string file); ITask UnlockFile(string file, bool force); + void UpdateGitLog(); + void UpdateGitStatus(); + void UpdateLocks(); int WaitForEvents(); IGitConfig Config { get; } @@ -78,6 +75,7 @@ public RepositoryPathConfiguration(NPath repositoryPath) DotGitIndex = DotGitPath.Combine("index"); DotGitHead = DotGitPath.Combine("HEAD"); DotGitConfig = DotGitPath.Combine("config"); + DotGitCommitEditMsg = DotGitPath.Combine("COMMIT_EDITMSG"); } public NPath RepositoryPath { get; } @@ -87,6 +85,7 @@ public RepositoryPathConfiguration(NPath repositoryPath) public NPath DotGitIndex { get; } public NPath DotGitHead { get; } public NPath DotGitConfig { get; } + public NPath DotGitCommitEditMsg { get; } } class RepositoryManager : IRepositoryManager @@ -99,16 +98,13 @@ class RepositoryManager : IRepositoryManager private bool isBusy; - public event Action OnCurrentBranchAndRemoteUpdated; - public event Action OnIsBusyChanged; - public event Action OnLocalBranchAdded; - public event Action> OnLocalBranchListUpdated; - public event Action OnLocalBranchRemoved; - public event Action OnLocalBranchUpdated; - public event Action OnRemoteBranchAdded; - public event Action, Dictionary>> OnRemoteBranchListUpdated; - public event Action OnRemoteBranchRemoved; - public event Action OnRepositoryUpdated; + public event Action CurrentBranchUpdated; + public event Action IsBusyChanged; + public event Action GitStatusUpdated; + public event Action> GitLocksUpdated; + public event Action> GitLogUpdated; + public event Action> LocalBranchesUpdated; + public event Action, Dictionary>> RemoteBranchesUpdated; public RepositoryManager(IPlatform platform, IGitConfig gitConfig, IRepositoryWatcher repositoryWatcher, IGitClient gitClient, @@ -185,18 +181,6 @@ public ITask CommitFiles(List files, string message, string body) return HookupHandlers(task, true, true); } - public ITask> Log() - { - var task = GitClient.Log(); - return HookupHandlers(task, false, false); - } - - public ITask Status() - { - var task = GitClient.Status(); - return HookupHandlers(task, true, false); - } - public ITask Fetch(string remote) { var task = GitClient.Fetch(remote); @@ -271,13 +255,6 @@ public ITask CreateBranch(string branch, string baseBranch) return HookupHandlers(task, true, false); } - public ITask> ListLocks(bool local) - { - var task = GitClient.ListLocks(local); - HookupHandlers(task, false, false); - return task; - } - public ITask LockFile(string file) { var task = GitClient.Lock(file); @@ -290,24 +267,43 @@ public ITask UnlockFile(string file, bool force) return HookupHandlers(task, true, false); } - private void SetupWatcher() + public void UpdateGitLog() + { + var task = GitClient.Log(); + task = HookupHandlers(task, false, false); + task.Then((success, logEntries) => + { + if (success) + { + GitLogUpdated?.Invoke(logEntries); + } + }).Start(); + } + + public void UpdateGitStatus() { - watcher.HeadChanged += Watcher_OnHeadChanged; - watcher.IndexChanged += Watcher_OnIndexChanged; - watcher.ConfigChanged += Watcher_OnConfigChanged; - watcher.LocalBranchChanged += Watcher_OnLocalBranchChanged; - watcher.LocalBranchCreated += Watcher_OnLocalBranchCreated; - watcher.LocalBranchDeleted += Watcher_OnLocalBranchDeleted; - watcher.RepositoryChanged += Watcher_OnRepositoryChanged; - watcher.RemoteBranchCreated += Watcher_OnRemoteBranchCreated; - watcher.RemoteBranchDeleted += Watcher_OnRemoteBranchDeleted; + var task = GitClient.Status(); + task = HookupHandlers(task, true, false); + task.Then((success, status) => + { + if (success) + { + GitStatusUpdated?.Invoke(status); + } + }).Start(); } - private void UpdateHead() + public void UpdateLocks() { - var head = repositoryPaths.DotGitHead.ReadAllLines().FirstOrDefault(); - Logger.Trace("UpdateHead: {0}", head ?? "[NULL]"); - UpdateCurrentBranchAndRemote(head); + var task = GitClient.ListLocks(false); + HookupHandlers(task, false, false); + task.Then((success, locks) => + { + if (success) + { + GitLocksUpdated?.Invoke(locks); + } + }).Start(); } private ITask HookupHandlers(ITask task, bool isExclusive, bool filesystemChangesExpected) @@ -348,31 +344,22 @@ private ITask HookupHandlers(ITask task, bool isExclusive, bool filesys }); } - private void Watcher_OnRemoteBranchDeleted(string remote, string name) - { - OnRemoteBranchRemoved?.Invoke(remote, name); - } - - private void Watcher_OnRemoteBranchCreated(string remote, string name) - { - OnRemoteBranchAdded?.Invoke(remote, name); - } - - private void Watcher_OnRepositoryChanged() - { - Logger.Trace("OnRepositoryChanged"); - OnRepositoryUpdated?.Invoke(); - } - - private void Watcher_OnConfigChanged() + private void SetupWatcher() { - UpdateConfigData(true); + watcher.HeadChanged += WatcherOnHeadChanged; + watcher.IndexChanged += WatcherOnIndexChanged; + watcher.ConfigChanged += WatcherOnConfigChanged; + watcher.RepositoryCommitted += WatcherOnRepositoryCommitted; + watcher.RepositoryChanged += WatcherOnRepositoryChanged; + watcher.LocalBranchesChanged += WatcherOnLocalBranchesChanged; + watcher.RemoteBranchesChanged += WatcherOnRemoteBranchesChanged; } - private void Watcher_OnHeadChanged() + private void UpdateHead() { - Logger.Trace("Watcher_OnHeadChanged"); - UpdateHead(); + var head = repositoryPaths.DotGitHead.ReadAllLines().FirstOrDefault(); + Logger.Trace("UpdateHead: {0}", head ?? "[NULL]"); + UpdateCurrentBranchAndRemote(head); } private void UpdateCurrentBranchAndRemote(string head) @@ -412,27 +399,51 @@ private void UpdateCurrentBranchAndRemote(string head) } } - Logger.Trace("OnCurrentBranchUpdated: {0}", branch.HasValue ? branch.Value.ToString() : "[NULL]"); - Logger.Trace("OnCurrentRemoteUpdated: {0}", remote.HasValue ? remote.Value.ToString() : "[NULL]"); - OnCurrentBranchAndRemoteUpdated?.Invoke(branch, remote); + Logger.Trace("CurrentBranch: {0}", branch.HasValue ? branch.Value.ToString() : "[NULL]"); + Logger.Trace("CurrentRemote: {0}", remote.HasValue ? remote.Value.ToString() : "[NULL]"); + CurrentBranchUpdated?.Invoke(branch, remote); + } + + private void WatcherOnRemoteBranchesChanged() + { + Logger.Trace("WatcherOnRemoteBranchesChanged"); + UpdateRemoteBranches(); + } + + private void WatcherOnLocalBranchesChanged() + { + Logger.Trace("WatcherOnLocalBranchesChanged"); + UpdateLocalBranches(); + } + + private void WatcherOnRepositoryCommitted() + { + Logger.Trace("WatcherOnRepositoryCommitted"); + UpdateGitLog(); } - private void Watcher_OnIndexChanged() - {} + private void WatcherOnRepositoryChanged() + { + Logger.Trace("WatcherOnRepositoryChanged"); + UpdateGitStatus(); + } - private void Watcher_OnLocalBranchCreated(string name) + private void WatcherOnConfigChanged() { - OnLocalBranchAdded?.Invoke(name); + Logger.Trace("WatcherOnConfigChanged"); + UpdateConfigData(true); } - private void Watcher_OnLocalBranchDeleted(string name) + private void WatcherOnHeadChanged() { - OnLocalBranchRemoved?.Invoke(name); + Logger.Trace("WatcherOnHeadChanged"); + UpdateHead(); } - private void Watcher_OnLocalBranchChanged(string name) + private void WatcherOnIndexChanged() { - OnLocalBranchUpdated?.Invoke(name); + Logger.Trace("WatcherOnIndexChanged"); + UpdateGitStatus(); } private void UpdateConfigData(bool resetConfig = false) @@ -444,23 +455,23 @@ private void UpdateConfigData(bool resetConfig = false) config.Reset(); } - LoadBranchesFromConfig(); - LoadRemotesFromConfig(); + UpdateLocalBranches(); + UpdateRemoteBranches(); UpdateHead(); } - private void LoadBranchesFromConfig() + private void UpdateLocalBranches() { - Logger.Trace("LoadBranchesFromConfig"); + Logger.Trace("UpdateLocalBranches"); var branches = new Dictionary(); - LoadBranchesFromConfig(branches, repositoryPaths.BranchesPath, config.GetBranches().Where(x => x.IsTracking), ""); + UpdateLocalBranches(branches, repositoryPaths.BranchesPath, config.GetBranches().Where(x => x.IsTracking), ""); Logger.Trace("OnLocalBranchListUpdated {0} branches", branches.Count); - OnLocalBranchListUpdated?.Invoke(branches); + LocalBranchesUpdated?.Invoke(branches); } - private void LoadBranchesFromConfig(Dictionary branches, NPath path, IEnumerable configBranches, string prefix) + private void UpdateLocalBranches(Dictionary branches, NPath path, IEnumerable configBranches, string prefix) { foreach (var file in path.Files()) { @@ -476,13 +487,13 @@ private void LoadBranchesFromConfig(Dictionary branches, N foreach (var dir in path.Directories()) { - LoadBranchesFromConfig(branches, dir, configBranches, prefix + dir.FileName + "/"); + UpdateLocalBranches(branches, dir, configBranches, prefix + dir.FileName + "/"); } } - private void LoadRemotesFromConfig() + private void UpdateRemoteBranches() { - Logger.Trace("LoadRemotesFromConfig"); + Logger.Trace("UpdateRemoteBranches"); var remotes = config.GetRemotes().ToArray().ToDictionary(x => x.Name, x => x); var remoteBranches = new Dictionary>(); @@ -506,7 +517,7 @@ private void LoadRemotesFromConfig() } Logger.Trace("OnRemoteBranchListUpdated {0} remotes", remotes.Count); - OnRemoteBranchListUpdated?.Invoke(remotes, remoteBranches); + RemoteBranchesUpdated?.Invoke(remotes, remoteBranches); } private bool disposed; @@ -542,7 +553,7 @@ private set { Logger.Trace("IsBusyChanged Value:{0}", value); isBusy = value; - OnIsBusyChanged?.Invoke(isBusy); + IsBusyChanged?.Invoke(isBusy); } } } diff --git a/src/GitHub.Logging/FileLogAdapter.cs b/src/GitHub.Logging/FileLogAdapter.cs index b2c228c9b..10df47350 100644 --- a/src/GitHub.Logging/FileLogAdapter.cs +++ b/src/GitHub.Logging/FileLogAdapter.cs @@ -16,7 +16,7 @@ public FileLogAdapter(string path) private string GetMessage(string level, string context, string message) { - var time = DateTime.Now.ToString("yyMMdd-HH:mm:ss"); + var time = DateTime.Now.ToString("yyMMdd-HH:mm:ss.fff"); var threadId = Thread.CurrentThread.ManagedThreadId; return string.Format("{0} {1,5} [{2,2}] {3,-35} {4}{5}", time, level, threadId, context, message, Environment.NewLine); } diff --git a/src/UnityExtension/Assets/Editor/GitHub.Unity/ApplicationCache.cs b/src/UnityExtension/Assets/Editor/GitHub.Unity/ApplicationCache.cs index 701f231f2..b61783ad6 100644 --- a/src/UnityExtension/Assets/Editor/GitHub.Unity/ApplicationCache.cs +++ b/src/UnityExtension/Assets/Editor/GitHub.Unity/ApplicationCache.cs @@ -132,8 +132,23 @@ protected ManagedCacheBase(bool invalidOnFirstRun) public void ValidateData() { - if (ApplicationCache.Instance.FirstRunAt > InitializedAt) + var initialized = ValidateInitialized(); + if (!initialized) { + if (DateTimeOffset.Now - LastUpdatedAt > DataTimeout) + { + Logger.Trace("Timeout Invalidation"); + InvalidateData(); + } + } + } + + private bool ValidateInitialized() + { + var notInitialized = ApplicationCache.Instance.FirstRunAt > InitializedAt; + if (notInitialized) + { + Logger.Trace("Initialized"); InitializedAt = DateTimeOffset.Now; Save(true); @@ -143,11 +158,8 @@ public void ValidateData() InvalidateData(); } } - else if (DateTimeOffset.Now - LastUpdatedAt > DataTimeout) - { - Logger.Trace("Timeout Invalidation"); - InvalidateData(); - } + + return notInitialized; } public void InvalidateData() @@ -189,6 +201,8 @@ public DateTimeOffset LastUpdatedAt { if (!lastUpdatedAtValue.HasValue) { + ValidateInitialized(); + DateTimeOffset result; if (DateTimeOffset.TryParseExact(LastUpdatedAtString, Constants.Iso8601Format, CultureInfo.InvariantCulture, DateTimeStyles.None, out result)) { @@ -215,6 +229,8 @@ public DateTimeOffset LastVerifiedAt { if (!lastVerifiedAtValue.HasValue) { + ValidateInitialized(); + DateTimeOffset result; if (DateTimeOffset.TryParseExact(LastVerifiedAtString, Constants.Iso8601Format, CultureInfo.InvariantCulture, DateTimeStyles.None, out result)) { diff --git a/src/tests/IntegrationTests/BaseGitEnvironmentTest.cs b/src/tests/IntegrationTests/BaseGitEnvironmentTest.cs index 892878acf..bed96b74b 100644 --- a/src/tests/IntegrationTests/BaseGitEnvironmentTest.cs +++ b/src/tests/IntegrationTests/BaseGitEnvironmentTest.cs @@ -1,3 +1,4 @@ +using System; using System.Linq; using System.Threading; using GitHub.Unity; @@ -9,7 +10,7 @@ namespace IntegrationTests class BaseGitEnvironmentTest : BaseGitRepoTest { protected async Task Initialize(NPath repoPath, NPath environmentPath = null, - bool enableEnvironmentTrace = false) + bool enableEnvironmentTrace = false, bool initializeRepository = true, Action onRepositoryManagerCreated = null) { TaskManager = new TaskManager(); SyncContext = new ThreadSynchronizationContext(TaskManager.Token); @@ -24,6 +25,7 @@ protected async Task Initialize(NPath repoPath, NPath environmentP Environment.GitExecutablePath = gitSetup.GitExecutablePath; Platform = new Platform(Environment); + GitEnvironment = Platform.GitEnvironment; ProcessManager = new ProcessManager(Environment, GitEnvironment, TaskManager.Token); @@ -31,11 +33,17 @@ protected async Task Initialize(NPath repoPath, NPath environmentP GitClient = new GitClient(Environment, ProcessManager, TaskManager); - RepositoryManager = GitHub.Unity.RepositoryManager.CreateInstance(Platform, TaskManager, GitClient, repoPath); + var repositoryManager = GitHub.Unity.RepositoryManager.CreateInstance(Platform, TaskManager, GitClient, repoPath); + onRepositoryManagerCreated?.Invoke(repositoryManager); + + RepositoryManager = repositoryManager; RepositoryManager.Initialize(); - Environment.Repository = new Repository(repoPath, cacheContainer); - Environment.Repository.Initialize(RepositoryManager); + if (initializeRepository) + { + Environment.Repository = new Repository(repoPath, cacheContainer); + Environment.Repository.Initialize(RepositoryManager); + } RepositoryManager.Start(); diff --git a/src/tests/IntegrationTests/BaseGitRepoTest.cs b/src/tests/IntegrationTests/BaseGitRepoTest.cs index 57ed1b536..b8131fb42 100644 --- a/src/tests/IntegrationTests/BaseGitRepoTest.cs +++ b/src/tests/IntegrationTests/BaseGitRepoTest.cs @@ -16,7 +16,9 @@ public override void OnSetup() TestRepoMasterDirtyUnsynchronized = TestBasePath.Combine("IOTestsRepo", "IOTestsRepo_master_dirty_unsync"); TestRepoMasterTwoRemotes = TestBasePath.Combine("IOTestsRepo", "IOTestsRepo_master_two_remotes"); + Logger.Trace("Extracting Zip File to {0}", TestBasePath); ZipHelper.ExtractZipFile(TestZipFilePath, TestBasePath.ToString(), CancellationToken.None); + Logger.Trace("Extracted Zip File"); } protected NPath TestRepoMasterCleanSynchronized { get; private set; } diff --git a/src/tests/IntegrationTests/Events/RepositoryManagerTests.cs b/src/tests/IntegrationTests/Events/RepositoryManagerTests.cs index 8d18690f8..8cf724f89 100644 --- a/src/tests/IntegrationTests/Events/RepositoryManagerTests.cs +++ b/src/tests/IntegrationTests/Events/RepositoryManagerTests.cs @@ -11,7 +11,7 @@ namespace IntegrationTests { - [TestFixture, Ignore] + [TestFixture, Category("DoNotRunOnAppVeyor")] class RepositoryManagerTests : BaseGitEnvironmentTest { private RepositoryManagerEvents repositoryManagerEvents; @@ -23,848 +23,581 @@ public override void OnSetup() } [Test] - public async Task ShouldDoNothingOnInitialize() + public async Task ShouldPerformBasicInitialize() { - await Initialize(TestRepoMasterCleanSynchronized); - - var repositoryManagerListener = Substitute.For(); - repositoryManagerListener.AttachListener(RepositoryManager, repositoryManagerEvents); - - RepositoryManager.WaitForEvents(); - repositoryManagerEvents.WaitForNotBusy(2); - - repositoryManagerListener.AssertDidNotReceiveAnyCalls(); - - Repository.Name.Should().Be("IOTestsRepo"); - Repository.CloneUrl.ToString().Should().Be("https://github.com/EvilStanleyGoldman/IOTestsRepo.git"); - Repository.Owner.Should().Be("EvilStanleyGoldman"); - Repository.LocalPath.Should().Be(TestRepoMasterCleanSynchronized); - Repository.IsGitHub.Should().BeTrue(); - Repository.CurrentBranchName.Should().Be("master"); - Repository.CurrentBranch.HasValue.Should().BeTrue(); - Repository.CurrentBranch.Value.Name.Should().Be("master"); - Repository.CurrentRemote.HasValue.Should().BeTrue(); - Repository.CurrentRemote.Value.Name.Should().Be("origin"); - Repository.CurrentRemote.Value.Url.Should().Be("https://github.com/EvilStanleyGoldman/IOTestsRepo.git"); - Repository.LocalBranches.Should().BeEquivalentTo(new[] { - new GitBranch("master", "origin/master", true), - new GitBranch("feature/document", "origin/feature/document", false), - new GitBranch("feature/other-feature", "origin/feature/other-feature", false), - }); - Repository.Remotes.Should().BeEquivalentTo(new GitRemote("origin", "https://github.com/EvilStanleyGoldman/IOTestsRepo.git")); - Repository.RemoteBranches.Should().BeEquivalentTo(new[] { - new GitBranch("origin/master", "[None]", false), - new GitBranch("origin/feature/document-2", "[None]", false), - new GitBranch("origin/feature/other-feature", "[None]", false), - }); + Logger.Trace("Starting ShouldPerformBasicInitialize"); + + try + { + var repositoryManagerListener = Substitute.For(); + + await Initialize(TestRepoMasterCleanSynchronized, initializeRepository: false, + onRepositoryManagerCreated: manager => { + repositoryManagerListener.AttachListener(manager, repositoryManagerEvents); + }); + + repositoryManagerEvents.CurrentBranchUpdated.WaitOne(TimeSpan.FromSeconds(20)).Should().BeTrue(); + repositoryManagerEvents.LocalBranchesUpdated.WaitOne(TimeSpan.FromSeconds(20)).Should().BeTrue(); + repositoryManagerEvents.RemoteBranchesUpdated.WaitOne(TimeSpan.FromSeconds(20)).Should().BeTrue(); + + repositoryManagerListener.DidNotReceive().OnIsBusyChanged(Args.Bool); + repositoryManagerListener.Received().CurrentBranchUpdated(Args.NullableConfigBranch, Args.NullableConfigRemote); + repositoryManagerListener.DidNotReceive().GitStatusUpdated(Args.GitStatus); + repositoryManagerListener.DidNotReceive().GitLocksUpdated(Args.GitLocks); + repositoryManagerListener.DidNotReceive().GitLogUpdated(Args.GitLogs); + repositoryManagerListener.Received().LocalBranchesUpdated(Args.LocalBranchDictionary); + repositoryManagerListener.Received().RemoteBranchesUpdated(Args.RemoteDictionary, Args.RemoteBranchDictionary); + } + finally + { + Logger.Trace("Ending ShouldPerformBasicInitialize"); + } } [Test] public async Task ShouldDetectFileChanges() { - await Initialize(TestRepoMasterCleanSynchronized); - - var repositoryManagerListener = Substitute.For(); - repositoryManagerListener.AttachListener(RepositoryManager, repositoryManagerEvents); - - var expected = new GitStatus { - Behind = 1, - LocalBranch = "master", - RemoteBranch = "origin/master", - Entries = - new List { - new GitStatusEntry("foobar.txt", TestRepoMasterCleanSynchronized.Combine("foobar.txt"), - "foobar.txt", GitFileStatus.Untracked) - } - }; - - var result = new GitStatus(); - //TODO: Figure this out - //Environment.Repository.OnStatusChanged += status => { result = status; }; - - var foobarTxt = TestRepoMasterCleanSynchronized.Combine("foobar.txt"); - foobarTxt.WriteAllText("foobar"); - - await TaskManager.Wait(); - RepositoryManager.WaitForEvents(); - repositoryManagerEvents.WaitForNotBusy(); - repositoryManagerEvents.WaitForStatusUpdated(); - - repositoryManagerListener.Received().OnIsBusyChanged(Args.Bool); - repositoryManagerListener.Received().OnStatusUpdated(Args.GitStatus); - repositoryManagerListener.DidNotReceive().OnLocksUpdated(Args.EnumerableGitLock); - repositoryManagerListener.DidNotReceive().OnCurrentBranchAndRemoteUpdated(Arg.Any(), Arg.Any()); - repositoryManagerListener.DidNotReceive().OnLocalBranchListUpdated(Arg.Any>()); - repositoryManagerListener.DidNotReceive().OnRemoteBranchListUpdated(Arg.Any>(), Arg.Any>>()); - repositoryManagerListener.DidNotReceive().OnLocalBranchUpdated(Args.String); - repositoryManagerListener.DidNotReceive().OnLocalBranchAdded(Args.String); - repositoryManagerListener.DidNotReceive().OnLocalBranchRemoved(Args.String); - repositoryManagerListener.DidNotReceive().OnRemoteBranchAdded(Args.String, Args.String); - repositoryManagerListener.DidNotReceive().OnRemoteBranchRemoved(Args.String, Args.String); - - result.AssertEqual(expected); + Logger.Trace("Starting ShouldDetectFileChanges"); + + try + { + var repositoryManagerListener = Substitute.For(); + + await Initialize(TestRepoMasterCleanSynchronized, initializeRepository: false, + onRepositoryManagerCreated: manager => { + repositoryManagerListener.AttachListener(manager, repositoryManagerEvents); + }); + + repositoryManagerEvents.CurrentBranchUpdated.WaitOne(TimeSpan.FromSeconds(20)).Should().BeTrue(); + repositoryManagerEvents.LocalBranchesUpdated.WaitOne(TimeSpan.FromSeconds(20)).Should().BeTrue(); + repositoryManagerEvents.RemoteBranchesUpdated.WaitOne(TimeSpan.FromSeconds(20)).Should().BeTrue(); + + repositoryManagerListener.ClearReceivedCalls(); + + var foobarTxt = TestRepoMasterCleanSynchronized.Combine("foobar.txt"); + foobarTxt.WriteAllText("foobar"); + + await TaskManager.Wait(); + + RepositoryManager.WaitForEvents(); + repositoryManagerEvents.WaitForNotBusy(); + + repositoryManagerEvents.GitStatusUpdated.WaitOne(TimeSpan.FromSeconds(20)).Should().BeTrue(); + + repositoryManagerListener.Received().OnIsBusyChanged(Args.Bool); + repositoryManagerListener.DidNotReceive().CurrentBranchUpdated(Args.NullableConfigBranch, Args.NullableConfigRemote); + repositoryManagerListener.Received().GitStatusUpdated(Args.GitStatus); + repositoryManagerListener.DidNotReceive().GitLocksUpdated(Args.GitLocks); + repositoryManagerListener.DidNotReceive().GitLogUpdated(Args.GitLogs); + repositoryManagerListener.DidNotReceive().LocalBranchesUpdated(Args.LocalBranchDictionary); + repositoryManagerListener.DidNotReceive().RemoteBranchesUpdated(Args.RemoteDictionary, Args.RemoteBranchDictionary); + } + finally + { + Logger.Trace("Ending ShouldDetectFileChanges"); + } } [Test] public async Task ShouldAddAndCommitFiles() { - await Initialize(TestRepoMasterCleanSynchronized); - - var repositoryManagerListener = Substitute.For(); - repositoryManagerListener.AttachListener(RepositoryManager, repositoryManagerEvents); - - var expectedLocalBranch = "master"; - var expectedAfterChanges = new GitStatus { - Behind = 1, - LocalBranch = expectedLocalBranch, - RemoteBranch = "origin/master", - Entries = - new List { - new GitStatusEntry("Assets\\TestDocument.txt", - TestRepoMasterCleanSynchronized.Combine("Assets", "TestDocument.txt"), - "Assets\\TestDocument.txt", GitFileStatus.Modified), - new GitStatusEntry("foobar.txt", TestRepoMasterCleanSynchronized.Combine("foobar.txt"), - "foobar.txt", GitFileStatus.Untracked) - } - }; - - var result = new GitStatus(); - //RepositoryManager.OnStatusUpdated += status => { result = status; }; - - var foobarTxt = TestRepoMasterCleanSynchronized.Combine("foobar.txt"); - foobarTxt.WriteAllText("foobar"); - - var testDocumentTxt = TestRepoMasterCleanSynchronized.Combine("Assets", "TestDocument.txt"); - testDocumentTxt.WriteAllText("foobar"); - - await TaskManager.Wait(); - - //Intentionally wait two cycles, in case the first cycle did not pick up all events - RepositoryManager.WaitForEvents(); - repositoryManagerEvents.WaitForNotBusy(); - repositoryManagerEvents.WaitForStatusUpdated(); - - RepositoryManager.WaitForEvents(); - repositoryManagerEvents.WaitForNotBusy(); - repositoryManagerEvents.WaitForStatusUpdated(); - - repositoryManagerListener.Received().OnIsBusyChanged(Args.Bool); - repositoryManagerListener.Received().OnStatusUpdated(Args.GitStatus); - repositoryManagerListener.DidNotReceive().OnLocksUpdated(Args.EnumerableGitLock); - repositoryManagerListener.DidNotReceive().OnCurrentBranchAndRemoteUpdated(Arg.Any(), Arg.Any()); - repositoryManagerListener.DidNotReceive().OnLocalBranchListUpdated(Arg.Any>()); - repositoryManagerListener.DidNotReceive().OnRemoteBranchListUpdated(Arg.Any>(), Arg.Any>>()); - repositoryManagerListener.DidNotReceive().OnLocalBranchUpdated(Args.String); - repositoryManagerListener.DidNotReceive().OnLocalBranchAdded(Args.String); - repositoryManagerListener.DidNotReceive().OnLocalBranchRemoved(Args.String); - repositoryManagerListener.DidNotReceive().OnRemoteBranchAdded(Args.String, Args.String); - repositoryManagerListener.DidNotReceive().OnRemoteBranchRemoved(Args.String, Args.String); - - result.AssertEqual(expectedAfterChanges); - - repositoryManagerListener.ClearReceivedCalls(); - repositoryManagerEvents.Reset(); - - await RepositoryManager - .CommitFiles(new List { "Assets\\TestDocument.txt", "foobar.txt" }, "IntegrationTest Commit", string.Empty) - .StartAsAsync(); - - await TaskManager.Wait(); - RepositoryManager.WaitForEvents(); - repositoryManagerEvents.WaitForNotBusy(); - - repositoryManagerListener.Received().OnIsBusyChanged(Args.Bool); - repositoryManagerListener.DidNotReceive().OnStatusUpdated(Args.GitStatus); - repositoryManagerListener.DidNotReceive().OnLocksUpdated(Args.EnumerableGitLock); - repositoryManagerListener.DidNotReceive().OnCurrentBranchAndRemoteUpdated(Arg.Any(), Arg.Any()); - repositoryManagerListener.DidNotReceive().OnLocalBranchListUpdated(Arg.Any>()); - repositoryManagerListener.DidNotReceive().OnRemoteBranchListUpdated(Arg.Any>(), Arg.Any>>()); - repositoryManagerListener.Received().OnLocalBranchUpdated(expectedLocalBranch); - repositoryManagerListener.DidNotReceive().OnLocalBranchAdded(Args.String); - repositoryManagerListener.DidNotReceive().OnLocalBranchRemoved(Args.String); - repositoryManagerListener.DidNotReceive().OnRemoteBranchAdded(Args.String, Args.String); - repositoryManagerListener.DidNotReceive().OnRemoteBranchRemoved(Args.String, Args.String); + Logger.Trace("Starting ShouldAddAndCommitFiles"); + + try + { + var repositoryManagerListener = Substitute.For(); + + await Initialize(TestRepoMasterCleanSynchronized, initializeRepository: false, + onRepositoryManagerCreated: manager => { + repositoryManagerListener.AttachListener(manager, repositoryManagerEvents); + }); + + repositoryManagerEvents.CurrentBranchUpdated.WaitOne(TimeSpan.FromSeconds(20)).Should().BeTrue(); + repositoryManagerEvents.LocalBranchesUpdated.WaitOne(TimeSpan.FromSeconds(20)).Should().BeTrue(); + repositoryManagerEvents.RemoteBranchesUpdated.WaitOne(TimeSpan.FromSeconds(20)).Should().BeTrue(); + + repositoryManagerListener.ClearReceivedCalls(); + + var foobarTxt = TestRepoMasterCleanSynchronized.Combine("foobar.txt"); + foobarTxt.WriteAllText("foobar"); + + var testDocumentTxt = TestRepoMasterCleanSynchronized.Combine("Assets", "TestDocument.txt"); + testDocumentTxt.WriteAllText("foobar"); + + await TaskManager.Wait(); + + RepositoryManager.WaitForEvents(); + repositoryManagerEvents.WaitForNotBusy(); + + repositoryManagerEvents.GitStatusUpdated.WaitOne(TimeSpan.FromSeconds(20)).Should().BeTrue(); + + repositoryManagerListener.Received().OnIsBusyChanged(Args.Bool); + repositoryManagerListener.DidNotReceive().CurrentBranchUpdated(Args.NullableConfigBranch, Args.NullableConfigRemote); + repositoryManagerListener.Received().GitStatusUpdated(Args.GitStatus); + repositoryManagerListener.DidNotReceive().GitLocksUpdated(Args.GitLocks); + repositoryManagerListener.DidNotReceive().GitLogUpdated(Args.GitLogs); + repositoryManagerListener.DidNotReceive().LocalBranchesUpdated(Args.LocalBranchDictionary); + repositoryManagerListener.DidNotReceive().RemoteBranchesUpdated(Args.RemoteDictionary, Args.RemoteBranchDictionary); + repositoryManagerListener.ClearReceivedCalls(); + + repositoryManagerEvents.Reset(); + + await RepositoryManager + .CommitFiles(new List { "Assets\\TestDocument.txt", "foobar.txt" }, "IntegrationTest Commit", string.Empty) + .StartAsAsync(); + await TaskManager.Wait(); + + RepositoryManager.WaitForEvents(); + repositoryManagerEvents.WaitForNotBusy(); + + repositoryManagerEvents.LocalBranchesUpdated.WaitOne(TimeSpan.FromSeconds(20)).Should().BeTrue(); + repositoryManagerEvents.GitStatusUpdated.WaitOne(TimeSpan.FromSeconds(20)).Should().BeTrue(); + repositoryManagerEvents.GitLogUpdated.WaitOne(TimeSpan.FromSeconds(20)).Should().BeTrue(); + + repositoryManagerListener.Received().OnIsBusyChanged(Args.Bool); + repositoryManagerListener.DidNotReceive().CurrentBranchUpdated(Args.NullableConfigBranch, Args.NullableConfigRemote); + repositoryManagerListener.Received().GitStatusUpdated(Args.GitStatus); + repositoryManagerListener.DidNotReceive().GitLocksUpdated(Args.GitLocks); + repositoryManagerListener.Received().GitLogUpdated(Args.GitLogs); + repositoryManagerListener.Received().LocalBranchesUpdated(Args.LocalBranchDictionary); + repositoryManagerListener.DidNotReceive().RemoteBranchesUpdated(Args.RemoteDictionary, Args.RemoteBranchDictionary); + } + finally + { + Logger.Trace("Ending ShouldAddAndCommitFiles"); + } } - [Test, Ignore("Fails often")] + [Test] public async Task ShouldAddAndCommitAllFiles() { - await Initialize(TestRepoMasterCleanSynchronized); - - var repositoryManagerListener = Substitute.For(); - repositoryManagerListener.AttachListener(RepositoryManager, repositoryManagerEvents); - - var expectedLocalBranch = "master"; - var expectedAfterChanges = new GitStatus { - Behind = 1, - LocalBranch = expectedLocalBranch, - RemoteBranch = "origin/master", - Entries = - new List { - new GitStatusEntry("Assets\\TestDocument.txt", - TestRepoMasterCleanSynchronized.Combine("Assets", "TestDocument.txt"), - "Assets\\TestDocument.txt", GitFileStatus.Modified), - new GitStatusEntry("foobar.txt", TestRepoMasterCleanSynchronized.Combine("foobar.txt"), - "foobar.txt", GitFileStatus.Untracked) - } - }; - - var result = new GitStatus(); - //TODO: Figure this out - //RepositoryManager.OnStatusUpdated += status => { result = status; }; - - var foobarTxt = TestRepoMasterCleanSynchronized.Combine("foobar.txt"); - foobarTxt.WriteAllText("foobar"); - - var testDocumentTxt = TestRepoMasterCleanSynchronized.Combine("Assets", "TestDocument.txt"); - testDocumentTxt.WriteAllText("foobar"); - - await TaskManager.Wait(); - RepositoryManager.WaitForEvents(); - repositoryManagerEvents.WaitForNotBusy(); - repositoryManagerEvents.WaitForStatusUpdated(); - - repositoryManagerListener.Received().OnIsBusyChanged(Args.Bool); - repositoryManagerListener.Received().OnStatusUpdated(Args.GitStatus); - repositoryManagerListener.DidNotReceive().OnLocksUpdated(Args.EnumerableGitLock); - repositoryManagerListener.DidNotReceive().OnCurrentBranchAndRemoteUpdated(Arg.Any(), Arg.Any()); - repositoryManagerListener.DidNotReceive().OnLocalBranchListUpdated(Arg.Any>()); - repositoryManagerListener.DidNotReceive().OnRemoteBranchListUpdated(Arg.Any>(), Arg.Any>>()); - repositoryManagerListener.DidNotReceive().OnLocalBranchUpdated(Args.String); - repositoryManagerListener.DidNotReceive().OnLocalBranchAdded(Args.String); - repositoryManagerListener.DidNotReceive().OnLocalBranchRemoved(Args.String); - repositoryManagerListener.DidNotReceive().OnRemoteBranchAdded(Args.String, Args.String); - repositoryManagerListener.DidNotReceive().OnRemoteBranchRemoved(Args.String, Args.String); - - result.AssertEqual(expectedAfterChanges); - - repositoryManagerListener.ClearReceivedCalls(); - repositoryManagerEvents.Reset(); - - await RepositoryManager - .CommitAllFiles("IntegrationTest Commit", string.Empty) - .StartAsAsync(); - - await TaskManager.Wait(); - RepositoryManager.WaitForEvents(); - repositoryManagerEvents.WaitForNotBusy(); - - repositoryManagerListener.Received().OnIsBusyChanged(Args.Bool); - repositoryManagerListener.DidNotReceive().OnStatusUpdated(Args.GitStatus); - repositoryManagerListener.DidNotReceive().OnLocksUpdated(Args.EnumerableGitLock); - repositoryManagerListener.DidNotReceive().OnCurrentBranchAndRemoteUpdated(Arg.Any(), Arg.Any()); - repositoryManagerListener.DidNotReceive().OnLocalBranchListUpdated(Arg.Any>()); - repositoryManagerListener.DidNotReceive().OnRemoteBranchListUpdated(Arg.Any>(), Arg.Any>>()); - repositoryManagerListener.Received().OnLocalBranchUpdated(expectedLocalBranch); - repositoryManagerListener.DidNotReceive().OnLocalBranchAdded(Args.String); - repositoryManagerListener.DidNotReceive().OnLocalBranchRemoved(Args.String); - repositoryManagerListener.DidNotReceive().OnRemoteBranchAdded(Args.String, Args.String); - repositoryManagerListener.DidNotReceive().OnRemoteBranchRemoved(Args.String, Args.String); + Logger.Trace("Starting ShouldAddAndCommitAllFiles"); + + try + { + var repositoryManagerListener = Substitute.For(); + + await Initialize(TestRepoMasterCleanSynchronized, initializeRepository: false, + onRepositoryManagerCreated: manager => { + repositoryManagerListener.AttachListener(manager, repositoryManagerEvents); + }); + + repositoryManagerEvents.CurrentBranchUpdated.WaitOne(TimeSpan.FromSeconds(20)).Should().BeTrue(); + repositoryManagerEvents.LocalBranchesUpdated.WaitOne(TimeSpan.FromSeconds(20)).Should().BeTrue(); + repositoryManagerEvents.RemoteBranchesUpdated.WaitOne(TimeSpan.FromSeconds(20)).Should().BeTrue(); + + repositoryManagerListener.ClearReceivedCalls(); + + var foobarTxt = TestRepoMasterCleanSynchronized.Combine("foobar.txt"); + foobarTxt.WriteAllText("foobar"); + + var testDocumentTxt = TestRepoMasterCleanSynchronized.Combine("Assets", "TestDocument.txt"); + testDocumentTxt.WriteAllText("foobar"); + + await TaskManager.Wait(); + + RepositoryManager.WaitForEvents(); + repositoryManagerEvents.WaitForNotBusy(); + + repositoryManagerEvents.GitStatusUpdated.WaitOne(TimeSpan.FromSeconds(20)).Should().BeTrue(); + + repositoryManagerListener.Received().OnIsBusyChanged(Args.Bool); + repositoryManagerListener.DidNotReceive().CurrentBranchUpdated(Args.NullableConfigBranch, Args.NullableConfigRemote); + repositoryManagerListener.Received().GitStatusUpdated(Args.GitStatus); + repositoryManagerListener.DidNotReceive().GitLocksUpdated(Args.GitLocks); + repositoryManagerListener.DidNotReceive().GitLogUpdated(Args.GitLogs); + repositoryManagerListener.DidNotReceive().LocalBranchesUpdated(Args.LocalBranchDictionary); + repositoryManagerListener.DidNotReceive().RemoteBranchesUpdated(Args.RemoteDictionary, Args.RemoteBranchDictionary); + + repositoryManagerListener.ClearReceivedCalls(); + repositoryManagerEvents.Reset(); + + await RepositoryManager + .CommitAllFiles("IntegrationTest Commit", string.Empty) + .StartAsAsync(); + await TaskManager.Wait(); + + RepositoryManager.WaitForEvents(); + repositoryManagerEvents.WaitForNotBusy(); + + repositoryManagerEvents.GitStatusUpdated.WaitOne(TimeSpan.FromSeconds(20)).Should().BeTrue(); + repositoryManagerEvents.LocalBranchesUpdated.WaitOne(TimeSpan.FromSeconds(20)).Should().BeTrue(); + + repositoryManagerListener.Received().OnIsBusyChanged(Args.Bool); + repositoryManagerListener.DidNotReceive().CurrentBranchUpdated(Args.NullableConfigBranch, Args.NullableConfigRemote); + repositoryManagerListener.Received().GitStatusUpdated(Args.GitStatus); + repositoryManagerListener.DidNotReceive().GitLocksUpdated(Args.GitLocks); + repositoryManagerListener.DidNotReceive().GitLogUpdated(Args.GitLogs); + repositoryManagerListener.Received().LocalBranchesUpdated(Args.LocalBranchDictionary); + repositoryManagerListener.DidNotReceive().RemoteBranchesUpdated(Args.RemoteDictionary, Args.RemoteBranchDictionary); + } + finally + { + Logger.Trace("Ending ShouldAddAndCommitAllFiles"); + } } [Test] public async Task ShouldDetectBranchChange() { - await Initialize(TestRepoMasterCleanSynchronized); - - var repositoryManagerListener = Substitute.For(); - repositoryManagerListener.AttachListener(RepositoryManager, repositoryManagerEvents); - - var expectedLocalBranch = "feature/document"; - var expected = new GitStatus { - LocalBranch = expectedLocalBranch, - RemoteBranch = "origin/feature/document", - Entries = new List() - }; - - var result = new GitStatus(); - //TODO: Figure this out - //RepositoryManager.OnStatusUpdated += status => { result = status; }; - - Logger.Trace("Starting test"); - - await RepositoryManager.SwitchBranch(expectedLocalBranch).StartAsAsync(); - - await TaskManager.Wait(); - RepositoryManager.WaitForEvents(); - repositoryManagerEvents.WaitForNotBusy(); - repositoryManagerEvents.WaitForStatusUpdated(); - - repositoryManagerListener.Received().OnIsBusyChanged(Args.Bool); - repositoryManagerListener.Received().OnStatusUpdated(Args.GitStatus); - repositoryManagerListener.DidNotReceive().OnLocksUpdated(Args.EnumerableGitLock); - repositoryManagerListener.Received().OnCurrentBranchAndRemoteUpdated(Arg.Any(), Arg.Any()); - repositoryManagerListener.DidNotReceive().OnLocalBranchListUpdated(Arg.Any>()); - repositoryManagerListener.DidNotReceive().OnRemoteBranchListUpdated(Arg.Any>(), Arg.Any>>()); - repositoryManagerListener.DidNotReceive().OnLocalBranchUpdated(Args.String); - repositoryManagerListener.DidNotReceive().OnLocalBranchAdded(Args.String); - repositoryManagerListener.DidNotReceive().OnLocalBranchRemoved(Args.String); - repositoryManagerListener.DidNotReceive().OnRemoteBranchAdded(Args.String, Args.String); - repositoryManagerListener.DidNotReceive().OnRemoteBranchRemoved(Args.String, Args.String); - - result.AssertEqual(expected); - - Repository.Name.Should().Be("IOTestsRepo"); - Repository.CloneUrl.ToString().Should().Be("https://github.com/EvilStanleyGoldman/IOTestsRepo.git"); - Repository.Owner.Should().Be("EvilStanleyGoldman"); - Repository.LocalPath.Should().Be(TestRepoMasterCleanSynchronized); - Repository.IsGitHub.Should().BeTrue(); - Repository.CurrentBranchName.Should().Be("feature/document"); - Repository.CurrentBranch.HasValue.Should().BeTrue(); - Repository.CurrentBranch.Value.Name.Should().Be("feature/document"); - Repository.CurrentRemote.HasValue.Should().BeTrue(); - Repository.CurrentRemote.Value.Name.Should().Be("origin"); - Repository.CurrentRemote.Value.Url.Should().Be("https://github.com/EvilStanleyGoldman/IOTestsRepo.git"); - Repository.LocalBranches.Should().BeEquivalentTo(new[] { - new GitBranch("master", "origin/master", false), - new GitBranch("feature/document", "origin/feature/document", true), - new GitBranch("feature/other-feature", "origin/feature/other-feature", false), - }); - Repository.Remotes.Should().BeEquivalentTo(new GitRemote("origin", "https://github.com/EvilStanleyGoldman/IOTestsRepo.git")); - Repository.RemoteBranches.Should().BeEquivalentTo(new[] { - new GitBranch("origin/master", "[None]", false), - new GitBranch("origin/feature/document-2", "[None]", false), - new GitBranch("origin/feature/other-feature", "[None]", false), - }); + Logger.Trace("Starting ShouldDetectBranchChange"); + + try + { + var repositoryManagerListener = Substitute.For(); + + await Initialize(TestRepoMasterCleanSynchronized, initializeRepository: false, + onRepositoryManagerCreated: manager => { + repositoryManagerListener.AttachListener(manager, repositoryManagerEvents); + }); + + repositoryManagerEvents.CurrentBranchUpdated.WaitOne(TimeSpan.FromSeconds(20)).Should().BeTrue(); + repositoryManagerEvents.LocalBranchesUpdated.WaitOne(TimeSpan.FromSeconds(20)).Should().BeTrue(); + repositoryManagerEvents.RemoteBranchesUpdated.WaitOne(TimeSpan.FromSeconds(20)).Should().BeTrue(); + + repositoryManagerListener.ClearReceivedCalls(); + + await RepositoryManager.SwitchBranch("feature/document").StartAsAsync(); + await TaskManager.Wait(); + + RepositoryManager.WaitForEvents(); + repositoryManagerEvents.WaitForNotBusy(); + + repositoryManagerEvents.CurrentBranchUpdated.WaitOne(TimeSpan.FromSeconds(2)).Should().BeTrue(); + + repositoryManagerListener.Received().OnIsBusyChanged(Args.Bool); + repositoryManagerListener.Received().CurrentBranchUpdated(Args.NullableConfigBranch, Args.NullableConfigRemote); + repositoryManagerListener.DidNotReceive().GitStatusUpdated(Args.GitStatus); + repositoryManagerListener.DidNotReceive().GitLocksUpdated(Args.GitLocks); + repositoryManagerListener.DidNotReceive().GitLogUpdated(Args.GitLogs); + repositoryManagerListener.DidNotReceive().LocalBranchesUpdated(Args.LocalBranchDictionary); + repositoryManagerListener.DidNotReceive().RemoteBranchesUpdated(Args.RemoteDictionary, Args.RemoteBranchDictionary); + } + finally + { + Logger.Trace("Ending ShouldDetectBranchChange"); + } } [Test] public async Task ShouldDetectBranchDelete() { - await Initialize(TestRepoMasterCleanSynchronized); - - var repositoryManagerListener = Substitute.For(); - repositoryManagerListener.AttachListener(RepositoryManager, repositoryManagerEvents); - - var deletedBranch = "feature/document"; - await RepositoryManager.DeleteBranch(deletedBranch, true).StartAsAsync(); - await TaskManager.Wait(); - RepositoryManager.WaitForEvents(); - repositoryManagerEvents.WaitForNotBusy(); - - repositoryManagerListener.Received().OnIsBusyChanged(Args.Bool); - repositoryManagerListener.DidNotReceive().OnStatusUpdated(Args.GitStatus); - repositoryManagerListener.DidNotReceive().OnLocksUpdated(Args.EnumerableGitLock); - repositoryManagerListener.Received().OnCurrentBranchAndRemoteUpdated(Arg.Any(), Arg.Any()); - repositoryManagerListener.Received().OnLocalBranchListUpdated(Arg.Any>()); - repositoryManagerListener.Received().OnRemoteBranchListUpdated(Arg.Any>(), Arg.Any>>()); - repositoryManagerListener.DidNotReceive().OnLocalBranchUpdated(Args.String); - repositoryManagerListener.DidNotReceive().OnLocalBranchAdded(Args.String); - repositoryManagerListener.Received().OnLocalBranchRemoved(deletedBranch); - repositoryManagerListener.DidNotReceive().OnRemoteBranchAdded(Args.String, Args.String); - repositoryManagerListener.DidNotReceive().OnRemoteBranchRemoved(Args.String, Args.String); - - Repository.Name.Should().Be("IOTestsRepo"); - Repository.CloneUrl.ToString().Should().Be("https://github.com/EvilStanleyGoldman/IOTestsRepo.git"); - Repository.Owner.Should().Be("EvilStanleyGoldman"); - Repository.LocalPath.Should().Be(TestRepoMasterCleanSynchronized); - Repository.IsGitHub.Should().BeTrue(); - Repository.CurrentBranchName.Should().Be("master"); - Repository.CurrentBranch.HasValue.Should().BeTrue(); - Repository.CurrentBranch.Value.Name.Should().Be("master"); - Repository.CurrentRemote.HasValue.Should().BeTrue(); - Repository.CurrentRemote.Value.Name.Should().Be("origin"); - Repository.CurrentRemote.Value.Url.Should().Be("https://github.com/EvilStanleyGoldman/IOTestsRepo.git"); - Repository.LocalBranches.Should().BeEquivalentTo(new[] { - new GitBranch("master", "origin/master", true), - new GitBranch("feature/other-feature", "origin/feature/other-feature", false), - }); - Repository.Remotes.Should().BeEquivalentTo(new GitRemote("origin","https://github.com/EvilStanleyGoldman/IOTestsRepo.git")); - Repository.RemoteBranches.Should().BeEquivalentTo(new[] { - new GitBranch("origin/master", "[None]", false), - new GitBranch("origin/feature/document-2", "[None]", false), - new GitBranch("origin/feature/other-feature", "[None]", false), - }); + Logger.Trace("Starting ShouldDetectBranchDelete"); + + try + { + var repositoryManagerListener = Substitute.For(); + + await Initialize(TestRepoMasterCleanSynchronized, initializeRepository: false, + onRepositoryManagerCreated: manager => { + repositoryManagerListener.AttachListener(manager, repositoryManagerEvents); + }); + + repositoryManagerEvents.CurrentBranchUpdated.WaitOne(TimeSpan.FromSeconds(20)).Should().BeTrue(); + repositoryManagerEvents.LocalBranchesUpdated.WaitOne(TimeSpan.FromSeconds(20)).Should().BeTrue(); + repositoryManagerEvents.RemoteBranchesUpdated.WaitOne(TimeSpan.FromSeconds(20)).Should().BeTrue(); + + repositoryManagerListener.ClearReceivedCalls(); + + await RepositoryManager.DeleteBranch("feature/document", true).StartAsAsync(); + await TaskManager.Wait(); + + RepositoryManager.WaitForEvents(); + repositoryManagerEvents.WaitForNotBusy(); + + repositoryManagerEvents.CurrentBranchUpdated.WaitOne(TimeSpan.FromSeconds(2)).Should().BeTrue(); + repositoryManagerEvents.LocalBranchesUpdated.WaitOne(TimeSpan.FromSeconds(2)).Should().BeTrue(); + repositoryManagerEvents.RemoteBranchesUpdated.WaitOne(TimeSpan.FromSeconds(2)).Should().BeTrue(); + + repositoryManagerListener.Received().OnIsBusyChanged(Args.Bool); + repositoryManagerListener.Received().CurrentBranchUpdated(Args.NullableConfigBranch, Args.NullableConfigRemote); + repositoryManagerListener.DidNotReceive().GitStatusUpdated(Args.GitStatus); + repositoryManagerListener.DidNotReceive().GitLocksUpdated(Args.GitLocks); + repositoryManagerListener.DidNotReceive().GitLogUpdated(Args.GitLogs); + repositoryManagerListener.Received().LocalBranchesUpdated(Args.LocalBranchDictionary); + repositoryManagerListener.Received().RemoteBranchesUpdated(Args.RemoteDictionary, Args.RemoteBranchDictionary); + } + finally + { + Logger.Trace("Ending ShouldDetectBranchDelete"); + } } [Test] public async Task ShouldDetectBranchCreate() { - await Initialize(TestRepoMasterCleanSynchronized); - - var repositoryManagerListener = Substitute.For(); - repositoryManagerListener.AttachListener(RepositoryManager, repositoryManagerEvents); - - var createdBranch1 = "feature/document2"; - await RepositoryManager.CreateBranch(createdBranch1, "feature/document").StartAsAsync(); - await TaskManager.Wait(); - RepositoryManager.WaitForEvents(); - repositoryManagerEvents.WaitForNotBusy(); - - repositoryManagerListener.Received().OnIsBusyChanged(Args.Bool); - repositoryManagerListener.DidNotReceive().OnStatusUpdated(Args.GitStatus); - repositoryManagerListener.DidNotReceive().OnLocksUpdated(Args.EnumerableGitLock); - repositoryManagerListener.DidNotReceive().OnCurrentBranchAndRemoteUpdated(Arg.Any(), Arg.Any()); - repositoryManagerListener.DidNotReceive().OnLocalBranchListUpdated(Arg.Any>()); - repositoryManagerListener.DidNotReceive().OnRemoteBranchListUpdated(Arg.Any>(), Arg.Any>>()); - repositoryManagerListener.DidNotReceive().OnLocalBranchUpdated(Args.String); - repositoryManagerListener.Received().OnLocalBranchAdded(createdBranch1); - repositoryManagerListener.DidNotReceive().OnLocalBranchRemoved(Args.String); - repositoryManagerListener.DidNotReceive().OnRemoteBranchAdded(Args.String, Args.String); - repositoryManagerListener.DidNotReceive().OnRemoteBranchRemoved(Args.String, Args.String); - - Repository.Name.Should().Be("IOTestsRepo"); - Repository.CloneUrl.ToString().Should().Be("https://github.com/EvilStanleyGoldman/IOTestsRepo.git"); - Repository.Owner.Should().Be("EvilStanleyGoldman"); - Repository.LocalPath.Should().Be(TestRepoMasterCleanSynchronized); - Repository.IsGitHub.Should().BeTrue(); - Repository.CurrentBranchName.Should().Be("master"); - Repository.CurrentBranch.HasValue.Should().BeTrue(); - Repository.CurrentBranch.Value.Name.Should().Be("master"); - Repository.CurrentRemote.HasValue.Should().BeTrue(); - Repository.CurrentRemote.Value.Name.Should().Be("origin"); - Repository.CurrentRemote.Value.Url.Should().Be("https://github.com/EvilStanleyGoldman/IOTestsRepo.git"); - Repository.LocalBranches.Should().BeEquivalentTo(new[] { - new GitBranch("master", "origin/master", true), - new GitBranch("feature/document", "origin/feature/document", false), - new GitBranch("feature/document2", "[None]", false), - new GitBranch("feature/other-feature", "origin/feature/other-feature", false), - }); - Repository.Remotes.Should().BeEquivalentTo(new GitRemote("origin","https://github.com/EvilStanleyGoldman/IOTestsRepo.git")); - Repository.RemoteBranches.Should().BeEquivalentTo(new[] { - new GitBranch("origin/master", "[None]", false), - new GitBranch("origin/feature/document-2", "[None]", false), - new GitBranch("origin/feature/other-feature", "[None]", false), - }); - - repositoryManagerListener.ClearReceivedCalls(); - repositoryManagerEvents.Reset(); - - var createdBranch2 = "feature2/document2"; - await RepositoryManager.CreateBranch(createdBranch2, "feature/document").StartAsAsync(); - await TaskManager.Wait(); - RepositoryManager.WaitForEvents(); - repositoryManagerEvents.WaitForNotBusy(); - - repositoryManagerListener.Received().OnIsBusyChanged(Args.Bool); - repositoryManagerListener.DidNotReceive().OnStatusUpdated(Args.GitStatus); - repositoryManagerListener.DidNotReceive().OnLocksUpdated(Args.EnumerableGitLock); - repositoryManagerListener.DidNotReceive().OnCurrentBranchAndRemoteUpdated(Arg.Any(), Arg.Any()); - repositoryManagerListener.DidNotReceive().OnLocalBranchListUpdated(Arg.Any>()); - repositoryManagerListener.DidNotReceive().OnRemoteBranchListUpdated(Arg.Any>(), Arg.Any>>()); - repositoryManagerListener.DidNotReceive().OnLocalBranchUpdated(Args.String); - repositoryManagerListener.Received().OnLocalBranchAdded(createdBranch2); - repositoryManagerListener.DidNotReceive().OnLocalBranchRemoved(Args.String); - repositoryManagerListener.DidNotReceive().OnRemoteBranchAdded(Args.String, Args.String); - repositoryManagerListener.DidNotReceive().OnRemoteBranchRemoved(Args.String, Args.String); - - Repository.Name.Should().Be("IOTestsRepo"); - Repository.CloneUrl.ToString().Should().Be("https://github.com/EvilStanleyGoldman/IOTestsRepo.git"); - Repository.Owner.Should().Be("EvilStanleyGoldman"); - Repository.LocalPath.Should().Be(TestRepoMasterCleanSynchronized); - Repository.IsGitHub.Should().BeTrue(); - Repository.CurrentBranchName.Should().Be("master"); - Repository.CurrentBranch.HasValue.Should().BeTrue(); - Repository.CurrentBranch.Value.Name.Should().Be("master"); - Repository.CurrentRemote.HasValue.Should().BeTrue(); - Repository.CurrentRemote.Value.Name.Should().Be("origin"); - Repository.CurrentRemote.Value.Url.Should().Be("https://github.com/EvilStanleyGoldman/IOTestsRepo.git"); - Repository.LocalBranches.Should().BeEquivalentTo(new[] { - new GitBranch("master", "origin/master", true), - new GitBranch("feature/document", "origin/feature/document", false), - new GitBranch("feature/document2", "[None]", false), - new GitBranch("feature2/document2", "[None]", false), - new GitBranch("feature/other-feature", "origin/feature/other-feature", false), - }); - Repository.Remotes.Should().BeEquivalentTo(new GitRemote("origin","https://github.com/EvilStanleyGoldman/IOTestsRepo.git")); - Repository.RemoteBranches.Should().BeEquivalentTo(new[] { - new GitBranch("origin/master", "[None]", false), - new GitBranch("origin/feature/document-2", "[None]", false), - new GitBranch("origin/feature/other-feature", "[None]", false), - }); + Logger.Trace("Starting ShouldDetectBranchCreate"); + + try + { + var repositoryManagerListener = Substitute.For(); + + await Initialize(TestRepoMasterCleanSynchronized, initializeRepository: false, + onRepositoryManagerCreated: manager => { + repositoryManagerListener.AttachListener(manager, repositoryManagerEvents); + }); + + repositoryManagerEvents.CurrentBranchUpdated.WaitOne(TimeSpan.FromSeconds(20)).Should().BeTrue(); + repositoryManagerEvents.LocalBranchesUpdated.WaitOne(TimeSpan.FromSeconds(20)).Should().BeTrue(); + repositoryManagerEvents.RemoteBranchesUpdated.WaitOne(TimeSpan.FromSeconds(20)).Should().BeTrue(); + + repositoryManagerListener.ClearReceivedCalls(); + + var createdBranch1 = "feature/document2"; + await RepositoryManager.CreateBranch(createdBranch1, "feature/document").StartAsAsync(); + await TaskManager.Wait(); + + RepositoryManager.WaitForEvents(); + repositoryManagerEvents.WaitForNotBusy(); + + repositoryManagerEvents.LocalBranchesUpdated.WaitOne(TimeSpan.FromSeconds(2)).Should().BeTrue(); + + repositoryManagerListener.Received().OnIsBusyChanged(Args.Bool); + repositoryManagerListener.DidNotReceive().CurrentBranchUpdated(Args.NullableConfigBranch, Args.NullableConfigRemote); + repositoryManagerListener.DidNotReceive().GitStatusUpdated(Args.GitStatus); + repositoryManagerListener.DidNotReceive().GitLocksUpdated(Args.GitLocks); + repositoryManagerListener.DidNotReceive().GitLogUpdated(Args.GitLogs); + repositoryManagerListener.Received().LocalBranchesUpdated(Args.LocalBranchDictionary); + repositoryManagerListener.DidNotReceive().RemoteBranchesUpdated(Args.RemoteDictionary, Args.RemoteBranchDictionary); + + repositoryManagerListener.ClearReceivedCalls(); + repositoryManagerEvents.Reset(); + + await RepositoryManager.CreateBranch("feature2/document2", "feature/document").StartAsAsync(); + await TaskManager.Wait(); + + RepositoryManager.WaitForEvents(); + repositoryManagerEvents.WaitForNotBusy(); + + repositoryManagerEvents.LocalBranchesUpdated.WaitOne(TimeSpan.FromSeconds(2)).Should().BeTrue(); + + repositoryManagerListener.Received().OnIsBusyChanged(Args.Bool); + repositoryManagerListener.DidNotReceive().CurrentBranchUpdated(Args.NullableConfigBranch, Args.NullableConfigRemote); + repositoryManagerListener.DidNotReceive().GitStatusUpdated(Args.GitStatus); + repositoryManagerListener.DidNotReceive().GitLocksUpdated(Args.GitLocks); + repositoryManagerListener.DidNotReceive().GitLogUpdated(Args.GitLogs); + repositoryManagerListener.Received().LocalBranchesUpdated(Args.LocalBranchDictionary); + repositoryManagerListener.DidNotReceive().RemoteBranchesUpdated(Args.RemoteDictionary, Args.RemoteBranchDictionary); + } + finally + { + Logger.Trace("Ending ShouldDetectBranchCreate"); + } } [Test] public async Task ShouldDetectChangesToRemotes() { - await Initialize(TestRepoMasterCleanSynchronized); - - var repositoryManagerListener = Substitute.For(); - repositoryManagerListener.AttachListener(RepositoryManager, repositoryManagerEvents); - - RepositoryManager.WaitForEvents(); - repositoryManagerEvents.WaitForNotBusy(2); - - repositoryManagerListener.AssertDidNotReceiveAnyCalls(); - - Repository.Name.Should().Be("IOTestsRepo"); - Repository.CloneUrl.ToString().Should().Be("https://github.com/EvilStanleyGoldman/IOTestsRepo.git"); - Repository.Owner.Should().Be("EvilStanleyGoldman"); - Repository.LocalPath.Should().Be(TestRepoMasterCleanSynchronized); - Repository.IsGitHub.Should().BeTrue(); - Repository.CurrentBranchName.Should().Be("master"); - Repository.CurrentBranch.HasValue.Should().BeTrue(); - Repository.CurrentBranch.Value.Name.Should().Be("master"); - Repository.CurrentRemote.HasValue.Should().BeTrue(); - Repository.CurrentRemote.Value.Name.Should().Be("origin"); - Repository.CurrentRemote.Value.Url.Should().Be("https://github.com/EvilStanleyGoldman/IOTestsRepo.git"); - Repository.LocalBranches.Should().BeEquivalentTo(new[] { - new GitBranch("master", "origin/master", true), - new GitBranch("feature/document", "origin/feature/document", false), - new GitBranch("feature/other-feature", "origin/feature/other-feature", false), - }); - Repository.Remotes.Should().BeEquivalentTo(new GitRemote("origin","https://github.com/EvilStanleyGoldman/IOTestsRepo.git")); - Repository.RemoteBranches.Should().BeEquivalentTo(new[] { - new GitBranch("origin/master", "[None]", false), - new GitBranch("origin/feature/document-2", "[None]", false), - new GitBranch("origin/feature/other-feature", "[None]", false), - }); - - await RepositoryManager.RemoteRemove("origin").StartAsAsync(); - await TaskManager.Wait(); - - RepositoryManager.WaitForEvents(); - repositoryManagerEvents.WaitForNotBusy(); - - repositoryManagerEvents.OnRemoteBranchListUpdated.WaitOne(TimeSpan.FromSeconds(1)); - repositoryManagerEvents.OnLocalBranchListUpdated.WaitOne(TimeSpan.FromSeconds(1)); - - repositoryManagerListener.Received().OnIsBusyChanged(Args.Bool); - repositoryManagerListener.DidNotReceive().OnStatusUpdated(Args.GitStatus); - repositoryManagerListener.DidNotReceive().OnLocksUpdated(Args.EnumerableGitLock); - repositoryManagerListener.Received().OnCurrentBranchAndRemoteUpdated(Arg.Any(), Arg.Any()); - repositoryManagerListener.Received().OnLocalBranchListUpdated(Arg.Any>()); - repositoryManagerListener.Received().OnRemoteBranchListUpdated(Arg.Any>(), Arg.Any>>()); - repositoryManagerListener.DidNotReceive().OnLocalBranchUpdated(Args.String); - repositoryManagerListener.DidNotReceive().OnLocalBranchAdded(Args.String); - repositoryManagerListener.DidNotReceive().OnLocalBranchRemoved(Args.String); - repositoryManagerListener.DidNotReceive().OnRemoteBranchAdded(Args.String, Args.String); - repositoryManagerListener.Received().OnRemoteBranchRemoved(Args.String, Args.String); - - Repository.Name.Should().Be("IOTestsRepo_master_clean_sync"); - Repository.CloneUrl.Should().BeNull(); - Repository.Owner.Should().BeNull(); - Repository.LocalPath.Should().Be(TestRepoMasterCleanSynchronized); - Repository.IsGitHub.Should().BeFalse(); - Repository.CurrentBranchName.Should().Be("master"); - Repository.CurrentBranch.HasValue.Should().BeTrue(); - Repository.CurrentBranch.Value.Name.Should().Be("master"); - Repository.CurrentRemote.HasValue.Should().BeFalse(); - Repository.Remotes.Should().BeEquivalentTo(); - Repository.RemoteBranches.Should().BeEmpty(); - - repositoryManagerListener.ClearReceivedCalls(); - repositoryManagerEvents.Reset(); - - await RepositoryManager.RemoteAdd("origin", "https://github.com/EvilShana/IOTestsRepo.git").StartAsAsync(); - await TaskManager.Wait(); - RepositoryManager.WaitForEvents(); - repositoryManagerEvents.WaitForNotBusy(); - repositoryManagerEvents.OnRemoteBranchListUpdated.WaitOne(TimeSpan.FromSeconds(1)); - repositoryManagerEvents.OnLocalBranchListUpdated.WaitOne(TimeSpan.FromSeconds(1)); - - repositoryManagerListener.Received().OnIsBusyChanged(Args.Bool); - repositoryManagerListener.DidNotReceive().OnStatusUpdated(Args.GitStatus); - repositoryManagerListener.DidNotReceive().OnLocksUpdated(Args.EnumerableGitLock); - repositoryManagerListener.Received().OnCurrentBranchAndRemoteUpdated(Arg.Any(), Arg.Any()); - repositoryManagerListener.Received().OnLocalBranchListUpdated(Arg.Any>()); - repositoryManagerListener.Received().OnRemoteBranchListUpdated(Arg.Any>(), Arg.Any>>()); - repositoryManagerListener.DidNotReceive().OnLocalBranchUpdated(Args.String); - repositoryManagerListener.DidNotReceive().OnLocalBranchAdded(Args.String); - repositoryManagerListener.DidNotReceive().OnLocalBranchRemoved(Args.String); - repositoryManagerListener.DidNotReceive().OnRemoteBranchAdded(Args.String, Args.String); - repositoryManagerListener.DidNotReceive().OnRemoteBranchRemoved(Args.String, Args.String); - - Repository.Name.Should().Be("IOTestsRepo"); - Repository.CloneUrl.ToString().Should().Be("https://github.com/EvilShana/IOTestsRepo.git"); - Repository.Owner.Should().Be("EvilShana"); - Repository.LocalPath.Should().Be(TestRepoMasterCleanSynchronized); - Repository.IsGitHub.Should().BeTrue(); - Repository.CurrentBranchName.Should().Be("master"); - Repository.CurrentBranch.HasValue.Should().BeTrue(); - Repository.CurrentBranch.Value.Name.Should().Be("master"); - Repository.CurrentRemote.HasValue.Should().BeTrue(); - Repository.CurrentRemote.Value.Name.Should().Be("origin"); - Repository.CurrentRemote.Value.Url.Should().Be("https://github.com/EvilShana/IOTestsRepo.git"); - Repository.LocalBranches.Should().BeEquivalentTo(new[] { - new GitBranch("master", "[None]", true), - new GitBranch("feature/document", "[None]", false), - new GitBranch("feature/other-feature", "[None]", false), - }); - Repository.Remotes.Should().BeEquivalentTo(new GitRemote("origin","https://github.com/EvilShana/IOTestsRepo.git")); - Repository.RemoteBranches.Should().BeEmpty(); + Logger.Trace("Starting ShouldDetectChangesToRemotes"); + + try + { + var repositoryManagerListener = Substitute.For(); + + await Initialize(TestRepoMasterCleanSynchronized, initializeRepository: false, + onRepositoryManagerCreated: manager => { + repositoryManagerListener.AttachListener(manager, repositoryManagerEvents); + }); + + repositoryManagerEvents.CurrentBranchUpdated.WaitOne(TimeSpan.FromSeconds(20)).Should().BeTrue(); + repositoryManagerEvents.LocalBranchesUpdated.WaitOne(TimeSpan.FromSeconds(20)).Should().BeTrue(); + repositoryManagerEvents.RemoteBranchesUpdated.WaitOne(TimeSpan.FromSeconds(20)).Should().BeTrue(); + + repositoryManagerListener.ClearReceivedCalls(); + + await RepositoryManager.RemoteRemove("origin").StartAsAsync(); + await TaskManager.Wait(); + + RepositoryManager.WaitForEvents(); + repositoryManagerEvents.WaitForNotBusy(); + + repositoryManagerEvents.CurrentBranchUpdated.WaitOne(TimeSpan.FromSeconds(2)).Should().BeTrue(); + repositoryManagerEvents.RemoteBranchesUpdated.WaitOne(TimeSpan.FromSeconds(2)).Should().BeTrue(); + repositoryManagerEvents.LocalBranchesUpdated.WaitOne(TimeSpan.FromSeconds(2)).Should().BeTrue(); + + repositoryManagerListener.Received().OnIsBusyChanged(Args.Bool); + repositoryManagerListener.Received().CurrentBranchUpdated(Args.NullableConfigBranch, Args.NullableConfigRemote); + repositoryManagerListener.DidNotReceive().GitStatusUpdated(Args.GitStatus); + repositoryManagerListener.DidNotReceive().GitLocksUpdated(Args.GitLocks); + repositoryManagerListener.DidNotReceive().GitLogUpdated(Args.GitLogs); + repositoryManagerListener.Received().LocalBranchesUpdated(Args.LocalBranchDictionary); + repositoryManagerListener.Received().RemoteBranchesUpdated(Args.RemoteDictionary, Args.RemoteBranchDictionary); + + repositoryManagerListener.ClearReceivedCalls(); + repositoryManagerEvents.Reset(); + + await RepositoryManager.RemoteAdd("origin", "https://github.com/EvilShana/IOTestsRepo.git").StartAsAsync(); + await TaskManager.Wait(); + + RepositoryManager.WaitForEvents(); + repositoryManagerEvents.WaitForNotBusy(); + + repositoryManagerEvents.CurrentBranchUpdated.WaitOne(TimeSpan.FromSeconds(2)).Should().BeTrue(); + repositoryManagerEvents.RemoteBranchesUpdated.WaitOne(TimeSpan.FromSeconds(2)).Should().BeTrue(); + repositoryManagerEvents.LocalBranchesUpdated.WaitOne(TimeSpan.FromSeconds(2)).Should().BeTrue(); + + repositoryManagerListener.Received().OnIsBusyChanged(Args.Bool); + repositoryManagerListener.Received().CurrentBranchUpdated(Args.NullableConfigBranch, Args.NullableConfigRemote); + repositoryManagerListener.DidNotReceive().GitStatusUpdated(Args.GitStatus); + repositoryManagerListener.DidNotReceive().GitLocksUpdated(Args.GitLocks); + repositoryManagerListener.DidNotReceive().GitLogUpdated(Args.GitLogs); + repositoryManagerListener.Received().LocalBranchesUpdated(Args.LocalBranchDictionary); + repositoryManagerListener.Received().RemoteBranchesUpdated(Args.RemoteDictionary, Args.RemoteBranchDictionary); + } + finally + { + Logger.Trace("Ending ShouldDetectChangesToRemotes"); + } } [Test] public async Task ShouldDetectChangesToRemotesWhenSwitchingBranches() { - await Initialize(TestRepoMasterTwoRemotes); - - var repositoryManagerListener = Substitute.For(); - repositoryManagerListener.AttachListener(RepositoryManager, repositoryManagerEvents); - - RepositoryManager.WaitForEvents(); - repositoryManagerEvents.WaitForNotBusy(2); - - repositoryManagerListener.AssertDidNotReceiveAnyCalls(); - - Repository.Name.Should().Be("IOTestsRepo"); - Repository.CloneUrl.ToString().Should().Be("https://github.com/EvilStanleyGoldman/IOTestsRepo.git"); - Repository.Owner.Should().Be("EvilStanleyGoldman"); - Repository.LocalPath.Should().Be(TestRepoMasterTwoRemotes); - Repository.IsGitHub.Should().BeTrue(); - Repository.CurrentBranchName.Should().Be("master"); - Repository.CurrentBranch.HasValue.Should().BeTrue(); - Repository.CurrentBranch.Value.Name.Should().Be("master"); - Repository.CurrentRemote.HasValue.Should().BeTrue(); - Repository.CurrentRemote.Value.Name.Should().Be("origin"); - Repository.CurrentRemote.Value.Url.Should().Be("https://github.com/EvilStanleyGoldman/IOTestsRepo.git"); - Repository.LocalBranches.Should().BeEquivalentTo(new[] { - new GitBranch("master", "origin/master", true), - new GitBranch("feature/document", "origin/feature/document", false), - new GitBranch("feature/other-feature", "origin/feature/other-feature", false), - }); - Repository.Remotes.Should().BeEquivalentTo( - new GitRemote("origin","https://github.com/EvilStanleyGoldman/IOTestsRepo.git"), - new GitRemote("another","https://another.remote/Owner/Url.git")); - Repository.RemoteBranches.Should().BeEquivalentTo(new[] { - new GitBranch("origin/master", "[None]", false), - new GitBranch("origin/feature/document-2", "[None]", false), - new GitBranch("origin/feature/other-feature", "[None]", false), - new GitBranch("another/master", "[None]", false), - new GitBranch("another/feature/document-2", "[None]", false), - new GitBranch("another/feature/other-feature", "[None]", false), - }); - - await RepositoryManager.CreateBranch("branch2", "another/master") - .StartAsAsync(); - - await TaskManager.Wait(); - RepositoryManager.WaitForEvents(); - repositoryManagerEvents.WaitForNotBusy(); - - repositoryManagerListener.Received().OnIsBusyChanged(Args.Bool); - repositoryManagerListener.DidNotReceive().OnStatusUpdated(Args.GitStatus); - repositoryManagerListener.DidNotReceive().OnLocksUpdated(Args.EnumerableGitLock); - repositoryManagerListener.Received().OnCurrentBranchAndRemoteUpdated(Arg.Any(), Arg.Any()); - repositoryManagerListener.Received().OnLocalBranchListUpdated(Arg.Any>()); - repositoryManagerListener.Received().OnRemoteBranchListUpdated(Arg.Any>(), Arg.Any>>()); - repositoryManagerListener.DidNotReceive().OnLocalBranchUpdated(Args.String); - repositoryManagerListener.Received().OnLocalBranchAdded(Args.String); - repositoryManagerListener.DidNotReceive().OnLocalBranchRemoved(Args.String); - repositoryManagerListener.DidNotReceive().OnRemoteBranchAdded(Args.String, Args.String); - repositoryManagerListener.DidNotReceive().OnRemoteBranchRemoved(Args.String, Args.String); - - Repository.Name.Should().Be("IOTestsRepo"); - Repository.CloneUrl.ToString().Should().Be("https://github.com/EvilStanleyGoldman/IOTestsRepo.git"); - Repository.Owner.Should().Be("EvilStanleyGoldman"); - Repository.LocalPath.Should().Be(TestRepoMasterTwoRemotes); - Repository.IsGitHub.Should().BeTrue(); - Repository.CurrentBranchName.Should().Be("master"); - Repository.CurrentBranch.HasValue.Should().BeTrue(); - Repository.CurrentBranch.Value.Name.Should().Be("master"); - Repository.CurrentRemote.HasValue.Should().BeTrue(); - Repository.CurrentRemote.Value.Name.Should().Be("origin"); - Repository.CurrentRemote.Value.Url.Should().Be("https://github.com/EvilStanleyGoldman/IOTestsRepo.git"); - Repository.LocalBranches.Should().BeEquivalentTo(new[] { - new GitBranch("master", "origin/master", true), - new GitBranch("branch2", "another/branch2", false), - new GitBranch("feature/document", "origin/feature/document", false), - new GitBranch("feature/other-feature", "origin/feature/other-feature", false), - }); - Repository.Remotes.Should().BeEquivalentTo( - new GitRemote("origin","https://github.com/EvilStanleyGoldman/IOTestsRepo.git"), - new GitRemote("another","https://another.remote/Owner/Url.git")); - Repository.RemoteBranches.Should().BeEquivalentTo(new[] { - new GitBranch("origin/master", "[None]", false), - new GitBranch("origin/feature/document-2", "[None]", false), - new GitBranch("origin/feature/other-feature", "[None]", false), - new GitBranch("another/master", "[None]", false), - new GitBranch("another/feature/document-2", "[None]", false), - new GitBranch("another/feature/other-feature", "[None]", false), - }); - - repositoryManagerListener.ClearReceivedCalls(); - repositoryManagerEvents.Reset(); - - await RepositoryManager.SwitchBranch("branch2") - .StartAsAsync(); - - await TaskManager.Wait(); - RepositoryManager.WaitForEvents(); - repositoryManagerEvents.WaitForNotBusy(); - repositoryManagerEvents.WaitForHeadUpdated(); - - repositoryManagerListener.Received().OnIsBusyChanged(Args.Bool); - repositoryManagerListener.Received().OnStatusUpdated(Args.GitStatus); - repositoryManagerListener.DidNotReceive().OnLocksUpdated(Args.EnumerableGitLock); - repositoryManagerListener.Received().OnCurrentBranchAndRemoteUpdated(Arg.Any(), Arg.Any()); - repositoryManagerListener.DidNotReceive().OnLocalBranchListUpdated(Arg.Any>()); - repositoryManagerListener.DidNotReceive().OnRemoteBranchListUpdated(Arg.Any>(), Arg.Any>>()); - repositoryManagerListener.DidNotReceive().OnLocalBranchUpdated(Args.String); - repositoryManagerListener.DidNotReceive().OnLocalBranchAdded(Args.String); - repositoryManagerListener.DidNotReceive().OnLocalBranchRemoved(Args.String); - repositoryManagerListener.DidNotReceive().OnRemoteBranchAdded(Args.String, Args.String); - repositoryManagerListener.DidNotReceive().OnRemoteBranchRemoved(Args.String, Args.String); - - Repository.Name.Should().Be("Url"); - Repository.CloneUrl.ToString().Should().Be("https://another.remote/Owner/Url.git"); - Repository.Owner.Should().Be("Owner"); - Repository.LocalPath.Should().Be(TestRepoMasterTwoRemotes); - Repository.IsGitHub.Should().BeFalse(); - Repository.CurrentBranchName.Should().Be("branch2"); - Repository.CurrentBranch.HasValue.Should().BeTrue(); - Repository.CurrentBranch.Value.Name.Should().Be("branch2"); - Repository.CurrentRemote.HasValue.Should().BeTrue(); - Repository.CurrentRemote.Value.Name.Should().Be("another"); - Repository.CurrentRemote.Value.Url.Should().Be("https://another.remote/Owner/Url.git"); - Repository.LocalBranches.Should().BeEquivalentTo(new[] { - new GitBranch("master", "origin/master", false), - new GitBranch("branch2", "another/branch2", true), - new GitBranch("feature/document", "origin/feature/document", false), - new GitBranch("feature/other-feature", "origin/feature/other-feature", false), - }); - Repository.Remotes.Should().BeEquivalentTo( - new GitRemote("origin","https://github.com/EvilStanleyGoldman/IOTestsRepo.git"), - new GitRemote("another","https://another.remote/Owner/Url.git")); - Repository.RemoteBranches.Should().BeEquivalentTo(new[] { - new GitBranch("origin/master", "[None]", false), - new GitBranch("origin/feature/document-2", "[None]", false), - new GitBranch("origin/feature/other-feature", "[None]", false), - new GitBranch("another/master", "[None]", false), - new GitBranch("another/feature/document-2", "[None]", false), - new GitBranch("another/feature/other-feature", "[None]", false), - }); + Logger.Trace("Starting ShouldDetectChangesToRemotesWhenSwitchingBranches"); + + try + { + var repositoryManagerListener = Substitute.For(); + + await Initialize(TestRepoMasterTwoRemotes, initializeRepository: false, + onRepositoryManagerCreated: manager => { + repositoryManagerListener.AttachListener(manager, repositoryManagerEvents); + }); + + repositoryManagerEvents.CurrentBranchUpdated.WaitOne(TimeSpan.FromSeconds(20)).Should().BeTrue(); + repositoryManagerEvents.LocalBranchesUpdated.WaitOne(TimeSpan.FromSeconds(20)).Should().BeTrue(); + repositoryManagerEvents.RemoteBranchesUpdated.WaitOne(TimeSpan.FromSeconds(20)).Should().BeTrue(); + + repositoryManagerListener.ClearReceivedCalls(); + + await RepositoryManager.CreateBranch("branch2", "another/master") + .StartAsAsync(); + await TaskManager.Wait(); + + RepositoryManager.WaitForEvents(); + repositoryManagerEvents.WaitForNotBusy(); + + repositoryManagerEvents.CurrentBranchUpdated.WaitOne(TimeSpan.FromSeconds(2)).Should().BeTrue(); + repositoryManagerEvents.LocalBranchesUpdated.WaitOne(TimeSpan.FromSeconds(2)).Should().BeTrue(); + repositoryManagerEvents.RemoteBranchesUpdated.WaitOne(TimeSpan.FromSeconds(2)).Should().BeTrue(); + + repositoryManagerListener.Received().OnIsBusyChanged(Args.Bool); + repositoryManagerListener.Received().CurrentBranchUpdated(Args.NullableConfigBranch, Args.NullableConfigRemote); + repositoryManagerListener.DidNotReceive().GitStatusUpdated(Args.GitStatus); + repositoryManagerListener.DidNotReceive().GitLocksUpdated(Args.GitLocks); + repositoryManagerListener.DidNotReceive().GitLogUpdated(Args.GitLogs); + repositoryManagerListener.Received().LocalBranchesUpdated(Args.LocalBranchDictionary); + repositoryManagerListener.Received().RemoteBranchesUpdated(Args.RemoteDictionary, Args.RemoteBranchDictionary); + + repositoryManagerListener.ClearReceivedCalls(); + repositoryManagerEvents.Reset(); + + await RepositoryManager.SwitchBranch("branch2") + .StartAsAsync(); + await TaskManager.Wait(); + + RepositoryManager.WaitForEvents(); + repositoryManagerEvents.WaitForNotBusy(); + + repositoryManagerEvents.CurrentBranchUpdated.WaitOne(TimeSpan.FromSeconds(2)).Should().BeTrue(); + + repositoryManagerListener.Received().OnIsBusyChanged(Args.Bool); + repositoryManagerListener.Received().CurrentBranchUpdated(Args.NullableConfigBranch, Args.NullableConfigRemote); + repositoryManagerListener.DidNotReceive().GitStatusUpdated(Args.GitStatus); + repositoryManagerListener.DidNotReceive().GitLocksUpdated(Args.GitLocks); + repositoryManagerListener.DidNotReceive().GitLogUpdated(Args.GitLogs); + repositoryManagerListener.DidNotReceive().LocalBranchesUpdated(Args.LocalBranchDictionary); + repositoryManagerListener.DidNotReceive().RemoteBranchesUpdated(Args.RemoteDictionary, Args.RemoteBranchDictionary); + } + finally + { + Logger.Trace("Ending ShouldDetectChangesToRemotesWhenSwitchingBranches"); + } } [Test] public async Task ShouldDetectGitPull() { - await Initialize(TestRepoMasterCleanSynchronized); - - var repositoryManagerListener = Substitute.For(); - repositoryManagerListener.AttachListener(RepositoryManager, repositoryManagerEvents); - - var expected = new GitStatus { - LocalBranch = "master", - RemoteBranch = "origin/master", - Entries = new List() - }; - - var result = new GitStatus(); - //TODO: Figure this out - //RepositoryManager.OnStatusUpdated += status => { result = status; }; - - await RepositoryManager.Pull("origin", "master").StartAsAsync(); - await TaskManager.Wait(); - RepositoryManager.WaitForEvents(); - repositoryManagerEvents.WaitForNotBusy(); - repositoryManagerEvents.WaitForStatusUpdated(); - - repositoryManagerListener.Received().OnIsBusyChanged(Args.Bool); - repositoryManagerListener.Received().OnStatusUpdated(Args.GitStatus); - repositoryManagerListener.DidNotReceive().OnLocksUpdated(Args.EnumerableGitLock); - repositoryManagerListener.DidNotReceive().OnCurrentBranchAndRemoteUpdated(Arg.Any(), Arg.Any()); - repositoryManagerListener.DidNotReceive().OnLocalBranchListUpdated(Arg.Any>()); - repositoryManagerListener.DidNotReceive().OnRemoteBranchListUpdated(Arg.Any>(), Arg.Any>>()); - repositoryManagerListener.Received().OnLocalBranchUpdated(Args.String); - repositoryManagerListener.DidNotReceive().OnLocalBranchAdded(Args.String); - repositoryManagerListener.DidNotReceive().OnLocalBranchRemoved(Args.String); - repositoryManagerListener.DidNotReceive().OnRemoteBranchAdded(Args.String, Args.String); - repositoryManagerListener.DidNotReceive().OnRemoteBranchRemoved(Args.String, Args.String); - - result.AssertEqual(expected); - - Repository.Name.Should().Be("IOTestsRepo"); - Repository.CloneUrl.ToString().Should().Be("https://github.com/EvilStanleyGoldman/IOTestsRepo.git"); - Repository.Owner.Should().Be("EvilStanleyGoldman"); - Repository.LocalPath.Should().Be(TestRepoMasterCleanSynchronized); - Repository.IsGitHub.Should().BeTrue(); - Repository.CurrentBranchName.Should().Be("master"); - Repository.CurrentBranch.HasValue.Should().BeTrue(); - Repository.CurrentBranch.Value.Name.Should().Be("master"); - Repository.CurrentRemote.HasValue.Should().BeTrue(); - Repository.CurrentRemote.Value.Name.Should().Be("origin"); - Repository.CurrentRemote.Value.Url.Should().Be("https://github.com/EvilStanleyGoldman/IOTestsRepo.git"); - Repository.LocalBranches.Should().BeEquivalentTo(new[] { - new GitBranch("master", "origin/master", true), - new GitBranch("feature/document", "origin/feature/document", false), - new GitBranch("feature/other-feature", "origin/feature/other-feature", false), - }); - Repository.Remotes.Should().BeEquivalentTo(new GitRemote("origin","https://github.com/EvilStanleyGoldman/IOTestsRepo.git")); - Repository.RemoteBranches.Should().BeEquivalentTo(new[] { - new GitBranch("origin/master", "[None]", false), - new GitBranch("origin/feature/document-2", "[None]", false), - new GitBranch("origin/feature/other-feature", "[None]", false), - }); - - repositoryManagerEvents.Reset(); - repositoryManagerEvents.WaitForNotBusy(); + Logger.Trace("Starting ShouldDetectGitPull"); + + try + { + var repositoryManagerListener = Substitute.For(); + + await Initialize(TestRepoMasterCleanSynchronized, initializeRepository: false, + onRepositoryManagerCreated: manager => { + repositoryManagerListener.AttachListener(manager, repositoryManagerEvents); + }); + + repositoryManagerEvents.CurrentBranchUpdated.WaitOne(TimeSpan.FromSeconds(20)).Should().BeTrue(); + repositoryManagerEvents.LocalBranchesUpdated.WaitOne(TimeSpan.FromSeconds(20)).Should().BeTrue(); + repositoryManagerEvents.RemoteBranchesUpdated.WaitOne(TimeSpan.FromSeconds(20)).Should().BeTrue(); + + repositoryManagerListener.ClearReceivedCalls(); + + await RepositoryManager.Pull("origin", "master").StartAsAsync(); + await TaskManager.Wait(); + + RepositoryManager.WaitForEvents(); + repositoryManagerEvents.WaitForNotBusy(); + + repositoryManagerEvents.LocalBranchesUpdated.WaitOne(TimeSpan.FromSeconds(2)).Should().BeTrue(); + + repositoryManagerListener.Received().OnIsBusyChanged(Args.Bool); + repositoryManagerListener.DidNotReceive().CurrentBranchUpdated(Args.NullableConfigBranch, Args.NullableConfigRemote); + repositoryManagerListener.DidNotReceive().GitStatusUpdated(Args.GitStatus); + repositoryManagerListener.DidNotReceive().GitLocksUpdated(Args.GitLocks); + repositoryManagerListener.DidNotReceive().GitLogUpdated(Args.GitLogs); + repositoryManagerListener.Received().LocalBranchesUpdated(Args.LocalBranchDictionary); + repositoryManagerListener.DidNotReceive().RemoteBranchesUpdated(Args.RemoteDictionary, Args.RemoteBranchDictionary); + } + finally + { + Logger.Trace("Ending ShouldDetectGitPull"); + } } [Test] public async Task ShouldDetectGitFetch() { - await Initialize(TestRepoMasterCleanUnsynchronized); - - var repositoryManagerListener = Substitute.For(); - repositoryManagerListener.AttachListener(RepositoryManager, repositoryManagerEvents); - - RepositoryManager.WaitForEvents(); - repositoryManagerEvents.WaitForNotBusy(2); - - repositoryManagerListener.AssertDidNotReceiveAnyCalls(); - - Repository.Name.Should().Be("IOTestsRepo"); - Repository.CloneUrl.ToString().Should().Be("https://github.com/EvilStanleyGoldman/IOTestsRepo.git"); - Repository.Owner.Should().Be("EvilStanleyGoldman"); - Repository.LocalPath.Should().Be(TestRepoMasterCleanUnsynchronized); - Repository.IsGitHub.Should().BeTrue(); - Repository.CurrentBranchName.Should().Be("master"); - Repository.CurrentBranch.HasValue.Should().BeTrue(); - Repository.CurrentBranch.Value.Name.Should().Be("master"); - Repository.CurrentRemote.HasValue.Should().BeTrue(); - Repository.CurrentRemote.Value.Name.Should().Be("origin"); - Repository.CurrentRemote.Value.Url.Should().Be("https://github.com/EvilStanleyGoldman/IOTestsRepo.git"); - Repository.LocalBranches.Should().BeEquivalentTo(new[] { - new GitBranch("feature/document", "origin/feature/document", false), - }); - Repository.Remotes.Should().BeEquivalentTo(new GitRemote("origin","https://github.com/EvilStanleyGoldman/IOTestsRepo.git")); - Repository.RemoteBranches.Should().BeEquivalentTo(new[] { - new GitBranch("origin/master", "[None]", false), - new GitBranch("origin/feature/document", "[None]", false), - new GitBranch("origin/feature/document-2", "[None]", false), - }); - - await RepositoryManager.Fetch("origin").StartAsAsync(); - await TaskManager.Wait(); - RepositoryManager.WaitForEvents(); - repositoryManagerEvents.WaitForNotBusy(); - - repositoryManagerListener.Received().OnIsBusyChanged(Args.Bool); - repositoryManagerListener.DidNotReceive().OnStatusUpdated(Args.GitStatus); - repositoryManagerListener.DidNotReceive().OnLocksUpdated(Args.EnumerableGitLock); - repositoryManagerListener.DidNotReceive().OnCurrentBranchAndRemoteUpdated(Arg.Any(), Arg.Any()); - repositoryManagerListener.DidNotReceive().OnLocalBranchListUpdated(Arg.Any>()); - repositoryManagerListener.DidNotReceive().OnRemoteBranchListUpdated(Arg.Any>(), Arg.Any>>()); - repositoryManagerListener.DidNotReceive().OnLocalBranchUpdated(Args.String); - repositoryManagerListener.DidNotReceive().OnLocalBranchAdded(Args.String); - repositoryManagerListener.DidNotReceive().OnLocalBranchRemoved(Args.String); - repositoryManagerListener.Received().OnRemoteBranchAdded(Args.String, Args.String); - repositoryManagerListener.DidNotReceive().OnRemoteBranchRemoved(Args.String, Args.String); - - Repository.Name.Should().Be("IOTestsRepo"); - Repository.CloneUrl.ToString().Should().Be("https://github.com/EvilStanleyGoldman/IOTestsRepo.git"); - Repository.Owner.Should().Be("EvilStanleyGoldman"); - Repository.LocalPath.Should().Be(TestRepoMasterCleanUnsynchronized); - Repository.IsGitHub.Should().BeTrue(); - Repository.CurrentBranchName.Should().Be("master"); - Repository.CurrentBranch.HasValue.Should().BeTrue(); - Repository.CurrentBranch.Value.Name.Should().Be("master"); - Repository.CurrentRemote.HasValue.Should().BeTrue(); - Repository.CurrentRemote.Value.Name.Should().Be("origin"); - Repository.CurrentRemote.Value.Url.Should().Be("https://github.com/EvilStanleyGoldman/IOTestsRepo.git"); - Repository.LocalBranches.Should().BeEquivalentTo(new[] { - new GitBranch("feature/document", "origin/feature/document", false), - }); - Repository.Remotes.Should().BeEquivalentTo(new GitRemote("origin","https://github.com/EvilStanleyGoldman/IOTestsRepo.git")); - Repository.RemoteBranches.Should().BeEquivalentTo(new[] { - new GitBranch("origin/master", "[None]", false), - new GitBranch("origin/feature/document", "[None]", false), - new GitBranch("origin/feature/document-2", "[None]", false), - new GitBranch("origin/feature/new-feature", "[None]", false), - new GitBranch("origin/feature/other-feature", "[None]", false), - }); + Logger.Trace("Starting ShouldDetectGitFetch"); + + try + { + var repositoryManagerListener = Substitute.For(); + + await Initialize(TestRepoMasterCleanUnsynchronized, initializeRepository: false, + onRepositoryManagerCreated: manager => { + repositoryManagerListener.AttachListener(manager, repositoryManagerEvents); + }); + + repositoryManagerEvents.CurrentBranchUpdated.WaitOne(TimeSpan.FromSeconds(20)).Should().BeTrue(); + repositoryManagerEvents.LocalBranchesUpdated.WaitOne(TimeSpan.FromSeconds(20)).Should().BeTrue(); + repositoryManagerEvents.RemoteBranchesUpdated.WaitOne(TimeSpan.FromSeconds(20)).Should().BeTrue(); + + repositoryManagerListener.ClearReceivedCalls(); + + await RepositoryManager.Fetch("origin").StartAsAsync(); + await TaskManager.Wait(); + + RepositoryManager.WaitForEvents(); + repositoryManagerEvents.WaitForNotBusy(); + + repositoryManagerEvents.LocalBranchesUpdated.WaitOne(TimeSpan.FromSeconds(2)).Should().BeTrue(); + repositoryManagerEvents.RemoteBranchesUpdated.WaitOne(TimeSpan.FromSeconds(2)).Should().BeTrue(); + + repositoryManagerListener.Received().OnIsBusyChanged(Args.Bool); + repositoryManagerListener.DidNotReceive().CurrentBranchUpdated(Args.NullableConfigBranch, Args.NullableConfigRemote); + repositoryManagerListener.DidNotReceive().GitStatusUpdated(Args.GitStatus); + repositoryManagerListener.DidNotReceive().GitLocksUpdated(Args.GitLocks); + repositoryManagerListener.DidNotReceive().GitLogUpdated(Args.GitLogs); + repositoryManagerListener.Received().LocalBranchesUpdated(Args.LocalBranchDictionary); + repositoryManagerListener.Received().RemoteBranchesUpdated(Args.RemoteDictionary, Args.RemoteBranchDictionary); + } + finally + { + Logger.Trace("Ending ShouldDetectGitFetch"); + } } } } diff --git a/src/tests/IntegrationTests/Events/RepositoryWatcherTests.cs b/src/tests/IntegrationTests/Events/RepositoryWatcherTests.cs index 6427fac6c..28a0e615b 100644 --- a/src/tests/IntegrationTests/Events/RepositoryWatcherTests.cs +++ b/src/tests/IntegrationTests/Events/RepositoryWatcherTests.cs @@ -9,379 +9,471 @@ namespace IntegrationTests { - [TestFixture, Category("TimeSensitive")] + [TestFixture, Category("DoNotRunOnAppVeyor")] class RepositoryWatcherTests : BaseGitEnvironmentTest { - private const int ThreadSleepTimeout = 2000; - - [Test, Category("TimeSensitive")] - public async Task ShouldDetectFileChanges() + [Test] + public async Task ShouldDetectFileChangesAndCommit() { - await Initialize(TestRepoMasterCleanSynchronized); + Logger.Trace("Starting ShouldDetectFileChangesAndCommit"); - using (var repositoryWatcher = CreateRepositoryWatcher(TestRepoMasterCleanSynchronized)) + try { - var watcherAutoResetEvent = new RepositoryWatcherAutoResetEvent(); + await Initialize(TestRepoMasterCleanSynchronized, initializeRepository: false); - var repositoryWatcherListener = Substitute.For(); - repositoryWatcherListener.AttachListener(repositoryWatcher, watcherAutoResetEvent); + using (var repositoryWatcher = CreateRepositoryWatcher(TestRepoMasterCleanSynchronized)) + { + var watcherAutoResetEvent = new RepositoryWatcherAutoResetEvent(); - repositoryWatcher.Initialize(); - repositoryWatcher.Start(); + var repositoryWatcherListener = Substitute.For(); + repositoryWatcherListener.AttachListener(repositoryWatcher, watcherAutoResetEvent); - try - { - var foobarTxt = TestRepoMasterCleanSynchronized.Combine("foobar.txt"); + repositoryWatcher.Initialize(); + repositoryWatcher.Start(); + repositoryWatcher.Stop(); - Logger.Trace("Issuing Changes"); + try + { + var foobarTxt = TestRepoMasterCleanSynchronized.Combine("foobar.txt"); - foobarTxt.WriteAllText("foobar"); - await TaskManager.Wait(); + Logger.Trace("Issuing Changes"); - watcherAutoResetEvent.IndexChanged.WaitOne(TimeSpan.FromSeconds(2)).Should().BeTrue(); - watcherAutoResetEvent.RepositoryChanged.WaitOne(TimeSpan.FromSeconds(2)).Should().BeTrue(); + foobarTxt.WriteAllText("foobar"); + await TaskManager.Wait(); - Logger.Trace("Continue test"); + Logger.Trace("Continue test"); - repositoryWatcherListener.DidNotReceive().ConfigChanged(); - repositoryWatcherListener.DidNotReceive().HeadChanged(); - repositoryWatcherListener.Received().IndexChanged(); - repositoryWatcherListener.DidNotReceive().LocalBranchCreated(Args.String); - repositoryWatcherListener.DidNotReceive().LocalBranchDeleted(Args.String); - repositoryWatcherListener.DidNotReceive().LocalBranchChanged(Args.String); - repositoryWatcherListener.DidNotReceive().RemoteBranchChanged(Args.String, Args.String); - repositoryWatcherListener.DidNotReceive().RemoteBranchCreated(Args.String, Args.String); - repositoryWatcherListener.DidNotReceive().RemoteBranchDeleted(Args.String, Args.String); - repositoryWatcherListener.Received().RepositoryChanged(); - } - finally - { - repositoryWatcher.Stop(); + repositoryWatcher.Start(); + + watcherAutoResetEvent.RepositoryChanged.WaitOne(TimeSpan.FromSeconds(2)).Should().BeTrue(); + watcherAutoResetEvent.Reset(); + + repositoryWatcherListener.DidNotReceive().HeadChanged(); + repositoryWatcherListener.DidNotReceive().ConfigChanged(); + repositoryWatcherListener.DidNotReceive().RepositoryCommitted(); + repositoryWatcherListener.DidNotReceive().IndexChanged(); + repositoryWatcherListener.Received().RepositoryChanged(); + repositoryWatcherListener.DidNotReceive().LocalBranchesChanged(); + repositoryWatcherListener.DidNotReceive().RemoteBranchesChanged(); + repositoryWatcherListener.ClearReceivedCalls(); + + repositoryWatcher.Stop(); + Logger.Trace("Issuing Command"); + + await GitClient.AddAll().StartAsAsync(); + + Logger.Trace("Completed Command"); + repositoryWatcher.Start(); + + watcherAutoResetEvent.IndexChanged.WaitOne(TimeSpan.FromSeconds(2)).Should().BeTrue(); + watcherAutoResetEvent.Reset(); + + repositoryWatcherListener.DidNotReceive().HeadChanged(); + repositoryWatcherListener.DidNotReceive().ConfigChanged(); + repositoryWatcherListener.DidNotReceive().RepositoryCommitted(); + repositoryWatcherListener.Received(1).IndexChanged(); + repositoryWatcherListener.DidNotReceive().RepositoryChanged(); + repositoryWatcherListener.DidNotReceive().LocalBranchesChanged(); + repositoryWatcherListener.DidNotReceive().RemoteBranchesChanged(); + repositoryWatcherListener.ClearReceivedCalls(); + + repositoryWatcher.Stop(); + Logger.Trace("Issuing Command"); + + await GitClient.Commit("Test Commit", string.Empty).StartAsAsync(); + + Logger.Trace("Completed Command"); + repositoryWatcher.Start(); + + watcherAutoResetEvent.RepositoryCommitted.WaitOne(TimeSpan.FromSeconds(2)).Should().BeTrue(); + watcherAutoResetEvent.IndexChanged.WaitOne(TimeSpan.FromSeconds(2)).Should().BeTrue(); + watcherAutoResetEvent.Reset(); + + repositoryWatcherListener.DidNotReceive().HeadChanged(); + repositoryWatcherListener.DidNotReceive().ConfigChanged(); + repositoryWatcherListener.Received(1).RepositoryCommitted(); + repositoryWatcherListener.Received(1).IndexChanged(); + repositoryWatcherListener.DidNotReceive().RepositoryChanged(); + repositoryWatcherListener.Received(1).LocalBranchesChanged(); + repositoryWatcherListener.DidNotReceive().RemoteBranchesChanged(); + repositoryWatcherListener.ClearReceivedCalls(); + } + finally + { + repositoryWatcher.Stop(); + } } } + finally + { + Logger.Trace("Ending ShouldDetectFileChangesAndCommit"); + } } [Test] public async Task ShouldDetectBranchChange() { - await Initialize(TestRepoMasterCleanSynchronized); + Logger.Trace("Starting ShouldDetectBranchChange"); - using (var repositoryWatcher = CreateRepositoryWatcher(TestRepoMasterCleanSynchronized)) + try { - var watcherAutoResetEvent = new RepositoryWatcherAutoResetEvent(); + await Initialize(TestRepoMasterCleanSynchronized, initializeRepository: false); - var repositoryWatcherListener = Substitute.For(); - repositoryWatcherListener.AttachListener(repositoryWatcher, watcherAutoResetEvent); + using (var repositoryWatcher = CreateRepositoryWatcher(TestRepoMasterCleanSynchronized)) + { + var watcherAutoResetEvent = new RepositoryWatcherAutoResetEvent(); - repositoryWatcher.Initialize(); - repositoryWatcher.Start(); + var repositoryWatcherListener = Substitute.For(); + repositoryWatcherListener.AttachListener(repositoryWatcher, watcherAutoResetEvent); - try - { - Logger.Trace("Issuing Command"); - - await GitClient.SwitchBranch("feature/document").StartAsAsync(); - await TaskManager.Wait(); - - watcherAutoResetEvent.HeadChanged.WaitOne(TimeSpan.FromSeconds(2)).Should().BeTrue(); - watcherAutoResetEvent.IndexChanged.WaitOne(TimeSpan.FromSeconds(2)).Should().BeTrue(); - watcherAutoResetEvent.RepositoryChanged.WaitOne(TimeSpan.FromSeconds(2)).Should().BeTrue(); - - Logger.Trace("Continue test"); - - repositoryWatcherListener.DidNotReceive().ConfigChanged(); - repositoryWatcherListener.Received().HeadChanged(); - repositoryWatcherListener.Received().IndexChanged(); - repositoryWatcherListener.DidNotReceive().LocalBranchCreated(Args.String); - repositoryWatcherListener.DidNotReceive().LocalBranchDeleted(Args.String); - repositoryWatcherListener.DidNotReceive().LocalBranchChanged(Args.String); - repositoryWatcherListener.DidNotReceive().RemoteBranchChanged(Args.String, Args.String); - repositoryWatcherListener.DidNotReceive().RemoteBranchCreated(Args.String, Args.String); - repositoryWatcherListener.DidNotReceive().RemoteBranchDeleted(Args.String, Args.String); - repositoryWatcherListener.Received().RepositoryChanged(); - } - finally - { + repositoryWatcher.Initialize(); + repositoryWatcher.Start(); repositoryWatcher.Stop(); + + try + { + Logger.Trace("Issuing Command"); + + await GitClient.SwitchBranch("feature/document").StartAsAsync(); + await TaskManager.Wait(); + + Logger.Trace("Completed Command"); + + repositoryWatcher.Start(); + + watcherAutoResetEvent.HeadChanged.WaitOne(TimeSpan.FromSeconds(2)).Should().BeTrue(); + watcherAutoResetEvent.IndexChanged.WaitOne(TimeSpan.FromSeconds(2)).Should().BeTrue(); + watcherAutoResetEvent.RepositoryChanged.WaitOne(TimeSpan.FromSeconds(2)).Should().BeTrue(); + + Logger.Trace("Continue test"); + + repositoryWatcherListener.Received(1).HeadChanged(); + repositoryWatcherListener.DidNotReceive().ConfigChanged(); + repositoryWatcherListener.DidNotReceive().RepositoryCommitted(); + repositoryWatcherListener.Received(1).IndexChanged(); + repositoryWatcherListener.Received(1).RepositoryChanged(); + repositoryWatcherListener.DidNotReceive().LocalBranchesChanged(); + repositoryWatcherListener.DidNotReceive().RemoteBranchesChanged(); + } + finally + { + repositoryWatcher.Stop(); + } } } + finally + { + Logger.Trace("Ending ShouldDetectBranchChange"); + } } [Test] public async Task ShouldDetectBranchDelete() { - await Initialize(TestRepoMasterCleanSynchronized); + Logger.Trace("Starting ShouldDetectBranchDelete"); - using (var repositoryWatcher = CreateRepositoryWatcher(TestRepoMasterCleanSynchronized)) + try { - var watcherAutoResetEvent = new RepositoryWatcherAutoResetEvent(); + await Initialize(TestRepoMasterCleanSynchronized, initializeRepository: false); - var repositoryWatcherListener = Substitute.For(); - repositoryWatcherListener.AttachListener(repositoryWatcher, watcherAutoResetEvent); + using (var repositoryWatcher = CreateRepositoryWatcher(TestRepoMasterCleanSynchronized)) + { + var watcherAutoResetEvent = new RepositoryWatcherAutoResetEvent(); - repositoryWatcher.Initialize(); - repositoryWatcher.Start(); + var repositoryWatcherListener = Substitute.For(); + repositoryWatcherListener.AttachListener(repositoryWatcher, watcherAutoResetEvent); - try - { - Logger.Trace("Issuing Command"); - - await GitClient.DeleteBranch("feature/document", true).StartAsAsync(); - await TaskManager.Wait(); - - watcherAutoResetEvent.ConfigChanged.WaitOne(TimeSpan.FromSeconds(2)).Should().BeTrue(); - watcherAutoResetEvent.LocalBranchDeleted.WaitOne(TimeSpan.FromSeconds(2)).Should().BeTrue(); - - Logger.Trace("Continue test"); - - repositoryWatcherListener.Received(1).ConfigChanged(); - repositoryWatcherListener.DidNotReceive().HeadChanged(); - repositoryWatcherListener.DidNotReceive().IndexChanged(); - repositoryWatcherListener.DidNotReceive().LocalBranchCreated(Args.String); - repositoryWatcherListener.Received(1).LocalBranchDeleted("feature/document"); - repositoryWatcherListener.DidNotReceive().LocalBranchChanged(Args.String); - repositoryWatcherListener.DidNotReceive().RemoteBranchChanged(Args.String, Args.String); - repositoryWatcherListener.DidNotReceive().RemoteBranchCreated(Args.String, Args.String); - repositoryWatcherListener.DidNotReceive().RemoteBranchDeleted(Args.String, Args.String); - repositoryWatcherListener.DidNotReceive().RepositoryChanged(); - } - finally - { + repositoryWatcher.Initialize(); + repositoryWatcher.Start(); repositoryWatcher.Stop(); + + try + { + Logger.Trace("Issuing Command"); + + await GitClient.DeleteBranch("feature/document", true).StartAsAsync(); + await TaskManager.Wait(); + + Logger.Trace("Completed Command"); + + repositoryWatcher.Start(); + + watcherAutoResetEvent.ConfigChanged.WaitOne(TimeSpan.FromSeconds(2)).Should().BeTrue(); + + Logger.Trace("Continue test"); + + repositoryWatcherListener.DidNotReceive().HeadChanged(); + repositoryWatcherListener.Received(1).ConfigChanged(); + repositoryWatcherListener.DidNotReceive().RepositoryCommitted(); + repositoryWatcherListener.DidNotReceive().IndexChanged(); + repositoryWatcherListener.DidNotReceive().RepositoryChanged(); + repositoryWatcherListener.Received(1).LocalBranchesChanged(); + repositoryWatcherListener.DidNotReceive().RemoteBranchesChanged(); + } + finally + { + repositoryWatcher.Stop(); + } } } + finally + { + Logger.Trace("Ending ShouldDetectBranchDelete"); + } } [Test] public async Task ShouldDetectBranchCreate() { - await Initialize(TestRepoMasterCleanSynchronized); + Logger.Trace("Starting ShouldDetectBranchCreate"); - using (var repositoryWatcher = CreateRepositoryWatcher(TestRepoMasterCleanSynchronized)) + try { - var watcherAutoResetEvent = new RepositoryWatcherAutoResetEvent(); + await Initialize(TestRepoMasterCleanSynchronized, initializeRepository: false); - var repositoryWatcherListener = Substitute.For(); - repositoryWatcherListener.AttachListener(repositoryWatcher, watcherAutoResetEvent); + using (var repositoryWatcher = CreateRepositoryWatcher(TestRepoMasterCleanSynchronized)) + { + var watcherAutoResetEvent = new RepositoryWatcherAutoResetEvent(); - repositoryWatcher.Initialize(); - repositoryWatcher.Start(); + var repositoryWatcherListener = Substitute.For(); + repositoryWatcherListener.AttachListener(repositoryWatcher, watcherAutoResetEvent); - try - { - Logger.Trace("Issuing Command"); + repositoryWatcher.Initialize(); + repositoryWatcher.Start(); + repositoryWatcher.Stop(); - await GitClient.CreateBranch("feature/document2", "feature/document").StartAsAsync(); - await TaskManager.Wait(); + try + { + Logger.Trace("Issuing Command"); - watcherAutoResetEvent.LocalBranchCreated.WaitOne(TimeSpan.FromSeconds(2)).Should().BeTrue(); + await GitClient.CreateBranch("feature/document2", "feature/document").StartAsAsync(); + await TaskManager.Wait(); - Logger.Trace("Continue test"); + Logger.Trace("Continue test"); - repositoryWatcherListener.DidNotReceive().ConfigChanged(); - repositoryWatcherListener.DidNotReceive().HeadChanged(); - repositoryWatcherListener.DidNotReceive().IndexChanged(); - repositoryWatcherListener.Received(1).LocalBranchCreated("feature/document2"); - repositoryWatcherListener.DidNotReceive().LocalBranchDeleted(Args.String); - repositoryWatcherListener.DidNotReceive().LocalBranchChanged("feature/document2"); - repositoryWatcherListener.DidNotReceive().RemoteBranchChanged(Args.String, Args.String); - repositoryWatcherListener.DidNotReceive().RemoteBranchCreated(Args.String, Args.String); - repositoryWatcherListener.DidNotReceive().RemoteBranchDeleted(Args.String, Args.String); - repositoryWatcherListener.DidNotReceive().RepositoryChanged(); + repositoryWatcher.Start(); - repositoryWatcherListener.ClearReceivedCalls(); + watcherAutoResetEvent.LocalBranchesChanged.WaitOne(TimeSpan.FromSeconds(2)).Should().BeTrue(); + watcherAutoResetEvent.Reset(); - Logger.Trace("Issuing Command"); + repositoryWatcherListener.DidNotReceive().HeadChanged(); + repositoryWatcherListener.DidNotReceive().ConfigChanged(); + repositoryWatcherListener.DidNotReceive().RepositoryCommitted(); + repositoryWatcherListener.DidNotReceive().IndexChanged(); + repositoryWatcherListener.DidNotReceive().RepositoryChanged(); + repositoryWatcherListener.Received(1).LocalBranchesChanged(); + repositoryWatcherListener.DidNotReceive().RemoteBranchesChanged(); + repositoryWatcherListener.ClearReceivedCalls(); - await GitClient.CreateBranch("feature2/document2", "feature/document").StartAsAsync(); - await TaskManager.Wait(); + repositoryWatcher.Stop(); - watcherAutoResetEvent.LocalBranchCreated.WaitOne(TimeSpan.FromSeconds(2)).Should().BeTrue(); + Logger.Trace("Issuing Command"); - Logger.Trace("Continue test"); + await GitClient.CreateBranch("feature2/document2", "feature/document").StartAsAsync(); + await TaskManager.Wait(); - repositoryWatcherListener.DidNotReceive().ConfigChanged(); - repositoryWatcherListener.DidNotReceive().HeadChanged(); - repositoryWatcherListener.DidNotReceive().IndexChanged(); - repositoryWatcherListener.Received(1).LocalBranchCreated("feature2/document2"); - repositoryWatcherListener.DidNotReceive().LocalBranchDeleted(Args.String); - repositoryWatcherListener.DidNotReceive().LocalBranchChanged(Args.String); - repositoryWatcherListener.DidNotReceive().RemoteBranchChanged(Args.String, Args.String); - repositoryWatcherListener.DidNotReceive().RemoteBranchCreated(Args.String, Args.String); - repositoryWatcherListener.DidNotReceive().RemoteBranchDeleted(Args.String, Args.String); - repositoryWatcherListener.DidNotReceive().RepositoryChanged(); + Logger.Trace("Continue test"); - repositoryWatcherListener.ClearReceivedCalls(); - } - finally - { - repositoryWatcher.Stop(); + repositoryWatcher.Start(); + + watcherAutoResetEvent.LocalBranchesChanged.WaitOne(TimeSpan.FromSeconds(2)).Should().BeTrue(); + + repositoryWatcherListener.DidNotReceive().HeadChanged(); + repositoryWatcherListener.DidNotReceive().ConfigChanged(); + repositoryWatcherListener.DidNotReceive().RepositoryCommitted(); + repositoryWatcherListener.DidNotReceive().IndexChanged(); + repositoryWatcherListener.DidNotReceive().RepositoryChanged(); + repositoryWatcherListener.Received(1).LocalBranchesChanged(); + repositoryWatcherListener.DidNotReceive().RemoteBranchesChanged(); + } + finally + { + repositoryWatcher.Stop(); + } } } + finally + { + Logger.Trace("Ending ShouldDetectBranchCreate"); + } } [Test] public async Task ShouldDetectChangesToRemotes() { - await Initialize(TestRepoMasterCleanSynchronized); + Logger.Trace("Starting ShouldDetectChangesToRemotes"); - using (var repositoryWatcher = CreateRepositoryWatcher(TestRepoMasterCleanSynchronized)) + try { - var watcherAutoResetEvent = new RepositoryWatcherAutoResetEvent(); + await Initialize(TestRepoMasterCleanSynchronized, initializeRepository: false); - var repositoryWatcherListener = Substitute.For(); - repositoryWatcherListener.AttachListener(repositoryWatcher, watcherAutoResetEvent); + using (var repositoryWatcher = CreateRepositoryWatcher(TestRepoMasterCleanSynchronized)) + { + var watcherAutoResetEvent = new RepositoryWatcherAutoResetEvent(); - repositoryWatcher.Initialize(); - repositoryWatcher.Start(); + var repositoryWatcherListener = Substitute.For(); + repositoryWatcherListener.AttachListener(repositoryWatcher, watcherAutoResetEvent); - try - { - Logger.Trace("Issuing Command"); - - await GitClient.RemoteRemove("origin").StartAsAsync(); - await TaskManager.Wait(); - - watcherAutoResetEvent.ConfigChanged.WaitOne(TimeSpan.FromSeconds(2)).Should().BeTrue(); - watcherAutoResetEvent.RemoteBranchDeleted.WaitOne(TimeSpan.FromSeconds(2)).Should().BeTrue(); - watcherAutoResetEvent.RemoteBranchDeleted.WaitOne(TimeSpan.FromSeconds(2)); - watcherAutoResetEvent.RemoteBranchDeleted.WaitOne(TimeSpan.FromSeconds(2)); - - Logger.Trace("Continue test"); - - repositoryWatcherListener.Received().ConfigChanged(); - repositoryWatcherListener.DidNotReceive().HeadChanged(); - repositoryWatcherListener.DidNotReceive().IndexChanged(); - repositoryWatcherListener.DidNotReceive().LocalBranchCreated(Args.String); - repositoryWatcherListener.DidNotReceive().LocalBranchDeleted(Args.String); - repositoryWatcherListener.DidNotReceive().LocalBranchChanged(Args.String); - repositoryWatcherListener.Received(1).RemoteBranchDeleted("origin", "feature/document-2"); - repositoryWatcherListener.Received(1).RemoteBranchDeleted("origin", "feature/other-feature"); - repositoryWatcherListener.Received(1).RemoteBranchDeleted("origin", "master"); - repositoryWatcherListener.DidNotReceive().RepositoryChanged(); - - repositoryWatcherListener.ClearReceivedCalls(); - watcherAutoResetEvent.ConfigChanged.Reset(); - - Logger.Trace("Issuing 2nd Command"); - - await GitClient.RemoteAdd("origin", "https://github.com/EvilStanleyGoldman/IOTestsRepo.git").StartAsAsync(); - // give the fs watcher a bit of time to catch up - await TaskEx.Delay(500); - await TaskManager.Wait(); - - watcherAutoResetEvent.ConfigChanged.WaitOne(TimeSpan.FromSeconds(2)).Should().BeTrue(); - - Logger.Trace("Continue 2nd test"); - - repositoryWatcherListener.Received().ConfigChanged(); - repositoryWatcherListener.DidNotReceive().HeadChanged(); - repositoryWatcherListener.DidNotReceive().IndexChanged(); - repositoryWatcherListener.DidNotReceive().LocalBranchCreated(Args.String); - repositoryWatcherListener.DidNotReceive().LocalBranchDeleted(Args.String); - repositoryWatcherListener.DidNotReceive().LocalBranchChanged(Args.String); - repositoryWatcherListener.DidNotReceive().RemoteBranchChanged(Args.String, Args.String); - repositoryWatcherListener.DidNotReceive().RemoteBranchCreated(Args.String, Args.String); - repositoryWatcherListener.DidNotReceive().RemoteBranchDeleted(Args.String, Args.String); - repositoryWatcherListener.DidNotReceive().RepositoryChanged(); - } - finally - { + repositoryWatcher.Initialize(); + repositoryWatcher.Start(); repositoryWatcher.Stop(); + + try + { + Logger.Trace("Issuing Command"); + + await GitClient.RemoteRemove("origin").StartAsAsync(); + await TaskManager.Wait(); + + Logger.Trace("Continue test"); + + repositoryWatcher.Start(); + watcherAutoResetEvent.ConfigChanged.WaitOne(TimeSpan.FromSeconds(2)).Should().BeTrue(); + watcherAutoResetEvent.RemoteBranchesChanged.WaitOne(TimeSpan.FromSeconds(2)).Should().BeTrue(); + watcherAutoResetEvent.Reset(); + + repositoryWatcherListener.DidNotReceive().HeadChanged(); + repositoryWatcherListener.Received(1).ConfigChanged(); + repositoryWatcherListener.DidNotReceive().RepositoryCommitted(); + repositoryWatcherListener.DidNotReceive().IndexChanged(); + repositoryWatcherListener.DidNotReceive().RepositoryChanged(); + repositoryWatcherListener.DidNotReceive().LocalBranchesChanged(); + repositoryWatcherListener.Received(1).RemoteBranchesChanged(); + repositoryWatcherListener.ClearReceivedCalls(); + + repositoryWatcher.Stop(); + + Logger.Trace("Issuing 2nd Command"); + + await GitClient.RemoteAdd("origin", "https://github.com/EvilStanleyGoldman/IOTestsRepo.git").StartAsAsync(); + await TaskManager.Wait(); + + Logger.Trace("Continue 2nd test"); + + repositoryWatcher.Start(); + watcherAutoResetEvent.ConfigChanged.WaitOne(TimeSpan.FromSeconds(2)).Should().BeTrue(); + watcherAutoResetEvent.RemoteBranchesChanged.WaitOne(TimeSpan.FromSeconds(2)).Should().BeTrue(); + + repositoryWatcherListener.DidNotReceive().HeadChanged(); + repositoryWatcherListener.Received(1).ConfigChanged(); + repositoryWatcherListener.DidNotReceive().RepositoryCommitted(); + repositoryWatcherListener.DidNotReceive().IndexChanged(); + repositoryWatcherListener.DidNotReceive().RepositoryChanged(); + repositoryWatcherListener.DidNotReceive().LocalBranchesChanged(); + repositoryWatcherListener.Received(1).RemoteBranchesChanged(); + } + finally + { + repositoryWatcher.Stop(); + } } } + finally + { + Logger.Trace("Ending ShouldDetectChangesToRemotes"); + } } [Test] public async Task ShouldDetectGitPull() { - await Initialize(TestRepoMasterCleanSynchronized); + Logger.Trace("Starting ShouldDetectGitPull"); - using (var repositoryWatcher = CreateRepositoryWatcher(TestRepoMasterCleanSynchronized)) + try { - var watcherAutoResetEvent = new RepositoryWatcherAutoResetEvent(); + await Initialize(TestRepoMasterCleanSynchronized, initializeRepository: false); - var repositoryWatcherListener = Substitute.For(); - repositoryWatcherListener.AttachListener(repositoryWatcher, watcherAutoResetEvent); + using (var repositoryWatcher = CreateRepositoryWatcher(TestRepoMasterCleanSynchronized)) + { + var watcherAutoResetEvent = new RepositoryWatcherAutoResetEvent(); - repositoryWatcher.Initialize(); - repositoryWatcher.Start(); + var repositoryWatcherListener = Substitute.For(); + repositoryWatcherListener.AttachListener(repositoryWatcher, watcherAutoResetEvent); - try - { - Logger.Trace("Issuing Command"); - - await GitClient.Pull("origin", "master").StartAsAsync(); - await TaskManager.Wait(); - - watcherAutoResetEvent.IndexChanged.WaitOne(TimeSpan.FromSeconds(2)).Should().BeTrue(); - watcherAutoResetEvent.LocalBranchChanged.WaitOne(TimeSpan.FromSeconds(2)).Should().BeTrue(); - watcherAutoResetEvent.RepositoryChanged.WaitOne(TimeSpan.FromSeconds(2)).Should().BeTrue(); - - Logger.Trace("Continue test"); - - repositoryWatcherListener.DidNotReceive().ConfigChanged(); - repositoryWatcherListener.DidNotReceive().HeadChanged(); - repositoryWatcherListener.Received().IndexChanged(); - repositoryWatcherListener.DidNotReceive().LocalBranchCreated(Args.String); - repositoryWatcherListener.DidNotReceive().LocalBranchDeleted(Args.String); - repositoryWatcherListener.Received().LocalBranchChanged("master"); - repositoryWatcherListener.DidNotReceive().RemoteBranchChanged(Args.String, Args.String); - repositoryWatcherListener.DidNotReceive().RemoteBranchCreated(Args.String, Args.String); - repositoryWatcherListener.DidNotReceive().RemoteBranchDeleted(Args.String, Args.String); - repositoryWatcherListener.Received().RepositoryChanged(); - } - finally - { + repositoryWatcher.Initialize(); + repositoryWatcher.Start(); repositoryWatcher.Stop(); + + try + { + Logger.Trace("Issuing Command"); + + await GitClient.Pull("origin", "master").StartAsAsync(); + await TaskManager.Wait(); + + Logger.Trace("Continue test"); + + repositoryWatcher.Start(); + + watcherAutoResetEvent.IndexChanged.WaitOne(TimeSpan.FromSeconds(2)).Should().BeTrue(); + watcherAutoResetEvent.RepositoryChanged.WaitOne(TimeSpan.FromSeconds(2)).Should().BeTrue(); + + repositoryWatcherListener.DidNotReceive().HeadChanged(); + repositoryWatcherListener.DidNotReceive().ConfigChanged(); + repositoryWatcherListener.DidNotReceive().RepositoryCommitted(); + repositoryWatcherListener.Received(1).IndexChanged(); + repositoryWatcherListener.Received(1).RepositoryChanged(); + repositoryWatcherListener.Received(1).LocalBranchesChanged(); + repositoryWatcherListener.DidNotReceive().RemoteBranchesChanged(); + } + finally + { + repositoryWatcher.Stop(); + } } } + finally + { + Logger.Trace("Ending ShouldDetectGitPull"); + } } [Test] public async Task ShouldDetectGitFetch() { - await Initialize(TestRepoMasterCleanUnsynchronized); + Logger.Trace("Starting ShouldDetectGitFetch"); - using (var repositoryWatcher = CreateRepositoryWatcher(TestRepoMasterCleanUnsynchronized)) + try { - var watcherAutoResetEvent = new RepositoryWatcherAutoResetEvent(); - - var repositoryWatcherListener = Substitute.For(); - repositoryWatcherListener.AttachListener(repositoryWatcher, watcherAutoResetEvent, true); - - repositoryWatcher.Initialize(); - repositoryWatcher.Start(); + await Initialize(TestRepoMasterCleanUnsynchronized, initializeRepository: false); - try + using (var repositoryWatcher = CreateRepositoryWatcher(TestRepoMasterCleanUnsynchronized)) { - Logger.Trace("Issuing Command"); - - await GitClient.Fetch("origin").StartAsAsync(); - await TaskManager.Wait(); - - watcherAutoResetEvent.RemoteBranchCreated.WaitOne(TimeSpan.FromSeconds(2)).Should().BeTrue(); - watcherAutoResetEvent.RemoteBranchCreated.WaitOne(TimeSpan.FromSeconds(2)); - - Logger.Trace("Continue test"); - - repositoryWatcherListener.DidNotReceive().ConfigChanged(); - repositoryWatcherListener.DidNotReceive().HeadChanged(); - repositoryWatcherListener.DidNotReceive().IndexChanged(); - repositoryWatcherListener.DidNotReceive().LocalBranchCreated(Args.String); - repositoryWatcherListener.DidNotReceive().LocalBranchDeleted(Args.String); - repositoryWatcherListener.DidNotReceive().LocalBranchChanged(Args.String); - repositoryWatcherListener.DidNotReceive().RemoteBranchChanged(Args.String, Args.String); - repositoryWatcherListener.Received(1).RemoteBranchCreated("origin", "feature/new-feature"); - repositoryWatcherListener.Received(1).RemoteBranchCreated("origin", "feature/other-feature"); - repositoryWatcherListener.DidNotReceive().RemoteBranchDeleted(Args.String, Args.String); - repositoryWatcherListener.DidNotReceive().RepositoryChanged(); - } - finally - { - repositoryWatcher.Stop(); + var watcherAutoResetEvent = new RepositoryWatcherAutoResetEvent(); + + var repositoryWatcherListener = Substitute.For(); + repositoryWatcherListener.AttachListener(repositoryWatcher, watcherAutoResetEvent, true); + + repositoryWatcher.Initialize(); + repositoryWatcher.Start(); + + try + { + Logger.Trace("Issuing Command"); + + await GitClient.Fetch("origin").StartAsAsync(); + await TaskManager.Wait(); + + Logger.Trace("Continue test"); + + repositoryWatcherListener.DidNotReceive().HeadChanged(); + repositoryWatcherListener.DidNotReceive().ConfigChanged(); + repositoryWatcherListener.DidNotReceive().RepositoryCommitted(); + repositoryWatcherListener.DidNotReceive().IndexChanged(); + repositoryWatcherListener.DidNotReceive().RepositoryChanged(); + repositoryWatcherListener.DidNotReceive().LocalBranchesChanged(); + repositoryWatcherListener.DidNotReceive().RemoteBranchesChanged(); + } + finally + { + repositoryWatcher.Stop(); + } } } + finally + { + Logger.Trace("Ending ShouldDetectGitFetch"); + } } private RepositoryWatcher CreateRepositoryWatcher(NPath path) @@ -393,16 +485,13 @@ private RepositoryWatcher CreateRepositoryWatcher(NPath path) public interface IRepositoryWatcherListener { - void ConfigChanged(); void HeadChanged(); void IndexChanged(); - void LocalBranchCreated(string branch); - void LocalBranchDeleted(string branch); - void LocalBranchChanged(string branch); - void RemoteBranchChanged(string remote, string branch); - void RemoteBranchCreated(string remote, string branch); - void RemoteBranchDeleted(string remote, string branch); + void ConfigChanged(); + void RepositoryCommitted(); void RepositoryChanged(); + void LocalBranchesChanged(); + void RemoteBranchesChanged(); } static class RepositoryWatcherListenerExtensions @@ -418,13 +507,6 @@ public static void AttachListener(this IRepositoryWatcherListener listener, IRep autoResetEvent?.HeadChanged.Set(); }; - repositoryWatcher.ConfigChanged += () => - { - logger?.Trace("ConfigChanged"); - listener.ConfigChanged(); - autoResetEvent?.ConfigChanged.Set(); - }; - repositoryWatcher.IndexChanged += () => { logger?.Trace("IndexChanged"); @@ -432,61 +514,51 @@ public static void AttachListener(this IRepositoryWatcherListener listener, IRep autoResetEvent?.IndexChanged.Set(); }; - repositoryWatcher.LocalBranchChanged += s => - { - logger?.Trace("LocalBranchChanged: {0}", s); - listener.LocalBranchChanged(s); - autoResetEvent?.LocalBranchChanged.Set(); - }; - - repositoryWatcher.LocalBranchCreated += s => + repositoryWatcher.ConfigChanged += () => { - logger?.Trace("LocalBranchCreated: {0}", s); - listener.LocalBranchCreated(s); - autoResetEvent?.LocalBranchCreated.Set(); + logger?.Trace("ConfigChanged"); + listener.ConfigChanged(); + autoResetEvent?.ConfigChanged.Set(); }; - repositoryWatcher.LocalBranchDeleted += s => + repositoryWatcher.RepositoryCommitted += () => { - logger?.Trace("LocalBranchDeleted: {0}", s); - listener.LocalBranchDeleted(s); - autoResetEvent?.LocalBranchDeleted.Set(); + logger?.Trace("ConfigChanged"); + listener.RepositoryCommitted(); + autoResetEvent?.RepositoryCommitted.Set(); }; - repositoryWatcher.RemoteBranchCreated += (s, s1) => + repositoryWatcher.RepositoryChanged += () => { - logger?.Trace("RemoteBranchCreated: {0} {1}", s, s1); - listener.RemoteBranchCreated(s, s1); - autoResetEvent?.RemoteBranchCreated.Set(); + logger?.Trace("RepositoryChanged"); + listener.RepositoryChanged(); + autoResetEvent?.RepositoryChanged.Set(); }; - repositoryWatcher.RemoteBranchDeleted += (s, s1) => + repositoryWatcher.LocalBranchesChanged += () => { - logger?.Trace("RemoteBranchDeleted: {0} {1}", s, s1); - listener.RemoteBranchDeleted(s, s1); - autoResetEvent?.RemoteBranchDeleted.Set(); + logger?.Trace("LocalBranchesChanged"); + listener.LocalBranchesChanged(); + autoResetEvent?.LocalBranchesChanged.Set(); }; - repositoryWatcher.RepositoryChanged += () => + repositoryWatcher.RemoteBranchesChanged += () => { - logger?.Trace("RepositoryChanged"); - listener.RepositoryChanged(); - autoResetEvent?.RepositoryChanged.Set(); + logger?.Trace("RemoteBranchesChanged"); + listener.RemoteBranchesChanged(); + autoResetEvent?.RemoteBranchesChanged.Set(); }; } public static void AssertDidNotReceiveAnyCalls(this IRepositoryWatcherListener repositoryWatcherListener) { - repositoryWatcherListener.DidNotReceive().ConfigChanged(); repositoryWatcherListener.DidNotReceive().HeadChanged(); + repositoryWatcherListener.DidNotReceive().ConfigChanged(); + repositoryWatcherListener.DidNotReceive().RepositoryCommitted(); repositoryWatcherListener.DidNotReceive().IndexChanged(); - repositoryWatcherListener.DidNotReceive().LocalBranchCreated(Args.String); - repositoryWatcherListener.DidNotReceive().LocalBranchDeleted(Args.String); - repositoryWatcherListener.DidNotReceive().LocalBranchChanged(Args.String); - repositoryWatcherListener.DidNotReceive().RemoteBranchChanged(Args.String, Args.String); - repositoryWatcherListener.DidNotReceive().RemoteBranchCreated(Args.String, Args.String); - repositoryWatcherListener.DidNotReceive().RemoteBranchDeleted(Args.String, Args.String); repositoryWatcherListener.DidNotReceive().RepositoryChanged(); + repositoryWatcherListener.DidNotReceive().LocalBranchesChanged(); + repositoryWatcherListener.DidNotReceive().RemoteBranchesChanged(); } } @@ -494,13 +566,21 @@ class RepositoryWatcherAutoResetEvent { public AutoResetEvent HeadChanged { get; } = new AutoResetEvent(false); public AutoResetEvent ConfigChanged { get; } = new AutoResetEvent(false); + public AutoResetEvent RepositoryCommitted { get; } = new AutoResetEvent(false); public AutoResetEvent IndexChanged { get; } = new AutoResetEvent(false); - public AutoResetEvent LocalBranchChanged { get; } = new AutoResetEvent(false); - public AutoResetEvent LocalBranchCreated { get; } = new AutoResetEvent(false); - public AutoResetEvent LocalBranchDeleted { get; } = new AutoResetEvent(false); - public AutoResetEvent RemoteBranchChanged { get; } = new AutoResetEvent(false); - public AutoResetEvent RemoteBranchCreated { get; } = new AutoResetEvent(false); - public AutoResetEvent RemoteBranchDeleted { get; } = new AutoResetEvent(false); public AutoResetEvent RepositoryChanged { get; } = new AutoResetEvent(false); + public AutoResetEvent LocalBranchesChanged { get; } = new AutoResetEvent(false); + public AutoResetEvent RemoteBranchesChanged { get; } = new AutoResetEvent(false); + + public void Reset() + { + HeadChanged.Reset(); + ConfigChanged.Reset(); + RepositoryCommitted.Reset(); + IndexChanged.Reset(); + RepositoryChanged.Reset(); + LocalBranchesChanged.Reset(); + RemoteBranchesChanged.Reset(); + } } } diff --git a/src/tests/IntegrationTests/GitClientTests.cs b/src/tests/IntegrationTests/GitClientTests.cs index 8acc3e70a..7acb2250d 100644 --- a/src/tests/IntegrationTests/GitClientTests.cs +++ b/src/tests/IntegrationTests/GitClientTests.cs @@ -6,7 +6,7 @@ namespace IntegrationTests { - [TestFixture/*, Category("TimeSensitive")*/] + [TestFixture] class GitClientTests : BaseGitEnvironmentTest { [Test] diff --git a/src/tests/TestUtils/Events/IRepositoryManagerListener.cs b/src/tests/TestUtils/Events/IRepositoryManagerListener.cs index ec7a10537..d0def0f87 100644 --- a/src/tests/TestUtils/Events/IRepositoryManagerListener.cs +++ b/src/tests/TestUtils/Events/IRepositoryManagerListener.cs @@ -10,65 +10,41 @@ namespace TestUtils.Events interface IRepositoryManagerListener { void OnIsBusyChanged(bool busy); - void OnStatusUpdated(GitStatus status); - void OnLocksUpdated(IEnumerable locks); - void OnLocalBranchListUpdated(Dictionary branchList); - void OnRemoteBranchListUpdated(Dictionary remotesList, Dictionary> remoteBranchList); - void OnLocalBranchUpdated(string name); - void OnLocalBranchAdded(string name); - void OnLocalBranchRemoved(string name); - void OnRemoteBranchAdded(string origin, string name); - void OnRemoteBranchRemoved(string origin, string name); - void OnCurrentBranchAndRemoteUpdated(ConfigBranch? configBranch, ConfigRemote? configRemote); + void LocalBranchesUpdated(Dictionary branchList); + void RemoteBranchesUpdated(Dictionary remotesList, Dictionary> remoteBranchList); + void CurrentBranchUpdated(ConfigBranch? configBranch, ConfigRemote? configRemote); + void GitLocksUpdated(List gitLocks); + void GitStatusUpdated(GitStatus gitStatus); + void GitLogUpdated(List gitLogEntries); } class RepositoryManagerEvents { - public EventWaitHandle OnIsBusy { get; } = new AutoResetEvent(false); - public EventWaitHandle OnIsNotBusy { get; } = new AutoResetEvent(false); - public EventWaitHandle OnStatusUpdated { get; } = new AutoResetEvent(false); - public EventWaitHandle OnLocksUpdated { get; } = new AutoResetEvent(false); - public EventWaitHandle OnCurrentBranchAndRemoteUpdated { get; } = new AutoResetEvent(false); - public EventWaitHandle OnHeadUpdated { get; } = new AutoResetEvent(false); - public EventWaitHandle OnLocalBranchListUpdated { get; } = new AutoResetEvent(false); - public EventWaitHandle OnRemoteBranchListUpdated { get; } = new AutoResetEvent(false); - public EventWaitHandle OnLocalBranchUpdated { get; } = new AutoResetEvent(false); - public EventWaitHandle OnLocalBranchAdded { get; } = new AutoResetEvent(false); - public EventWaitHandle OnLocalBranchRemoved { get; } = new AutoResetEvent(false); - public EventWaitHandle OnRemoteBranchAdded { get; } = new AutoResetEvent(false); - public EventWaitHandle OnRemoteBranchRemoved { get; } = new AutoResetEvent(false); + public EventWaitHandle IsBusy { get; } = new AutoResetEvent(false); + public EventWaitHandle IsNotBusy { get; } = new AutoResetEvent(false); + public EventWaitHandle CurrentBranchUpdated { get; } = new AutoResetEvent(false); + public EventWaitHandle GitStatusUpdated { get; } = new AutoResetEvent(false); + public EventWaitHandle GitLocksUpdated { get; } = new AutoResetEvent(false); + public EventWaitHandle GitLogUpdated { get; } = new AutoResetEvent(false); + public EventWaitHandle LocalBranchesUpdated { get; } = new AutoResetEvent(false); + public EventWaitHandle RemoteBranchesUpdated { get; } = new AutoResetEvent(false); public void Reset() { - OnIsBusy.Reset(); - OnIsNotBusy.Reset(); - OnStatusUpdated.Reset(); - OnLocksUpdated.Reset(); - OnCurrentBranchAndRemoteUpdated.Reset(); - OnHeadUpdated.Reset(); - OnLocalBranchListUpdated.Reset(); - OnRemoteBranchListUpdated.Reset(); - OnLocalBranchUpdated.Reset(); - OnLocalBranchAdded.Reset(); - OnLocalBranchRemoved.Reset(); - OnRemoteBranchAdded.Reset(); - OnRemoteBranchRemoved.Reset(); + IsBusy.Reset(); + IsNotBusy.Reset(); + CurrentBranchUpdated.Reset(); + GitStatusUpdated.Reset(); + GitLocksUpdated.Reset(); + GitLogUpdated.Reset(); + LocalBranchesUpdated.Reset(); + RemoteBranchesUpdated.Reset(); } public void WaitForNotBusy(int seconds = 1) { - OnIsBusy.WaitOne(TimeSpan.FromSeconds(seconds)); - OnIsNotBusy.WaitOne(TimeSpan.FromSeconds(seconds)); - } - - public void WaitForStatusUpdated(int seconds = 1) - { - OnStatusUpdated.WaitOne(TimeSpan.FromSeconds(seconds)); - } - - public void WaitForHeadUpdated(int seconds = 1) - { - OnHeadUpdated.WaitOne(TimeSpan.FromSeconds(seconds)); + IsBusy.WaitOne(TimeSpan.FromSeconds(seconds)); + IsNotBusy.WaitOne(TimeSpan.FromSeconds(seconds)); } } @@ -79,77 +55,61 @@ public static void AttachListener(this IRepositoryManagerListener listener, { var logger = trace ? Logging.GetLogger() : null; - repositoryManager.OnIsBusyChanged += isBusy => { + repositoryManager.IsBusyChanged += isBusy => { logger?.Trace("OnIsBusyChanged: {0}", isBusy); listener.OnIsBusyChanged(isBusy); if (isBusy) - managerEvents?.OnIsBusy.Set(); + managerEvents?.IsBusy.Set(); else - managerEvents?.OnIsNotBusy.Set(); - }; - - repositoryManager.OnCurrentBranchAndRemoteUpdated += (configBranch, configRemote) => { - logger?.Trace("OnCurrentBranchAndRemoteUpdated"); - listener.OnCurrentBranchAndRemoteUpdated(configBranch, configRemote); - managerEvents?.OnCurrentBranchAndRemoteUpdated.Set(); - }; - - repositoryManager.OnLocalBranchListUpdated += branchList => { - logger?.Trace("OnLocalBranchListUpdated"); - listener.OnLocalBranchListUpdated(branchList); - managerEvents?.OnLocalBranchListUpdated.Set(); + managerEvents?.IsNotBusy.Set(); }; - repositoryManager.OnRemoteBranchListUpdated += (remotesList, branchList) => { - logger?.Trace("OnRemoteBranchListUpdated"); - listener.OnRemoteBranchListUpdated(remotesList, branchList); - managerEvents?.OnRemoteBranchListUpdated.Set(); + repositoryManager.CurrentBranchUpdated += (configBranch, configRemote) => { + logger?.Trace("CurrentBranchUpdated"); + listener.CurrentBranchUpdated(configBranch, configRemote); + managerEvents?.CurrentBranchUpdated.Set(); }; - repositoryManager.OnLocalBranchUpdated += name => { - logger?.Trace("OnLocalBranchUpdated Name:{0}", name); - listener.OnLocalBranchUpdated(name); - managerEvents?.OnLocalBranchUpdated.Set(); + repositoryManager.GitLocksUpdated += gitLocks => { + logger?.Trace("GitLocksUpdated"); + listener.GitLocksUpdated(gitLocks); + managerEvents?.GitLocksUpdated.Set(); }; - repositoryManager.OnLocalBranchAdded += name => { - logger?.Trace("OnLocalBranchAdded Name:{0}", name); - listener.OnLocalBranchAdded(name); - managerEvents?.OnLocalBranchAdded.Set(); + repositoryManager.GitStatusUpdated += gitStatus => { + logger?.Trace("GitStatusUpdated"); + listener.GitStatusUpdated(gitStatus); + managerEvents?.GitStatusUpdated.Set(); }; - repositoryManager.OnLocalBranchRemoved += name => { - logger?.Trace("OnLocalBranchRemoved Name:{0}", name); - listener.OnLocalBranchRemoved(name); - managerEvents?.OnLocalBranchRemoved.Set(); + repositoryManager.GitLogUpdated += gitLogEntries => { + logger?.Trace("GitLogUpdated"); + listener.GitLogUpdated(gitLogEntries); + managerEvents?.GitLogUpdated.Set(); }; - repositoryManager.OnRemoteBranchAdded += (origin, name) => { - logger?.Trace("OnRemoteBranchAdded Origin:{0} Name:{1}", origin, name); - listener.OnRemoteBranchAdded(origin, name); - managerEvents?.OnRemoteBranchAdded.Set(); + repositoryManager.LocalBranchesUpdated += branchList => { + logger?.Trace("LocalBranchesUpdated"); + listener.LocalBranchesUpdated(branchList); + managerEvents?.LocalBranchesUpdated.Set(); }; - repositoryManager.OnRemoteBranchRemoved += (origin, name) => { - logger?.Trace("OnRemoteBranchRemoved Origin:{0} Name:{1}", origin, name); - listener.OnRemoteBranchRemoved(origin, name); - managerEvents?.OnRemoteBranchRemoved.Set(); + repositoryManager.RemoteBranchesUpdated += (remotesList, branchList) => { + logger?.Trace("RemoteBranchesUpdated"); + listener.RemoteBranchesUpdated(remotesList, branchList); + managerEvents?.RemoteBranchesUpdated.Set(); }; } public static void AssertDidNotReceiveAnyCalls(this IRepositoryManagerListener repositoryManagerListener) { repositoryManagerListener.DidNotReceive().OnIsBusyChanged(Args.Bool); - repositoryManagerListener.DidNotReceive().OnStatusUpdated(Args.GitStatus); - repositoryManagerListener.DidNotReceive().OnLocksUpdated(Args.EnumerableGitLock); - repositoryManagerListener.DidNotReceive().OnCurrentBranchAndRemoteUpdated(Arg.Any(), Arg.Any()); - repositoryManagerListener.DidNotReceive().OnLocalBranchListUpdated(Arg.Any>()); - repositoryManagerListener.DidNotReceive().OnRemoteBranchListUpdated(Arg.Any>(), Arg.Any>>()); - repositoryManagerListener.DidNotReceive().OnLocalBranchUpdated(Args.String); - repositoryManagerListener.DidNotReceive().OnLocalBranchAdded(Args.String); - repositoryManagerListener.DidNotReceive().OnLocalBranchRemoved(Args.String); - repositoryManagerListener.DidNotReceive().OnRemoteBranchAdded(Args.String, Args.String); - repositoryManagerListener.DidNotReceive().OnRemoteBranchRemoved(Args.String, Args.String); + repositoryManagerListener.DidNotReceive().CurrentBranchUpdated(Args.NullableConfigBranch, Args.NullableConfigRemote); + repositoryManagerListener.DidNotReceive().GitStatusUpdated(Args.GitStatus); + repositoryManagerListener.DidNotReceive().GitLocksUpdated(Args.GitLocks); + repositoryManagerListener.DidNotReceive().GitLogUpdated(Args.GitLogs); + repositoryManagerListener.DidNotReceive().LocalBranchesUpdated(Args.LocalBranchDictionary); + repositoryManagerListener.DidNotReceive().RemoteBranchesUpdated(Args.RemoteDictionary, Args.RemoteBranchDictionary); } } }; \ No newline at end of file diff --git a/src/tests/TestUtils/Helpers/Args.cs b/src/tests/TestUtils/Helpers/Args.cs index 650d65e73..e8bd7d980 100644 --- a/src/tests/TestUtils/Helpers/Args.cs +++ b/src/tests/TestUtils/Helpers/Args.cs @@ -15,9 +15,16 @@ static class Args public static SearchOption SearchOption { get { return Arg.Any(); } } public static GitFileStatus GitFileStatus { get { return Arg.Any(); } } public static GitConfigSource GitConfigSource { get { return Arg.Any(); } } + public static List GitLogs { get { return Arg.Any>(); } } public static GitStatus GitStatus { get { return Arg.Any(); } } + public static List GitLocks { get { return Arg.Any>(); } } public static IEnumerable EnumerableGitLock { get { return Arg.Any>(); } } public static IUser User { get { return Arg.Any(); } } + public static ConfigBranch? NullableConfigBranch { get { return Arg.Any(); } } + public static ConfigRemote? NullableConfigRemote { get { return Arg.Any(); } } + public static Dictionary LocalBranchDictionary { get { return Arg.Any>(); } } + public static Dictionary RemoteDictionary { get { return Arg.Any>(); } } + public static Dictionary> RemoteBranchDictionary { get { return Arg.Any>>(); } } public static ITask GitStatusTask {