diff --git a/src/AddIns/Misc/PackageManagement/Project/PackageManagement.csproj b/src/AddIns/Misc/PackageManagement/Project/PackageManagement.csproj index 09d9701692..eb7ec25457 100644 --- a/src/AddIns/Misc/PackageManagement/Project/PackageManagement.csproj +++ b/src/AddIns/Misc/PackageManagement/Project/PackageManagement.csproj @@ -80,6 +80,7 @@ + @@ -91,6 +92,8 @@ + + LicenseAcceptanceView.xaml @@ -109,6 +112,8 @@ + + diff --git a/src/AddIns/Misc/PackageManagement/Project/Src/AddPackageReferenceViewModel.cs b/src/AddIns/Misc/PackageManagement/Project/Src/AddPackageReferenceViewModel.cs index 50e342f05d..5990b7ddf6 100644 --- a/src/AddIns/Misc/PackageManagement/Project/Src/AddPackageReferenceViewModel.cs +++ b/src/AddIns/Misc/PackageManagement/Project/Src/AddPackageReferenceViewModel.cs @@ -15,12 +15,14 @@ namespace ICSharpCode.PackageManagement AvailablePackagesViewModel availablePackagesViewModel; PackageUpdatesViewModel packageUpdatesViewModel; - public AddPackageReferenceViewModel(IPackageManagementService packageManagementService) + public AddPackageReferenceViewModel( + IPackageManagementService packageManagementService, + ITaskFactory taskFactory) { this.packageManagementService = packageManagementService; - installedPackagesViewModel = new InstalledPackagesViewModel(packageManagementService); - availablePackagesViewModel = new AvailablePackagesViewModel(packageManagementService); - packageUpdatesViewModel = new PackageUpdatesViewModel(packageManagementService); + installedPackagesViewModel = new InstalledPackagesViewModel(packageManagementService, taskFactory); + availablePackagesViewModel = new AvailablePackagesViewModel(packageManagementService, taskFactory); + packageUpdatesViewModel = new PackageUpdatesViewModel(packageManagementService, taskFactory); installedPackagesViewModel.ReadPackages(); availablePackagesViewModel.ReadPackages(); diff --git a/src/AddIns/Misc/PackageManagement/Project/Src/AvailablePackagesViewModel.cs b/src/AddIns/Misc/PackageManagement/Project/Src/AvailablePackagesViewModel.cs index a7dd9075e2..4fb004f9a9 100644 --- a/src/AddIns/Misc/PackageManagement/Project/Src/AvailablePackagesViewModel.cs +++ b/src/AddIns/Misc/PackageManagement/Project/Src/AvailablePackagesViewModel.cs @@ -11,8 +11,10 @@ namespace ICSharpCode.PackageManagement { public class AvailablePackagesViewModel : PackagesViewModel { - public AvailablePackagesViewModel(IPackageManagementService packageManagementService) - : base(packageManagementService) + public AvailablePackagesViewModel( + IPackageManagementService packageManagementService, + ITaskFactory taskFactory) + : base(packageManagementService, taskFactory) { IsSearchable = true; ShowPackageSources = packageManagementService.HasMultiplePackageSources; diff --git a/src/AddIns/Misc/PackageManagement/Project/Src/Design/DesignTimePackagesViewModel.cs b/src/AddIns/Misc/PackageManagement/Project/Src/Design/DesignTimePackagesViewModel.cs index 925be2dd51..8b04991fa0 100644 --- a/src/AddIns/Misc/PackageManagement/Project/Src/Design/DesignTimePackagesViewModel.cs +++ b/src/AddIns/Misc/PackageManagement/Project/Src/Design/DesignTimePackagesViewModel.cs @@ -11,7 +11,7 @@ namespace ICSharpCode.PackageManagement.Design public class DesignTimePackagesViewModel : PackagesViewModel { public DesignTimePackagesViewModel() - : base(new DesignTimePackageManagementService()) + : base(new DesignTimePackageManagementService(), new PackageManagementTaskFactory()) { PageSize = 3; AddPackageViewModels(); diff --git a/src/AddIns/Misc/PackageManagement/Project/Src/Design/FakePackageManagementService.cs b/src/AddIns/Misc/PackageManagement/Project/Src/Design/FakePackageManagementService.cs index 3a2a0bca71..10d9c5dc10 100644 --- a/src/AddIns/Misc/PackageManagement/Project/Src/Design/FakePackageManagementService.cs +++ b/src/AddIns/Misc/PackageManagement/Project/Src/Design/FakePackageManagementService.cs @@ -38,10 +38,8 @@ namespace ICSharpCode.PackageManagement.Design public IPackageRepository RepositoryPassedToUninstallPackage; public IPackage PackagePassedToUninstallPackage; - public FakeProjectManager FakeActiveProjectManager { - get { return ActiveProjectManager as FakeProjectManager; } - set { ActiveProjectManager = value; } - } + public FakeProjectManager FakeActiveProjectManager { get; set; } + public FakePackageRepository FakeActivePackageRepository { get { return ActivePackageRepository as FakePackageRepository; } set { ActivePackageRepository = value; } @@ -55,7 +53,15 @@ namespace ICSharpCode.PackageManagement.Design } public IPackageRepository ActivePackageRepository { get; set; } - public IProjectManager ActiveProjectManager { get; set; } + + public IProjectManager ActiveProjectManager { + get { + if (ActiveProjectManagerExeptionToThrow != null) { + throw ActiveProjectManagerExeptionToThrow; + } + return FakeActiveProjectManager; + } + } public void InstallPackage(IPackageRepository repository, IPackage package) { @@ -117,5 +123,7 @@ namespace ICSharpCode.PackageManagement.Design { return FakeAggregateRepository; } + + public Exception ActiveProjectManagerExeptionToThrow { get; set; } } } diff --git a/src/AddIns/Misc/PackageManagement/Project/Src/ITask.cs b/src/AddIns/Misc/PackageManagement/Project/Src/ITask.cs new file mode 100644 index 0000000000..e38d568b37 --- /dev/null +++ b/src/AddIns/Misc/PackageManagement/Project/Src/ITask.cs @@ -0,0 +1,19 @@ +// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt) +// This code is distributed under the GNU LGPL (for details please see \doc\license.txt) + +using System; + +namespace ICSharpCode.PackageManagement +{ + public interface ITask + { + void Start(); + void Cancel(); + + TResult Result { get; } + + bool IsCancelled { get; } + bool IsFaulted { get; } + AggregateException Exception { get; } + } +} diff --git a/src/AddIns/Misc/PackageManagement/Project/Src/ITaskFactory.cs b/src/AddIns/Misc/PackageManagement/Project/Src/ITaskFactory.cs new file mode 100644 index 0000000000..dfda7faaf8 --- /dev/null +++ b/src/AddIns/Misc/PackageManagement/Project/Src/ITaskFactory.cs @@ -0,0 +1,14 @@ +// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt) +// This code is distributed under the GNU LGPL (for details please see \doc\license.txt) + +using System; + +namespace ICSharpCode.PackageManagement +{ + public interface ITaskFactory + { + ITask CreateTask( + Func function, + Action> continueWith); + } +} diff --git a/src/AddIns/Misc/PackageManagement/Project/Src/InstalledPackagesViewModel.cs b/src/AddIns/Misc/PackageManagement/Project/Src/InstalledPackagesViewModel.cs index 5b5207612c..7b9765337a 100644 --- a/src/AddIns/Misc/PackageManagement/Project/Src/InstalledPackagesViewModel.cs +++ b/src/AddIns/Misc/PackageManagement/Project/Src/InstalledPackagesViewModel.cs @@ -10,8 +10,10 @@ namespace ICSharpCode.PackageManagement { public class InstalledPackagesViewModel : PackagesViewModel { - public InstalledPackagesViewModel(IPackageManagementService packageManagementService) - : base(packageManagementService) + public InstalledPackagesViewModel( + IPackageManagementService packageManagementService, + ITaskFactory taskFactory) + : base(packageManagementService, taskFactory) { packageManagementService.PackageInstalled += PackageInstalled; packageManagementService.PackageUninstalled += PackageUninstalled; diff --git a/src/AddIns/Misc/PackageManagement/Project/Src/PackageManagementTask.cs b/src/AddIns/Misc/PackageManagement/Project/Src/PackageManagementTask.cs new file mode 100644 index 0000000000..cdc678d1d3 --- /dev/null +++ b/src/AddIns/Misc/PackageManagement/Project/Src/PackageManagementTask.cs @@ -0,0 +1,63 @@ +// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt) +// This code is distributed under the GNU LGPL (for details please see \doc\license.txt) + +using System; +using System.Threading; +using System.Threading.Tasks; + +namespace ICSharpCode.PackageManagement +{ + public class PackageManagementTask : ITask + { + Task task; + Action> continueWith; + CancellationTokenSource cancellationTokenSource; + + public PackageManagementTask( + Func function, + Action> continueWith) + { + this.continueWith = continueWith; + CreateTask(function); + } + + void CreateTask(Func function) + { + TaskScheduler scheduler = TaskScheduler.FromCurrentSynchronizationContext(); + cancellationTokenSource = new CancellationTokenSource(); + task = new Task(function, cancellationTokenSource.Token); + task.ContinueWith(result => OnContinueWith(result), scheduler); + } + + void OnContinueWith(Task task) + { + continueWith(this); + } + + public void Start() + { + task.Start(); + } + + public TResult Result { + get { return task.Result; } + } + + public void Cancel() + { + cancellationTokenSource.Cancel(); + } + + public bool IsCancelled { + get { return task.IsCanceled; } + } + + public bool IsFaulted { + get { return task.IsFaulted; } + } + + public AggregateException Exception { + get { return task.Exception; } + } + } +} diff --git a/src/AddIns/Misc/PackageManagement/Project/Src/PackageManagementTaskFactory.cs b/src/AddIns/Misc/PackageManagement/Project/Src/PackageManagementTaskFactory.cs new file mode 100644 index 0000000000..66c25e1fd1 --- /dev/null +++ b/src/AddIns/Misc/PackageManagement/Project/Src/PackageManagementTaskFactory.cs @@ -0,0 +1,21 @@ +// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt) +// This code is distributed under the GNU LGPL (for details please see \doc\license.txt) + +using System; +using System.Collections.Generic; +using System.Threading.Tasks; + +using NuGet; + +namespace ICSharpCode.PackageManagement +{ + public class PackageManagementTaskFactory : ITaskFactory + { + public ITask CreateTask( + Func function, + Action> continueWith) + { + return new PackageManagementTask(function, continueWith); + } + } +} diff --git a/src/AddIns/Misc/PackageManagement/Project/Src/PackageUpdatesViewModel.cs b/src/AddIns/Misc/PackageManagement/Project/Src/PackageUpdatesViewModel.cs index e4ec539fd8..93cdaad823 100644 --- a/src/AddIns/Misc/PackageManagement/Project/Src/PackageUpdatesViewModel.cs +++ b/src/AddIns/Misc/PackageManagement/Project/Src/PackageUpdatesViewModel.cs @@ -14,8 +14,10 @@ namespace ICSharpCode.PackageManagement List packages = new List(); IPackageManagementService packageManagementService; - public PackageUpdatesViewModel(IPackageManagementService packageManagementService) - : base(packageManagementService) + public PackageUpdatesViewModel( + IPackageManagementService packageManagementService, + ITaskFactory taskFactory) + : base(packageManagementService, taskFactory) { this.packageManagementService = packageManagementService; } diff --git a/src/AddIns/Misc/PackageManagement/Project/Src/PackagesForSelectedPageResult.cs b/src/AddIns/Misc/PackageManagement/Project/Src/PackagesForSelectedPageResult.cs new file mode 100644 index 0000000000..db53f5ce9f --- /dev/null +++ b/src/AddIns/Misc/PackageManagement/Project/Src/PackagesForSelectedPageResult.cs @@ -0,0 +1,25 @@ +// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt) +// This code is distributed under the GNU LGPL (for details please see \doc\license.txt) + +using System; +using System.Collections.Generic; +using System.Linq; + +using NuGet; + +namespace ICSharpCode.PackageManagement +{ + public class PackagesForSelectedPageResult + { + public PackagesForSelectedPageResult(IEnumerable packages, int totalPackages) + { + this.Packages = packages; + this.TotalPackagesOnPage = packages.Count(); + this.TotalPackages = totalPackages; + } + + public IEnumerable Packages { get; set; } + public int TotalPackagesOnPage { get; set; } + public int TotalPackages { get; set; } + } +} diff --git a/src/AddIns/Misc/PackageManagement/Project/Src/PackagesView.xaml b/src/AddIns/Misc/PackageManagement/Project/Src/PackagesView.xaml index 152e1aced0..6ae59390f2 100644 --- a/src/AddIns/Misc/PackageManagement/Project/Src/PackagesView.xaml +++ b/src/AddIns/Misc/PackageManagement/Project/Src/PackagesView.xaml @@ -232,6 +232,14 @@ ItemsSource="{Binding Path=PackageViewModels}" HorizontalContentAlignment="Stretch" ScrollViewer.HorizontalScrollBarVisibility="Disabled"/> + allPackages; string searchTerms; + bool isReadingPackages; + ITask task; + int totalItems; + bool hasError; + string errorMessage = String.Empty; - public PackagesViewModel(IPackageManagementService packageManagementService) - : this(packageManagementService, new LicenseAcceptanceService()) + public PackagesViewModel(IPackageManagementService packageManagementService, ITaskFactory taskFactory) + : this( + packageManagementService, + new LicenseAcceptanceService(), + taskFactory) { } public PackagesViewModel( IPackageManagementService packageManagementService, - ILicenseAcceptanceService licenseAcceptanceService) + ILicenseAcceptanceService licenseAcceptanceService, + ITaskFactory taskFactory) : this( packageManagementService, - new PackageViewModelFactory(packageManagementService, licenseAcceptanceService)) + new PackageViewModelFactory(packageManagementService, licenseAcceptanceService), + taskFactory) { } public PackagesViewModel( IPackageManagementService packageManagementService, - IPackageViewModelFactory packageViewModelFactory) + IPackageViewModelFactory packageViewModelFactory, + ITaskFactory taskFactory) { this.packageManagementService = packageManagementService; this.packageViewModelFactory = packageViewModelFactory; - this.projectManager = packageManagementService.ActiveProjectManager; + this.taskFactory = taskFactory; + GetActiveProjectManager(); + CreateCommands(); } + void GetActiveProjectManager() + { + try { + this.projectManager = packageManagementService.ActiveProjectManager; + } catch (Exception ex) { + SaveError(ex); + } + } + + void SaveError(Exception ex) + { + hasError = true; + errorMessage = ex.Message; + } + void CreateCommands() { showNextPageCommand = new DelegateCommand(param => ShowNextPage()); @@ -77,6 +106,14 @@ namespace ICSharpCode.PackageManagement get { return searchCommand; } } + public bool HasError { + get { return hasError; } + } + + public string ErrorMessage { + get { return errorMessage; } + } + public ObservableCollection PackageViewModels { get { return packageViewModels; } set { packageViewModels = value; } @@ -90,42 +127,80 @@ namespace ICSharpCode.PackageManagement get { return projectManager; } } + public bool IsReadingPackages { + get { return isReadingPackages; } + } + public void ReadPackages() { allPackages = null; SelectedPageNumber = 1; - UpdatePackageViewModels(); + StartReadPackagesTask(); } - void PagesChanged(object sender, NotifyCollectionChangedEventArgs e) + void StartReadPackagesTask() { - UpdatePackageViewModels(); - base.OnPropertyChanged(null); + isReadingPackages = true; + ClearPackages(); + CancelReadPackagesTask(); + CreateReadPackagesTask(); + task.Start(); + } + + void CancelReadPackagesTask() + { + if (task != null) { + task.Cancel(); + } + } + + void CreateReadPackagesTask() + { + task = taskFactory.CreateTask( + () => GetPackagesForSelectedPageResult(), + (result) => OnPackagesReadForSelectedPage(result)); } - void UpdatePackageViewModels() + PackagesForSelectedPageResult GetPackagesForSelectedPageResult() { + IEnumerable packages = GetPackagesForSelectedPage(); + return new PackagesForSelectedPageResult(packages, totalItems); + } + + void OnPackagesReadForSelectedPage(ITask task) + { + isReadingPackages = false; + if (task.IsFaulted) { + SaveError(task.Exception); + } else if (task.IsCancelled) { + // Ignore + } else { + UpdatePackagesForSelectedPage(task.Result); + } + base.OnPropertyChanged(null); + } + + void UpdatePackagesForSelectedPage(PackagesForSelectedPageResult result) + { pages.CollectionChanged -= PagesChanged; - IEnumerable packages = GetPackagesForSelectedPage(); - pages.TotalItemsOnSelectedPage = packages.Count(); - UpdatePackageViewModels(packages); + pages.TotalItems = result.TotalPackages; + pages.TotalItemsOnSelectedPage = result.TotalPackagesOnPage; + UpdatePackageViewModels(result.Packages); pages.CollectionChanged += PagesChanged; } - IEnumerable GetPackagesForSelectedPage() + void PagesChanged(object sender, NotifyCollectionChangedEventArgs e) { - IEnumerable filteredPackages = GetFilteredPackagesBeforePagingResults(); - return GetPackagesForSelectedPage(filteredPackages); + StartReadPackagesTask(); + base.OnPropertyChanged(null); } - IEnumerable GetPackagesForSelectedPage(IEnumerable allPackages) + IEnumerable GetPackagesForSelectedPage() { - int packagesToSkip = pages.ItemsBeforeFirstPage; - return allPackages - .Skip(packagesToSkip) - .Take(pages.PageSize); + IEnumerable filteredPackages = GetFilteredPackagesBeforePagingResults(); + return GetPackagesForSelectedPage(filteredPackages); } IEnumerable GetFilteredPackagesBeforePagingResults() @@ -133,12 +208,20 @@ namespace ICSharpCode.PackageManagement if (allPackages == null) { IQueryable packages = GetAllPackages(); packages = packages.Find(searchTerms); - pages.TotalItems = packages.Count(); + totalItems = packages.Count(); allPackages = GetFilteredPackagesBeforePagingResults(packages); } return allPackages; } + IEnumerable GetPackagesForSelectedPage(IEnumerable allPackages) + { + int packagesToSkip = pages.ItemsBeforeFirstPage; + return allPackages + .Skip(packagesToSkip) + .Take(pages.PageSize); + } + /// /// Returns all the packages. /// @@ -170,10 +253,15 @@ namespace ICSharpCode.PackageManagement void UpdatePackageViewModels(IEnumerable newPackageViewModels) { - PackageViewModels.Clear(); + ClearPackages(); PackageViewModels.AddRange(newPackageViewModels); } + void ClearPackages() + { + PackageViewModels.Clear(); + } + public IEnumerable ConvertToPackageViewModels(IEnumerable packages) { foreach (IPackage package in packages) { @@ -217,6 +305,10 @@ namespace ICSharpCode.PackageManagement set { pages.MaximumSelectablePages = value; } } + public int TotalItems { + get { return totalItems; } + } + public void ShowNextPage() { SelectedPageNumber += 1; diff --git a/src/AddIns/Misc/PackageManagement/Project/Src/ViewModelLocator.cs b/src/AddIns/Misc/PackageManagement/Project/Src/ViewModelLocator.cs index 6762572a25..c1b5bd4d72 100644 --- a/src/AddIns/Misc/PackageManagement/Project/Src/ViewModelLocator.cs +++ b/src/AddIns/Misc/PackageManagement/Project/Src/ViewModelLocator.cs @@ -24,7 +24,7 @@ namespace ICSharpCode.PackageManagement void CreateAddPackageReferenceViewModel() { CreatePackageManagementService(); - addPackageReferenceViewModel = new AddPackageReferenceViewModel(packageManagementService); + addPackageReferenceViewModel = new AddPackageReferenceViewModel(packageManagementService, new PackageManagementTaskFactory()); } void CreatePackageManagementService() diff --git a/src/AddIns/Misc/PackageManagement/Test/PackageManagement.Tests.csproj b/src/AddIns/Misc/PackageManagement/Test/PackageManagement.Tests.csproj index c9c8292807..163613fb6c 100644 --- a/src/AddIns/Misc/PackageManagement/Test/PackageManagement.Tests.csproj +++ b/src/AddIns/Misc/PackageManagement/Test/PackageManagement.Tests.csproj @@ -77,6 +77,8 @@ + + diff --git a/src/AddIns/Misc/PackageManagement/Test/Src/AddPackageReferenceViewModelTests.cs b/src/AddIns/Misc/PackageManagement/Test/Src/AddPackageReferenceViewModelTests.cs index b8ed4b9af5..ec598f63cd 100644 --- a/src/AddIns/Misc/PackageManagement/Test/Src/AddPackageReferenceViewModelTests.cs +++ b/src/AddIns/Misc/PackageManagement/Test/Src/AddPackageReferenceViewModelTests.cs @@ -16,11 +16,12 @@ namespace PackageManagement.Tests public class AddPackageReferenceViewModelTests { AddPackageReferenceViewModel viewModel; - FakePackageManagementService fakePackageManagementService; + FakePackageManagementService fakePackageManagementService; + FakeTaskFactory taskFactory; void CreatePackageManagementService() { - fakePackageManagementService = new FakePackageManagementService(); + fakePackageManagementService = new FakePackageManagementService(); } void CreateViewModel() @@ -31,7 +32,9 @@ namespace PackageManagement.Tests void CreateViewModel(FakePackageManagementService packageManagementService) { - viewModel = new AddPackageReferenceViewModel(packageManagementService); + taskFactory = new FakeTaskFactory(); + viewModel = new AddPackageReferenceViewModel(packageManagementService, taskFactory); + taskFactory.ExecuteAllFakeTasks(); } [Test] @@ -39,7 +42,7 @@ namespace PackageManagement.Tests { CreatePackageManagementService(); var projectManager = new FakeProjectManager(); - fakePackageManagementService.ActiveProjectManager = projectManager; + fakePackageManagementService.FakeActiveProjectManager = projectManager; FakePackage package = new FakePackage(); projectManager.FakeLocalRepository.FakePackages.Add(package); CreateViewModel(fakePackageManagementService); diff --git a/src/AddIns/Misc/PackageManagement/Test/Src/AvailablePackagesViewModelTests.cs b/src/AddIns/Misc/PackageManagement/Test/Src/AvailablePackagesViewModelTests.cs index 37852a8706..1bd4a1f004 100644 --- a/src/AddIns/Misc/PackageManagement/Test/Src/AvailablePackagesViewModelTests.cs +++ b/src/AddIns/Misc/PackageManagement/Test/Src/AvailablePackagesViewModelTests.cs @@ -16,6 +16,7 @@ namespace PackageManagement.Tests { AvailablePackagesViewModel viewModel; FakePackageManagementService packageManagementService; + FakeTaskFactory taskFactory = new FakeTaskFactory(); void CreateViewModel() { @@ -30,9 +31,20 @@ namespace PackageManagement.Tests void CreateViewModel(IPackageManagementService packageManagementService) { - viewModel = new AvailablePackagesViewModel(packageManagementService); + taskFactory = new FakeTaskFactory(); + viewModel = new AvailablePackagesViewModel(packageManagementService, taskFactory); } + void CompleteReadPackagesTask() + { + taskFactory.ExecuteAllFakeTasks(); + } + + void ClearReadPackagesTasks() + { + taskFactory.ClearAllFakeTasks(); + } + void AddOnePackageSourceToRegisteredSources() { packageManagementService.ClearPackageSources(); @@ -70,7 +82,8 @@ namespace PackageManagement.Tests AddTwoPackageSourcesToRegisteredSources(); CreateViewModel(packageManagementService); packageManagementService.ActivePackageSource = packageManagementService.Options.PackageSources[0]; - viewModel.ReadPackages(); + viewModel.ReadPackages(); + CompleteReadPackagesTask(); CreateNewActiveRepositoryWithDifferentPackages(); } @@ -110,6 +123,7 @@ namespace PackageManagement.Tests packageManagementService.FakeActivePackageRepository.FakePackages.AddRange(packages); viewModel.ReadPackages(); + CompleteReadPackagesTask(); var expectedPackages = new FakePackage[] { package3 @@ -152,9 +166,12 @@ namespace PackageManagement.Tests packageManagementService.FakeActivePackageRepository.FakePackages.AddRange(packages); viewModel.ReadPackages(); + CompleteReadPackagesTask(); + ClearReadPackagesTasks(); viewModel.SearchTerms = "NotAMatch"; viewModel.Search(); + CompleteReadPackagesTask(); Assert.AreEqual(0, viewModel.PackageViewModels.Count); } @@ -192,10 +209,13 @@ namespace PackageManagement.Tests packageManagementService.FakeActivePackageRepository.FakePackages.AddRange(packages); viewModel.ReadPackages(); + CompleteReadPackagesTask(); + ClearReadPackagesTasks(); bool collectionChangedEventFired = false; viewModel.Pages.CollectionChanged += (sender, e) => collectionChangedEventFired = true; viewModel.ShowNextPage(); + CompleteReadPackagesTask(); var expectedPackages = new FakePackage[] { package4 @@ -281,7 +301,9 @@ namespace PackageManagement.Tests public void SelectedPackageSource_PackageSourceChangedAfterReadingPackages_PackagesReadFromNewPackageSourceAndDisplayed() { SetUpTwoPackageSourcesAndViewModelHasReadPackages(); + ClearReadPackagesTasks(); ChangeSelectedPackageSourceToSecondSource(); + CompleteReadPackagesTask(); var expectedPackages = packageManagementService.FakeActivePackageRepository.FakePackages; @@ -295,7 +317,9 @@ namespace PackageManagement.Tests int packageCountWhenPropertyChangedEventFired = -1; viewModel.PropertyChanged += (sender, e) => packageCountWhenPropertyChangedEventFired = viewModel.PackageViewModels.Count; + ClearReadPackagesTasks(); ChangeSelectedPackageSourceToSecondSource(); + CompleteReadPackagesTask(); Assert.AreEqual(1, packageCountWhenPropertyChangedEventFired); } diff --git a/src/AddIns/Misc/PackageManagement/Test/Src/Helpers/FakeTask.cs b/src/AddIns/Misc/PackageManagement/Test/Src/Helpers/FakeTask.cs new file mode 100644 index 0000000000..d26153e105 --- /dev/null +++ b/src/AddIns/Misc/PackageManagement/Test/Src/Helpers/FakeTask.cs @@ -0,0 +1,58 @@ +// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt) +// This code is distributed under the GNU LGPL (for details please see \doc\license.txt) + +using System; +using ICSharpCode.PackageManagement; + +namespace PackageManagement.Tests.Helpers +{ + public class FakeTask : ITask + { + public bool IsStartCalled; + public bool IsCancelCalled; + + Func function; + Action> continueWith; + + public FakeTask(Func function, Action> continueWith) + { + this.function = function; + this.continueWith = continueWith; + Exception = new AggregateException(); + } + + public void Start() + { + IsStartCalled = true; + } + + public TResult Result { get; set; } + + public void ExecuteTaskCompletely() + { + ExecuteTaskButNotContinueWith(); + ExecuteContinueWith(); + } + + public TResult ExecuteTaskButNotContinueWith() + { + Result = function(); + return Result; + } + + public void ExecuteContinueWith() + { + continueWith(this); + } + + public void Cancel() + { + IsCancelCalled = true; + } + + public bool IsCancelled { get;set; } + public bool IsFaulted { get; set; } + + public AggregateException Exception { get; set; } + } +} diff --git a/src/AddIns/Misc/PackageManagement/Test/Src/Helpers/FakeTaskFactory.cs b/src/AddIns/Misc/PackageManagement/Test/Src/Helpers/FakeTaskFactory.cs new file mode 100644 index 0000000000..521fd577d8 --- /dev/null +++ b/src/AddIns/Misc/PackageManagement/Test/Src/Helpers/FakeTaskFactory.cs @@ -0,0 +1,43 @@ +// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt) +// This code is distributed under the GNU LGPL (for details please see \doc\license.txt) + +using System; +using System.Collections.Generic; +using ICSharpCode.PackageManagement; +using NuGet; + +namespace PackageManagement.Tests.Helpers +{ + public class FakeTaskFactory : ITaskFactory + { + public bool IsCreateTaskCalled; + + public FakeTask FirstFakeTaskCreated { + get { return FakeTasksCreated[0] as FakeTask; } + } + + public List FakeTasksCreated = new List(); + + public ITask CreateTask( + Func function, + Action> continueWith) + { + IsCreateTaskCalled = true; + var task = new FakeTask(function, continueWith); + FakeTasksCreated.Add(task); + return task; + } + + public void ExecuteAllFakeTasks() + { + foreach (FakeTask task in FakeTasksCreated) { + task.ExecuteTaskCompletely(); + } + } + + public void ClearAllFakeTasks() + { + FakeTasksCreated.Clear(); + } + } +} diff --git a/src/AddIns/Misc/PackageManagement/Test/Src/Helpers/TestablePackagesViewModel.cs b/src/AddIns/Misc/PackageManagement/Test/Src/Helpers/TestablePackagesViewModel.cs index 571136d6ba..a7f6affcf8 100644 --- a/src/AddIns/Misc/PackageManagement/Test/Src/Helpers/TestablePackagesViewModel.cs +++ b/src/AddIns/Misc/PackageManagement/Test/Src/Helpers/TestablePackagesViewModel.cs @@ -14,6 +14,7 @@ namespace PackageManagement.Tests.Helpers public class TestablePackagesViewModel : PackagesViewModel { public FakePackageManagementService FakePackageManagementService; + public FakeTaskFactory FakeTaskFactory; public List FakePackages = new List(); public int GetAllPackagesCallCount; public int PageCountBeforePackagesFiltered; @@ -24,9 +25,15 @@ namespace PackageManagement.Tests.Helpers } public TestablePackagesViewModel(FakePackageManagementService packageManagementService) - : base(packageManagementService) + : this(packageManagementService, new FakeTaskFactory()) + { + } + + public TestablePackagesViewModel(FakePackageManagementService packageManagementService, FakeTaskFactory taskFactory) + : base(packageManagementService, taskFactory) { FakePackageManagementService = packageManagementService; + FakeTaskFactory = taskFactory; } public void AddOneFakePackage() diff --git a/src/AddIns/Misc/PackageManagement/Test/Src/InstalledPackagesViewModelTests.cs b/src/AddIns/Misc/PackageManagement/Test/Src/InstalledPackagesViewModelTests.cs index d6e379932e..0b906a2be3 100644 --- a/src/AddIns/Misc/PackageManagement/Test/Src/InstalledPackagesViewModelTests.cs +++ b/src/AddIns/Misc/PackageManagement/Test/Src/InstalledPackagesViewModelTests.cs @@ -6,6 +6,7 @@ using ICSharpCode.PackageManagement; using ICSharpCode.PackageManagement.Design; using NuGet; using NUnit.Framework; +using PackageManagement.Tests.Helpers; namespace PackageManagement.Tests { @@ -14,11 +15,23 @@ namespace PackageManagement.Tests { InstalledPackagesViewModel viewModel; FakePackageManagementService packageManagementService; + FakeTaskFactory taskFactory; void CreateViewModel() { packageManagementService = new FakePackageManagementService(); - viewModel = new InstalledPackagesViewModel(packageManagementService); + taskFactory = new FakeTaskFactory(); + viewModel = new InstalledPackagesViewModel(packageManagementService, taskFactory); + } + + void CompleteReadPackagesTask() + { + taskFactory.ExecuteAllFakeTasks(); + } + + void ClearReadPackagesTasks() + { + taskFactory.ClearAllFakeTasks(); } [Test] @@ -26,12 +39,15 @@ namespace PackageManagement.Tests { CreateViewModel(); viewModel.ReadPackages(); + CompleteReadPackagesTask(); FakePackage package = new FakePackage(); package.Id = "Test"; FakePackageRepository repository = packageManagementService.FakeActiveProjectManager.FakeLocalRepository; repository.FakePackages.Add(package); + ClearReadPackagesTasks(); packageManagementService.FirePackageInstalled(); + CompleteReadPackagesTask(); IPackage firstPackage = viewModel.PackageViewModels[0].GetPackage(); Assert.AreEqual(package, firstPackage); @@ -46,10 +62,13 @@ namespace PackageManagement.Tests FakePackageRepository repository = packageManagementService.FakeActiveProjectManager.FakeLocalRepository; repository.FakePackages.Add(package); viewModel.ReadPackages(); + CompleteReadPackagesTask(); repository.FakePackages.Clear(); + ClearReadPackagesTasks(); packageManagementService.FirePackageUninstalled(); + CompleteReadPackagesTask(); Assert.AreEqual(0, viewModel.PackageViewModels.Count); } diff --git a/src/AddIns/Misc/PackageManagement/Test/Src/PackageUpdatesViewModelTests.cs b/src/AddIns/Misc/PackageManagement/Test/Src/PackageUpdatesViewModelTests.cs index 2e43437ebf..920bd37902 100644 --- a/src/AddIns/Misc/PackageManagement/Test/Src/PackageUpdatesViewModelTests.cs +++ b/src/AddIns/Misc/PackageManagement/Test/Src/PackageUpdatesViewModelTests.cs @@ -14,13 +14,20 @@ namespace PackageManagement.Tests { PackageUpdatesViewModel viewModel; FakePackageManagementService packageManagementService; + FakeTaskFactory taskFactory; void CreateViewModel() { packageManagementService = new FakePackageManagementService(); - viewModel = new PackageUpdatesViewModel(packageManagementService); + taskFactory = new FakeTaskFactory(); + viewModel = new PackageUpdatesViewModel(packageManagementService, taskFactory); } + void CompleteReadPackagesTask() + { + taskFactory.ExecuteAllFakeTasks(); + } + FakePackage AddPackageToLocalRepository(string version) { var package = CreatePackage(version); @@ -53,6 +60,7 @@ namespace PackageManagement.Tests var newerPackage = AddPackageToSourceRepository("1.1.0.0"); viewModel.ReadPackages(); + CompleteReadPackagesTask(); var expectedPackages = new FakePackage[] { newerPackage @@ -70,6 +78,7 @@ namespace PackageManagement.Tests var newerPackage = AddPackageToSourceRepository("1.1.0.0"); viewModel.ReadPackages(); + CompleteReadPackagesTask(); var expectedPackages = new FakePackage[] { newerPackage diff --git a/src/AddIns/Misc/PackageManagement/Test/Src/PackagesViewModelTests.cs b/src/AddIns/Misc/PackageManagement/Test/Src/PackagesViewModelTests.cs index b23e6dcaea..0f9bae6cc9 100644 --- a/src/AddIns/Misc/PackageManagement/Test/Src/PackagesViewModelTests.cs +++ b/src/AddIns/Misc/PackageManagement/Test/Src/PackagesViewModelTests.cs @@ -18,14 +18,37 @@ namespace PackageManagement.Tests public class PackagesViewModelTests { TestablePackagesViewModel viewModel; + FakeTaskFactory taskFactory; FakePackageManagementService packageManagementService; + void CreateViewModel(FakePackageManagementService packageManagementService) + { + viewModel = new TestablePackagesViewModel(packageManagementService); + this.packageManagementService = packageManagementService; + taskFactory = viewModel.FakeTaskFactory; + } + void CreateViewModel() { - viewModel = new TestablePackagesViewModel(); - packageManagementService = viewModel.FakePackageManagementService; + CreatePackageManagementService(); + CreateViewModel(packageManagementService); + } + + void CreatePackageManagementService() + { + packageManagementService = new FakePackageManagementService(); } + void CompleteReadPackagesTask() + { + taskFactory.ExecuteAllFakeTasks(); + } + + void ClearReadPackagesTasks() + { + taskFactory.ClearAllFakeTasks(); + } + [Test] public void IsPaged_OnePackageAndPageSizeIsFive_ReturnsFalse() { @@ -33,6 +56,7 @@ namespace PackageManagement.Tests viewModel.PageSize = 5; viewModel.AddOneFakePackage(); viewModel.ReadPackages(); + CompleteReadPackagesTask(); bool paged = viewModel.IsPaged; @@ -46,6 +70,7 @@ namespace PackageManagement.Tests viewModel.PageSize = 5; viewModel.AddSixFakePackages(); viewModel.ReadPackages(); + CompleteReadPackagesTask(); bool paged = viewModel.IsPaged; @@ -69,6 +94,7 @@ namespace PackageManagement.Tests viewModel.PageSize = 5; viewModel.AddSixFakePackages(); viewModel.ReadPackages(); + CompleteReadPackagesTask(); viewModel.SelectedPageNumber = 1; Assert.IsFalse(viewModel.HasPreviousPage); @@ -81,6 +107,7 @@ namespace PackageManagement.Tests viewModel.PageSize = 5; viewModel.AddSixFakePackages(); viewModel.ReadPackages(); + CompleteReadPackagesTask(); viewModel.SelectedPageNumber = 2; Assert.IsTrue(viewModel.HasPreviousPage); @@ -94,6 +121,7 @@ namespace PackageManagement.Tests viewModel.AddSixFakePackages(); viewModel.SelectedPageNumber = 1; viewModel.ReadPackages(); + CompleteReadPackagesTask(); PropertyChangedEventArgs propertyChangedEvent = null; viewModel.PropertyChanged += (sender, e) => propertyChangedEvent = e; @@ -111,6 +139,7 @@ namespace PackageManagement.Tests viewModel.PageSize = 5; viewModel.AddSixFakePackages(); viewModel.ReadPackages(); + CompleteReadPackagesTask(); viewModel.SelectedPageNumber = 1; Assert.IsTrue(viewModel.HasNextPage); @@ -123,6 +152,7 @@ namespace PackageManagement.Tests viewModel.PageSize = 5; viewModel.AddSixFakePackages(); viewModel.ReadPackages(); + CompleteReadPackagesTask(); viewModel.SelectedPageNumber = 2; Assert.IsFalse(viewModel.HasNextPage); @@ -135,6 +165,7 @@ namespace PackageManagement.Tests viewModel.PageSize = 2; viewModel.AddSixFakePackages(); viewModel.ReadPackages(); + CompleteReadPackagesTask(); viewModel.SelectedPageNumber = 2; Assert.IsTrue(viewModel.HasNextPage); @@ -147,6 +178,7 @@ namespace PackageManagement.Tests viewModel.PageSize = 5; viewModel.AddSixFakePackages(); viewModel.ReadPackages(); + CompleteReadPackagesTask(); viewModel.SelectedPageNumber = 2; Page[] expectedPages = new Page[] { @@ -166,6 +198,7 @@ namespace PackageManagement.Tests viewModel.PageSize = 5; viewModel.AddSixFakePackages(); viewModel.ReadPackages(); + CompleteReadPackagesTask(); viewModel.SelectedPageNumber = 1; Page[] expectedPages = new Page[] { @@ -185,6 +218,7 @@ namespace PackageManagement.Tests viewModel.PageSize = 2; viewModel.AddSixFakePackages(); viewModel.ReadPackages(); + CompleteReadPackagesTask(); viewModel.SelectedPageNumber = 1; Page[] expectedPages = new Page[] { @@ -205,6 +239,7 @@ namespace PackageManagement.Tests viewModel.PageSize = 2; viewModel.AddSixFakePackages(); viewModel.ReadPackages(); + CompleteReadPackagesTask(); viewModel.SelectedPageNumber = 1; viewModel.MaximumSelectablePages = 2; @@ -225,6 +260,7 @@ namespace PackageManagement.Tests viewModel.PageSize = 5; viewModel.AddSixFakePackages(); viewModel.ReadPackages(); + CompleteReadPackagesTask(); viewModel.SelectedPageNumber = 1; Page[] expectedPages = new Page[] { @@ -245,6 +281,7 @@ namespace PackageManagement.Tests viewModel.PageSize = 2; viewModel.AddSixFakePackages(); viewModel.ReadPackages(); + CompleteReadPackagesTask(); viewModel.SelectedPageNumber = 3; viewModel.MaximumSelectablePages = 2; @@ -265,6 +302,7 @@ namespace PackageManagement.Tests viewModel.PageSize = 2; viewModel.AddTenFakePackages(); viewModel.ReadPackages(); + CompleteReadPackagesTask(); viewModel.SelectedPageNumber = 5; viewModel.MaximumSelectablePages = 3; @@ -287,12 +325,15 @@ namespace PackageManagement.Tests viewModel.SelectedPageNumber = 1; viewModel.AddThreeFakePackages(); viewModel.ReadPackages(); + CompleteReadPackagesTask(); var expectedPackages = new List(); expectedPackages.Add(viewModel.FakePackages[0]); expectedPackages.Add(viewModel.FakePackages[1]); + ClearReadPackagesTasks(); viewModel.ReadPackages(); + CompleteReadPackagesTask(); PackageCollectionAssert.AreEqual(expectedPackages, viewModel.PackageViewModels); } @@ -305,13 +346,16 @@ namespace PackageManagement.Tests viewModel.SelectedPageNumber = 1; viewModel.AddSixFakePackages(); viewModel.ReadPackages(); + CompleteReadPackagesTask(); var expectedPackages = new List(); expectedPackages.Add(viewModel.FakePackages[0]); expectedPackages.Add(viewModel.FakePackages[1]); expectedPackages.Add(viewModel.FakePackages[2]); - + + ClearReadPackagesTasks(); viewModel.ReadPackages(); + CompleteReadPackagesTask(); PackageCollectionAssert.AreEqual(expectedPackages, viewModel.PackageViewModels); } @@ -323,6 +367,7 @@ namespace PackageManagement.Tests viewModel.PageSize = 10; viewModel.AddSixFakePackages(); viewModel.ReadPackages(); + CompleteReadPackagesTask(); int oldPageCount = viewModel.Pages.Count; viewModel.PageSize = 5; @@ -340,9 +385,12 @@ namespace PackageManagement.Tests viewModel.SelectedPageNumber = 1; viewModel.AddSixFakePackages(); viewModel.ReadPackages(); + CompleteReadPackagesTask(); + ClearReadPackagesTasks(); var oldPages = viewModel.Pages; viewModel.SelectedPageNumber = 2; + CompleteReadPackagesTask(); var newPages = viewModel.Pages; Page[] expectedPages = new Page[] { @@ -361,6 +409,7 @@ namespace PackageManagement.Tests viewModel.SelectedPageNumber = 1; viewModel.AddSixFakePackages(); viewModel.ReadPackages(); + CompleteReadPackagesTask(); viewModel.ShowNextPageCommand.Execute(null); @@ -377,8 +426,11 @@ namespace PackageManagement.Tests viewModel.PageSize = 2; viewModel.SelectedPageNumber = 1; viewModel.ReadPackages(); + CompleteReadPackagesTask(); + ClearReadPackagesTasks(); viewModel.ShowNextPageCommand.Execute(null); + CompleteReadPackagesTask(); var expectedPackages = new List(); expectedPackages.Add(viewModel.FakePackages[2]); @@ -393,6 +445,7 @@ namespace PackageManagement.Tests viewModel.PageSize = 3; viewModel.AddSixFakePackages(); viewModel.ReadPackages(); + CompleteReadPackagesTask(); viewModel.SelectedPageNumber = 2; viewModel.ShowPreviousPageCommand.Execute(null); @@ -409,9 +462,12 @@ namespace PackageManagement.Tests viewModel.AddThreeFakePackages(); viewModel.PageSize = 2; viewModel.ReadPackages(); + CompleteReadPackagesTask(); viewModel.SelectedPageNumber = 2; + ClearReadPackagesTasks(); viewModel.ShowPreviousPageCommand.Execute(null); + CompleteReadPackagesTask(); var expectedPackages = new List(); expectedPackages.Add(viewModel.FakePackages[0]); @@ -427,6 +483,7 @@ namespace PackageManagement.Tests viewModel.PageSize = 2; viewModel.AddSixFakePackages(); viewModel.ReadPackages(); + CompleteReadPackagesTask(); viewModel.SelectedPageNumber = 2; int pageNumber = 1; @@ -443,6 +500,7 @@ namespace PackageManagement.Tests CreateViewModel(); viewModel.AddSixFakePackages(); viewModel.ReadPackages(); + CompleteReadPackagesTask(); bool result = viewModel.IsPaged; int count = viewModel.Pages.Count; @@ -455,9 +513,15 @@ namespace PackageManagement.Tests CreateViewModel(); viewModel.PageSize = 3; viewModel.AddSixFakePackages(); + viewModel.ReadPackages(); + CompleteReadPackagesTask(); + viewModel.ReadPackages(); + CompleteReadPackagesTask(); + viewModel.ReadPackages(); + CompleteReadPackagesTask(); int count = 0; viewModel.PropertyChanged += (sender, e) => count++; @@ -497,9 +561,12 @@ namespace PackageManagement.Tests viewModel.FakePackages.Add(package); viewModel.ReadPackages(); + CompleteReadPackagesTask(); + ClearReadPackagesTasks(); viewModel.SearchTerms = "SearchedForId"; viewModel.SearchCommand.Execute(null); + CompleteReadPackagesTask(); var expectedPackages = new FakePackage[] { package @@ -572,11 +639,14 @@ namespace PackageManagement.Tests viewModel.FakePackages.Add(package); viewModel.ReadPackages(); + CompleteReadPackagesTask(); ObservableCollection pages = viewModel.Pages; + ClearReadPackagesTasks(); viewModel.SearchTerms = "SearchedForId"; viewModel.Search(); + CompleteReadPackagesTask(); var expectedPages = new Page[] { new Page() { Number = 1, IsSelected = true } @@ -641,11 +711,14 @@ namespace PackageManagement.Tests }; viewModel.FakePackages.Add(package); viewModel.ReadPackages(); + CompleteReadPackagesTask(); viewModel.SelectedPageNumber = 2; + ClearReadPackagesTasks(); viewModel.SearchTerms = "SearchedForId"; viewModel.Search(); + CompleteReadPackagesTask(); Assert.AreEqual(1, viewModel.SelectedPageNumber); } @@ -656,15 +729,16 @@ namespace PackageManagement.Tests /// if this is not done when we only want 30 retrieved in one go. /// [Test] - public void ReadPackages_SixPackagesInRepository_TotalPagesSetBeforePackagesFiltered() + public void ReadPackages_SixPackagesInRepository_TotalItemsSetBeforePackagesFiltered() { CreateViewModel(); viewModel.PageSize = 2; viewModel.AddSixFakePackages(); viewModel.ReadPackages(); + CompleteReadPackagesTask(); - int expectedPages = 3; - Assert.AreEqual(expectedPages, viewModel.PageCountBeforePackagesFiltered); + int expectedTotal = 6; + Assert.AreEqual(expectedTotal, viewModel.TotalItems); } [Test] @@ -674,12 +748,15 @@ namespace PackageManagement.Tests viewModel.PageSize = 2; viewModel.AddSixFakePackages(); viewModel.ReadPackages(); + CompleteReadPackagesTask(); viewModel.SearchTerms = "SearchedForId"; + ClearReadPackagesTasks(); bool paged = true; viewModel.PropertyChanged += (sender, e) => paged = viewModel.IsPaged; viewModel.Search(); + CompleteReadPackagesTask(); Assert.IsFalse(paged); } @@ -698,11 +775,14 @@ namespace PackageManagement.Tests viewModel.FakePackages.Add(new FakePackage("SearchedForId3")); viewModel.ReadPackages(); + CompleteReadPackagesTask(); ObservableCollection pages = viewModel.Pages; + ClearReadPackagesTasks(); viewModel.SearchTerms = "SearchedForId"; viewModel.Search(); + CompleteReadPackagesTask(); var expectedPages = new Page[] { new Page() { Number = 1, IsSelected = true }, @@ -719,5 +799,302 @@ namespace PackageManagement.Tests Assert.IsFalse(viewModel.ShowPackageSources); } + + [Test] + public void ReadPackages_OnePackageInRepository_CreatesTask() + { + CreateViewModel(); + viewModel.AddOneFakePackage(); + + viewModel.ReadPackages(); + + Assert.IsTrue(taskFactory.IsCreateTaskCalled); + } + + [Test] + public void ReadPackages_OnePackageInRepository_TaskStartMethodCalled() + { + CreateViewModel(); + viewModel.AddOneFakePackage(); + + viewModel.ReadPackages(); + + Assert.IsTrue(taskFactory.FirstFakeTaskCreated.IsStartCalled); + } + + [Test] + public void IsReadingPackages_ReadPackagesNotCalled_ReturnsFalse() + { + CreateViewModel(); + + Assert.IsFalse(viewModel.IsReadingPackages); + } + + [Test] + public void IsReadingPackages_ReadPackagesCalled_ReturnsTrue() + { + CreateViewModel(); + viewModel.ReadPackages(); + + Assert.IsTrue(viewModel.IsReadingPackages); + } + + [Test] + public void ReadPackages_OnePackageInRepositoryWhenBackgroundTaskExecuted_ReadsOnePackage() + { + CreateViewModel(); + viewModel.AddOneFakePackage(); + + viewModel.ReadPackages(); + + PackagesForSelectedPageResult result = taskFactory.FirstFakeTaskCreated.ExecuteTaskButNotContinueWith(); + + CollectionAssert.AreEqual(viewModel.FakePackages, result.Packages); + } + + [Test] + public void ReadPackages_OnePackageInRepositoryWhenFirstPartOfBackgroundTaskExecuted_PackageCountReadInBackgroundTask() + { + CreateViewModel(); + viewModel.AddOneFakePackage(); + + viewModel.ReadPackages(); + + PackagesForSelectedPageResult result = taskFactory.FirstFakeTaskCreated.ExecuteTaskButNotContinueWith(); + + Assert.AreEqual(1, result.TotalPackagesOnPage); + } + + [Test] + public void ReadPackages_OnePackageInRepositoryWhenBackgroundTaskExecutedAndResultsReturned_PackagesUpdatedInViewModel() + { + CreateViewModel(); + viewModel.AddOneFakePackage(); + + viewModel.ReadPackages(); + + CompleteReadPackagesTask(); + + PackageCollectionAssert.AreEqual(viewModel.FakePackages, viewModel.PackageViewModels); + } + + [Test] + public void IsReadingPackages_OnePackageInRepositoryWhenBackgroundTaskExecutedAndResultsReturned_SetToFalseAfterPackagesRead() + { + CreateViewModel(); + viewModel.AddOneFakePackage(); + + viewModel.ReadPackages(); + + CompleteReadPackagesTask(); + + Assert.IsFalse(viewModel.IsReadingPackages); + } + + [Test] + public void IsReadingPackages_OnePackageInRepositoryWhenBackgroundTaskExecutedAndResultsReturned_NotifyPropertyChangedFiredAfterIsReadingPackagesSetToFalse() + { + CreateViewModel(); + viewModel.AddOneFakePackage(); + + viewModel.ReadPackages(); + + bool readingPackages = true; + viewModel.PropertyChanged += (sender, e) => readingPackages = viewModel.IsReadingPackages; + CompleteReadPackagesTask(); + + Assert.IsFalse(readingPackages); + } + + [Test] + public void ReadPackages_SixPackagesInRepositoryAndPageSizeIsTwoWhenFirstPartOfBackgroundTaskExecuted_PackageCountReadInBackgroundTask() + { + CreateViewModel(); + viewModel.PageSize = 2; + viewModel.AddSixFakePackages(); + + viewModel.ReadPackages(); + + PackagesForSelectedPageResult result = taskFactory.FirstFakeTaskCreated.ExecuteTaskButNotContinueWith(); + + Assert.AreEqual(6, result.TotalPackages); + } + + [Test] + public void ReadPackages_SixPackagesInRepositoryAndPageSizeIsTwoWhenFirstPartOfBackgroundTaskExecuted_PageSizeNotChangedDuringBackgroundTaskExecution() + { + CreateViewModel(); + viewModel.PageSize = 2; + viewModel.AddSixFakePackages(); + + viewModel.ReadPackages(); + + PackagesForSelectedPageResult result = taskFactory.FirstFakeTaskCreated.ExecuteTaskButNotContinueWith(); + + Assert.IsFalse(viewModel.IsPaged); + } + + [Test] + public void ReadPackages_SixPackagesInRepositoryAndPageSizeIsTwoWhenBackgroundTaskExecutedAndResultsReturned_ResultsArePaged() + { + CreateViewModel(); + viewModel.PageSize = 2; + viewModel.AddSixFakePackages(); + + viewModel.ReadPackages(); + + CompleteReadPackagesTask(); + + Assert.IsTrue(viewModel.IsPaged); + } + + [Test] + public void ReadPackages_CalledSecondTimeBeforeFirstReadPackagesTaskCompletes_FirstReadPackagesTaskIsCancelled() + { + CreateViewModel(); + viewModel.AddOneFakePackage(); + + viewModel.ReadPackages(); + viewModel.ReadPackages(); + + Assert.IsTrue(taskFactory.FirstFakeTaskCreated.IsCancelCalled); + } + + [Test] + public void ReadPackages_FirstReadPackagesTaskCompletesAfterBeingCancelled_PackagesNotUpdated() + { + CreateViewModel(); + viewModel.AddOneFakePackage(); + + viewModel.ReadPackages(); + taskFactory.FirstFakeTaskCreated.IsCancelled = true; + viewModel.ReadPackages(); + taskFactory.FirstFakeTaskCreated.ExecuteTaskCompletely(); + + Assert.AreEqual(0, viewModel.PackageViewModels.Count); + } + + [Test] + public void SelectedPage_ChangedTwoPageTwo_IsReadingPackagesReturnsTrue() + { + CreateViewModel(); + viewModel.AddSixFakePackages(); + viewModel.ReadPackages(); + CompleteReadPackagesTask(); + ClearReadPackagesTasks(); + + viewModel.SelectedPageNumber = 2; + + Assert.IsTrue(viewModel.IsReadingPackages); + } + + [Test] + public void ReadPackages_SixPackagesDisplayedWhenReadPackagesCalledAgain_DisplayedPackagesAreRemoved() + { + CreateViewModel(); + viewModel.AddSixFakePackages(); + viewModel.ReadPackages(); + CompleteReadPackagesTask(); + + viewModel.ReadPackages(); + + Assert.AreEqual(0, viewModel.PackageViewModels.Count); + } + + [Test] + public void SelectedPage_ChangedTwoPageTwo_DisplayedPackagesAreRemoved() + { + CreateViewModel(); + viewModel.AddSixFakePackages(); + viewModel.ReadPackages(); + CompleteReadPackagesTask(); + ClearReadPackagesTasks(); + + viewModel.SelectedPageNumber = 2; + + Assert.AreEqual(0, viewModel.PackageViewModels.Count); + } + + [Test] + public void HasError_BackgroundTaskHasExceptionWhenItFinishes_ReturnsTrue() + { + CreateViewModel(); + viewModel.ReadPackages(); + taskFactory.FirstFakeTaskCreated.IsFaulted = true; + CompleteReadPackagesTask(); + + Assert.IsTrue(viewModel.HasError); + } + + [Test] + public void HasError_ByDefault_ReturnsFalse() + { + CreateViewModel(); + + Assert.IsFalse(viewModel.HasError); + } + + [Test] + public void IsReadingPackages_BackgroundTaskHasExceptionWhenItFinishes_ReturnsFalse() + { + CreateViewModel(); + viewModel.ReadPackages(); + taskFactory.FirstFakeTaskCreated.IsFaulted = true; + CompleteReadPackagesTask(); + + Assert.IsFalse(viewModel.IsReadingPackages); + } + + [Test] + public void PropertyChanged_BackgroundTaskHasExceptionWhenItFinishes_PropertyChangedEventFiredWhenTaskCompletes() + { + CreateViewModel(); + viewModel.ReadPackages(); + taskFactory.FirstFakeTaskCreated.IsFaulted = true; + taskFactory.FirstFakeTaskCreated.ExecuteTaskButNotContinueWith(); + + string propertyName = "Nothing"; + viewModel.PropertyChanged += (sender, e) => propertyName = e.PropertyName; + taskFactory.FirstFakeTaskCreated.ExecuteContinueWith(); + + Assert.IsNull(propertyName); + } + + [Test] + public void ReadPackages_BackgroundTaskHasExceptionWhenItFinishes_PackagesNotUpdated() + { + CreateViewModel(); + viewModel.AddSixFakePackages(); + viewModel.ReadPackages(); + taskFactory.FirstFakeTaskCreated.Result = new PackagesForSelectedPageResult(viewModel.FakePackages, 6); + taskFactory.FirstFakeTaskCreated.IsFaulted = true; + CompleteReadPackagesTask(); + + Assert.AreEqual(0, viewModel.PackageViewModels.Count); + } + + [Test] + public void ErrorMessage_BackgroundTaskHasExceptionWhenItFinishes_ErrorMessageTakenFromException() + { + CreateViewModel(); + viewModel.AddSixFakePackages(); + viewModel.ReadPackages(); + AggregateException ex = new AggregateException("Test"); + taskFactory.FirstFakeTaskCreated.Exception = ex; + taskFactory.FirstFakeTaskCreated.IsFaulted = true; + CompleteReadPackagesTask(); + + Assert.AreEqual("Test", viewModel.ErrorMessage); + } + + [Test] + public void Constructor_ActiveProjectManagerThrowsException_HasErrorReturnsTrue() + { + CreatePackageManagementService(); + packageManagementService.ActiveProjectManagerExeptionToThrow = new Exception(); + CreateViewModel(packageManagementService); + + Assert.IsTrue(viewModel.HasError); + } } }