From 872df67ffd9d0ebf42bbc3a49b46811881ffb7d6 Mon Sep 17 00:00:00 2001 From: mgroves Date: Tue, 15 Mar 2011 22:58:47 -0400 Subject: [PATCH] hammered out race conditions in Portfolio Presenter tests finally, also renamed the CSV folder to reflect the new CSV library I'm using --- .../Csv/CachedCsvReader.CsvBindingList.cs | 0 .../CachedCsvReader.CsvPropertyDescriptor.cs | 0 .../Csv/CachedCsvReader.CsvRecordComparer.cs | 0 .../Csv/CachedCsvReader.cs | 0 .../Csv/CsvReader.DataReaderValidations.cs | 0 .../Csv/CsvReader.RecordEnumerator.cs | 0 .../Csv/CsvReader.cs | 0 .../Csv/Events/ParseErrorEventArgs.cs | 0 .../Csv/Exceptions/MalformedCsvException.cs | 0 .../Exceptions/MissingFieldCsvException.cs | 0 .../Csv/MissingFieldAction.cs | 0 .../Csv/ParseErrorAction.cs | 0 .../Resources/ExceptionMessage.Designer.cs | 0 .../Csv/Resources/ExceptionMessage.resx | 0 .../Csv/ValueTrimmingOptions.cs | 0 ...noDroid.LumenWorks.Framework.IO.Csv.csproj | 0 .../Properties/AssemblyInfo.cs | 0 .../README.txt | 0 .../MonoStockPortfolio.Core.csproj | 2 +- .../MonoStockPortfolio.Tests.csproj | 7 ++-- .../Presenters/PortfolioPresenterTests.cs | 40 ++++++++++++++++--- MonoStockPortfolio.sln | 2 +- .../PortfolioScreen/PortfolioPresenter.cs | 1 - .../Framework/OnWorkerThreadAttribute.cs | 20 +++++++++- 24 files changed, 59 insertions(+), 13 deletions(-) rename {MonoDroid.FileHelpers => MonoDroid.LumenWorks.Framework.IO.Csv}/Csv/CachedCsvReader.CsvBindingList.cs (100%) rename {MonoDroid.FileHelpers => MonoDroid.LumenWorks.Framework.IO.Csv}/Csv/CachedCsvReader.CsvPropertyDescriptor.cs (100%) rename {MonoDroid.FileHelpers => MonoDroid.LumenWorks.Framework.IO.Csv}/Csv/CachedCsvReader.CsvRecordComparer.cs (100%) rename {MonoDroid.FileHelpers => MonoDroid.LumenWorks.Framework.IO.Csv}/Csv/CachedCsvReader.cs (100%) rename {MonoDroid.FileHelpers => MonoDroid.LumenWorks.Framework.IO.Csv}/Csv/CsvReader.DataReaderValidations.cs (100%) rename {MonoDroid.FileHelpers => MonoDroid.LumenWorks.Framework.IO.Csv}/Csv/CsvReader.RecordEnumerator.cs (100%) rename {MonoDroid.FileHelpers => MonoDroid.LumenWorks.Framework.IO.Csv}/Csv/CsvReader.cs (100%) rename {MonoDroid.FileHelpers => MonoDroid.LumenWorks.Framework.IO.Csv}/Csv/Events/ParseErrorEventArgs.cs (100%) rename {MonoDroid.FileHelpers => MonoDroid.LumenWorks.Framework.IO.Csv}/Csv/Exceptions/MalformedCsvException.cs (100%) rename {MonoDroid.FileHelpers => MonoDroid.LumenWorks.Framework.IO.Csv}/Csv/Exceptions/MissingFieldCsvException.cs (100%) rename {MonoDroid.FileHelpers => MonoDroid.LumenWorks.Framework.IO.Csv}/Csv/MissingFieldAction.cs (100%) rename {MonoDroid.FileHelpers => MonoDroid.LumenWorks.Framework.IO.Csv}/Csv/ParseErrorAction.cs (100%) rename {MonoDroid.FileHelpers => MonoDroid.LumenWorks.Framework.IO.Csv}/Csv/Resources/ExceptionMessage.Designer.cs (100%) rename {MonoDroid.FileHelpers => MonoDroid.LumenWorks.Framework.IO.Csv}/Csv/Resources/ExceptionMessage.resx (100%) rename {MonoDroid.FileHelpers => MonoDroid.LumenWorks.Framework.IO.Csv}/Csv/ValueTrimmingOptions.cs (100%) rename {MonoDroid.FileHelpers => MonoDroid.LumenWorks.Framework.IO.Csv}/MonoDroid.LumenWorks.Framework.IO.Csv.csproj (100%) rename {MonoDroid.FileHelpers => MonoDroid.LumenWorks.Framework.IO.Csv}/Properties/AssemblyInfo.cs (100%) rename {MonoDroid.FileHelpers => MonoDroid.LumenWorks.Framework.IO.Csv}/README.txt (100%) diff --git a/MonoDroid.FileHelpers/Csv/CachedCsvReader.CsvBindingList.cs b/MonoDroid.LumenWorks.Framework.IO.Csv/Csv/CachedCsvReader.CsvBindingList.cs similarity index 100% rename from MonoDroid.FileHelpers/Csv/CachedCsvReader.CsvBindingList.cs rename to MonoDroid.LumenWorks.Framework.IO.Csv/Csv/CachedCsvReader.CsvBindingList.cs diff --git a/MonoDroid.FileHelpers/Csv/CachedCsvReader.CsvPropertyDescriptor.cs b/MonoDroid.LumenWorks.Framework.IO.Csv/Csv/CachedCsvReader.CsvPropertyDescriptor.cs similarity index 100% rename from MonoDroid.FileHelpers/Csv/CachedCsvReader.CsvPropertyDescriptor.cs rename to MonoDroid.LumenWorks.Framework.IO.Csv/Csv/CachedCsvReader.CsvPropertyDescriptor.cs diff --git a/MonoDroid.FileHelpers/Csv/CachedCsvReader.CsvRecordComparer.cs b/MonoDroid.LumenWorks.Framework.IO.Csv/Csv/CachedCsvReader.CsvRecordComparer.cs similarity index 100% rename from MonoDroid.FileHelpers/Csv/CachedCsvReader.CsvRecordComparer.cs rename to MonoDroid.LumenWorks.Framework.IO.Csv/Csv/CachedCsvReader.CsvRecordComparer.cs diff --git a/MonoDroid.FileHelpers/Csv/CachedCsvReader.cs b/MonoDroid.LumenWorks.Framework.IO.Csv/Csv/CachedCsvReader.cs similarity index 100% rename from MonoDroid.FileHelpers/Csv/CachedCsvReader.cs rename to MonoDroid.LumenWorks.Framework.IO.Csv/Csv/CachedCsvReader.cs diff --git a/MonoDroid.FileHelpers/Csv/CsvReader.DataReaderValidations.cs b/MonoDroid.LumenWorks.Framework.IO.Csv/Csv/CsvReader.DataReaderValidations.cs similarity index 100% rename from MonoDroid.FileHelpers/Csv/CsvReader.DataReaderValidations.cs rename to MonoDroid.LumenWorks.Framework.IO.Csv/Csv/CsvReader.DataReaderValidations.cs diff --git a/MonoDroid.FileHelpers/Csv/CsvReader.RecordEnumerator.cs b/MonoDroid.LumenWorks.Framework.IO.Csv/Csv/CsvReader.RecordEnumerator.cs similarity index 100% rename from MonoDroid.FileHelpers/Csv/CsvReader.RecordEnumerator.cs rename to MonoDroid.LumenWorks.Framework.IO.Csv/Csv/CsvReader.RecordEnumerator.cs diff --git a/MonoDroid.FileHelpers/Csv/CsvReader.cs b/MonoDroid.LumenWorks.Framework.IO.Csv/Csv/CsvReader.cs similarity index 100% rename from MonoDroid.FileHelpers/Csv/CsvReader.cs rename to MonoDroid.LumenWorks.Framework.IO.Csv/Csv/CsvReader.cs diff --git a/MonoDroid.FileHelpers/Csv/Events/ParseErrorEventArgs.cs b/MonoDroid.LumenWorks.Framework.IO.Csv/Csv/Events/ParseErrorEventArgs.cs similarity index 100% rename from MonoDroid.FileHelpers/Csv/Events/ParseErrorEventArgs.cs rename to MonoDroid.LumenWorks.Framework.IO.Csv/Csv/Events/ParseErrorEventArgs.cs diff --git a/MonoDroid.FileHelpers/Csv/Exceptions/MalformedCsvException.cs b/MonoDroid.LumenWorks.Framework.IO.Csv/Csv/Exceptions/MalformedCsvException.cs similarity index 100% rename from MonoDroid.FileHelpers/Csv/Exceptions/MalformedCsvException.cs rename to MonoDroid.LumenWorks.Framework.IO.Csv/Csv/Exceptions/MalformedCsvException.cs diff --git a/MonoDroid.FileHelpers/Csv/Exceptions/MissingFieldCsvException.cs b/MonoDroid.LumenWorks.Framework.IO.Csv/Csv/Exceptions/MissingFieldCsvException.cs similarity index 100% rename from MonoDroid.FileHelpers/Csv/Exceptions/MissingFieldCsvException.cs rename to MonoDroid.LumenWorks.Framework.IO.Csv/Csv/Exceptions/MissingFieldCsvException.cs diff --git a/MonoDroid.FileHelpers/Csv/MissingFieldAction.cs b/MonoDroid.LumenWorks.Framework.IO.Csv/Csv/MissingFieldAction.cs similarity index 100% rename from MonoDroid.FileHelpers/Csv/MissingFieldAction.cs rename to MonoDroid.LumenWorks.Framework.IO.Csv/Csv/MissingFieldAction.cs diff --git a/MonoDroid.FileHelpers/Csv/ParseErrorAction.cs b/MonoDroid.LumenWorks.Framework.IO.Csv/Csv/ParseErrorAction.cs similarity index 100% rename from MonoDroid.FileHelpers/Csv/ParseErrorAction.cs rename to MonoDroid.LumenWorks.Framework.IO.Csv/Csv/ParseErrorAction.cs diff --git a/MonoDroid.FileHelpers/Csv/Resources/ExceptionMessage.Designer.cs b/MonoDroid.LumenWorks.Framework.IO.Csv/Csv/Resources/ExceptionMessage.Designer.cs similarity index 100% rename from MonoDroid.FileHelpers/Csv/Resources/ExceptionMessage.Designer.cs rename to MonoDroid.LumenWorks.Framework.IO.Csv/Csv/Resources/ExceptionMessage.Designer.cs diff --git a/MonoDroid.FileHelpers/Csv/Resources/ExceptionMessage.resx b/MonoDroid.LumenWorks.Framework.IO.Csv/Csv/Resources/ExceptionMessage.resx similarity index 100% rename from MonoDroid.FileHelpers/Csv/Resources/ExceptionMessage.resx rename to MonoDroid.LumenWorks.Framework.IO.Csv/Csv/Resources/ExceptionMessage.resx diff --git a/MonoDroid.FileHelpers/Csv/ValueTrimmingOptions.cs b/MonoDroid.LumenWorks.Framework.IO.Csv/Csv/ValueTrimmingOptions.cs similarity index 100% rename from MonoDroid.FileHelpers/Csv/ValueTrimmingOptions.cs rename to MonoDroid.LumenWorks.Framework.IO.Csv/Csv/ValueTrimmingOptions.cs diff --git a/MonoDroid.FileHelpers/MonoDroid.LumenWorks.Framework.IO.Csv.csproj b/MonoDroid.LumenWorks.Framework.IO.Csv/MonoDroid.LumenWorks.Framework.IO.Csv.csproj similarity index 100% rename from MonoDroid.FileHelpers/MonoDroid.LumenWorks.Framework.IO.Csv.csproj rename to MonoDroid.LumenWorks.Framework.IO.Csv/MonoDroid.LumenWorks.Framework.IO.Csv.csproj diff --git a/MonoDroid.FileHelpers/Properties/AssemblyInfo.cs b/MonoDroid.LumenWorks.Framework.IO.Csv/Properties/AssemblyInfo.cs similarity index 100% rename from MonoDroid.FileHelpers/Properties/AssemblyInfo.cs rename to MonoDroid.LumenWorks.Framework.IO.Csv/Properties/AssemblyInfo.cs diff --git a/MonoDroid.FileHelpers/README.txt b/MonoDroid.LumenWorks.Framework.IO.Csv/README.txt similarity index 100% rename from MonoDroid.FileHelpers/README.txt rename to MonoDroid.LumenWorks.Framework.IO.Csv/README.txt diff --git a/MonoStockPortfolio.Core/MonoStockPortfolio.Core.csproj b/MonoStockPortfolio.Core/MonoStockPortfolio.Core.csproj index b8cb2ec..35d8453 100644 --- a/MonoStockPortfolio.Core/MonoStockPortfolio.Core.csproj +++ b/MonoStockPortfolio.Core/MonoStockPortfolio.Core.csproj @@ -60,7 +60,7 @@ - + {1AAA2739-D853-41B0-866B-B55B373616E1} MonoDroid.LumenWorks.Framework.IO.Csv diff --git a/MonoStockPortfolio.Tests/MonoStockPortfolio.Tests.csproj b/MonoStockPortfolio.Tests/MonoStockPortfolio.Tests.csproj index 08490c7..262eb7c 100644 --- a/MonoStockPortfolio.Tests/MonoStockPortfolio.Tests.csproj +++ b/MonoStockPortfolio.Tests/MonoStockPortfolio.Tests.csproj @@ -40,6 +40,10 @@ True + + False + ..\libs\PostSharp.SL.dll + True @@ -49,9 +53,6 @@ True - - True - ..\libs\Telerik.JustMock.Silverlight.dll diff --git a/MonoStockPortfolio.Tests/Presenters/PortfolioPresenterTests.cs b/MonoStockPortfolio.Tests/Presenters/PortfolioPresenterTests.cs index 955340d..47268b7 100644 --- a/MonoStockPortfolio.Tests/Presenters/PortfolioPresenterTests.cs +++ b/MonoStockPortfolio.Tests/Presenters/PortfolioPresenterTests.cs @@ -1,18 +1,19 @@ -using System; using System.Collections.Generic; +using System.Threading; using Machine.Specifications; using MonoStockPortfolio.Activites.PortfolioScreen; using MonoStockPortfolio.Core.Config; using MonoStockPortfolio.Core.PortfolioRepositories; using MonoStockPortfolio.Core.Services; using MonoStockPortfolio.Entities; +using MonoStockPortfolio.Framework; using Telerik.JustMock; namespace MonoStockPortfolio.Tests.Presenters { public class Given_an_initialized_Portfolio_Presenter { - protected static PortfolioPresenter _presenter; + protected static IPortfolioPresenter _presenter; protected static IPortfolioRepository _mockPortfolioRepository; protected static IPortfolioService _mockPortfolioService; protected static IConfigRepository _mockConfigRepository; @@ -20,6 +21,8 @@ namespace MonoStockPortfolio.Tests.Presenters Establish context = () => { + OnWorkerThreadAttribute.ThreadingService = new DoNotThreadService(); + _mockPortfolioRepository = Mock.Create(); Mock.Arrange(() => _mockPortfolioRepository.GetPortfolioById(999)).Returns(new Portfolio(123) { Name = "Test Portfolio" }); @@ -29,22 +32,32 @@ namespace MonoStockPortfolio.Tests.Presenters _mockConfigRepository = Mock.Create(); _mockView = Mock.Create(); - Mock.Arrange(() => _mockView.StartEditPosition(Arg.AnyInt, Arg.AnyLong)).DoNothing(); // i don't know why this has to be here to pass the "edit" context option test _presenter = new PortfolioPresenter(_mockPortfolioRepository, _mockPortfolioService, _mockConfigRepository); + _presenter.Initialize(_mockView, 999); }; } + internal class DoNotThreadService : IThreadingService + { + public void QueueUserWorkItem(WaitCallback func) + { + func.Invoke(null); + } + } + public class When_done_initializing_a_Portfolio_Presenter : Given_an_initialized_Portfolio_Presenter { - It should_get_the_positions_list_and_refresh_the_view = () => + It should_show_the_progress_bar_with_a_nice_message = () => + Mock.Assert(() => _mockView.ShowProgressDialog("Loading...Please wait..."), Occurs.Exactly(1)); + It should_use_the_service_to_get_the_positions = () => Mock.Assert(() => _mockPortfolioService.GetDetailedItems(999, Arg.IsAny>()), Occurs.Exactly(1)); - + It should_hide_the_progress_bar_message = () => + Mock.Assert(() => _mockView.HideProgressDialog(), Occurs.Exactly(1)); It should_refresh_the_view = () => Mock.Assert(() => _mockView.RefreshList(Arg.IsAny>(), Arg.IsAny>()), Occurs.Exactly(1)); - It should_get_the_portfolio_name_from_the_repository_and_set_the_title_with_that = () => Mock.Assert(() => _mockView.SetTitle("Portfolio: Test Portfolio"), Occurs.Exactly(1)); } @@ -75,4 +88,19 @@ namespace MonoStockPortfolio.Tests.Presenters It should_use_the_repo_to_delete_the_position = () => Mock.Assert(() => _mockPortfolioRepository.DeletePositionById(123), Occurs.Exactly(1)); } + + public class When_the_user_wants_to_refresh_the_positions : Given_an_initialized_Portfolio_Presenter + { + Because of = () => + _presenter.RefreshPositions(); + + It should_show_the_progress_bar_with_a_nice_message_again = () => + Mock.Assert(() => _mockView.ShowProgressDialog("Loading...Please wait..."), Occurs.Exactly(2)); + It should_use_the_service_to_get_the_positions_again = () => + Mock.Assert(() => _mockPortfolioService.GetDetailedItems(999, Arg.IsAny>()), Occurs.Exactly(2)); + It should_hide_the_progress_bar_message_again = () => + Mock.Assert(() => _mockView.HideProgressDialog(), Occurs.Exactly(2)); + It should_refresh_the_view_again = () => + Mock.Assert(() => _mockView.RefreshList(Arg.IsAny>(), Arg.IsAny>()), Occurs.Exactly(2)); + } } \ No newline at end of file diff --git a/MonoStockPortfolio.sln b/MonoStockPortfolio.sln index 39c116c..e312ac3 100644 --- a/MonoStockPortfolio.sln +++ b/MonoStockPortfolio.sln @@ -14,7 +14,7 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MonoStockPortfolio.Entities EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MonoStockPortfolio.Tests", "MonoStockPortfolio.Tests\MonoStockPortfolio.Tests.csproj", "{C2797FAB-AFAB-49F6-9131-FC9BF03CAB9D}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MonoDroid.LumenWorks.Framework.IO.Csv", "MonoDroid.FileHelpers\MonoDroid.LumenWorks.Framework.IO.Csv.csproj", "{1AAA2739-D853-41B0-866B-B55B373616E1}" +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MonoDroid.LumenWorks.Framework.IO.Csv", "MonoDroid.LumenWorks.Framework.IO.Csv\MonoDroid.LumenWorks.Framework.IO.Csv.csproj", "{1AAA2739-D853-41B0-866B-B55B373616E1}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution diff --git a/MonoStockPortfolio/Activites/PortfolioScreen/PortfolioPresenter.cs b/MonoStockPortfolio/Activites/PortfolioScreen/PortfolioPresenter.cs index 6aa6e9d..5d13213 100644 --- a/MonoStockPortfolio/Activites/PortfolioScreen/PortfolioPresenter.cs +++ b/MonoStockPortfolio/Activites/PortfolioScreen/PortfolioPresenter.cs @@ -1,6 +1,5 @@ using System.Collections.Generic; using System.Linq; -using Android.Runtime; using MonoStockPortfolio.Core.Config; using MonoStockPortfolio.Core.PortfolioRepositories; using MonoStockPortfolio.Core.Services; diff --git a/MonoStockPortfolio/Framework/OnWorkerThreadAttribute.cs b/MonoStockPortfolio/Framework/OnWorkerThreadAttribute.cs index 11547e9..1f4cfff 100644 --- a/MonoStockPortfolio/Framework/OnWorkerThreadAttribute.cs +++ b/MonoStockPortfolio/Framework/OnWorkerThreadAttribute.cs @@ -5,9 +5,27 @@ namespace MonoStockPortfolio.Framework { public class OnWorkerThreadAttribute : MethodInterceptionAspect { + public static IThreadingService ThreadingService; + public override void OnInvoke(MethodInterceptionArgs args) { - ThreadPool.QueueUserWorkItem(d => args.Proceed()); + if(ThreadingService == null) ThreadingService = new ThreadingService(); + ThreadingService.QueueUserWorkItem(d => args.Invoke(args.Arguments)); + } + } + + // this is kinda fail, but it helps with testing to inject in a "non threaded" service + // and I suppose it might make refactoring easier maybe...? just go with it + public interface IThreadingService + { + void QueueUserWorkItem(WaitCallback func); + } + + public class ThreadingService : IThreadingService + { + public void QueueUserWorkItem(WaitCallback waitCallback) + { + ThreadPool.QueueUserWorkItem(waitCallback); } } } \ No newline at end of file