refactored config view to MVP, added tests

This commit is contained in:
mgroves 2011-03-22 00:18:30 -04:00
parent efdf271f1a
commit f7edde8dae
10 changed files with 219 additions and 48 deletions

View file

@ -63,6 +63,7 @@
</ItemGroup>
<ItemGroup>
<Compile Include="Framework\ValidationTests.cs" />
<Compile Include="Presenters\Given_an_initialized_Config_Presenter.cs" />
<Compile Include="Presenters\EditPortfolioTests.cs" />
<Compile Include="Presenters\EditPositionTests.cs" />
<Compile Include="Presenters\MainPresenterTests.cs" />

View file

@ -0,0 +1,94 @@
using System.Collections.Generic;
using System.Linq;
using Machine.Specifications;
using MonoStockPortfolio.Activites.ConfigScreen;
using MonoStockPortfolio.Core.Config;
using MonoStockPortfolio.Entities;
using Telerik.JustMock;
using MonoStockPortfolio.Core;
namespace MonoStockPortfolio.Tests.Presenters
{
public class Given_a_Config_Presenter
{
protected static ConfigPresenter _presenter;
protected static IConfigRepository _configRepository;
protected static IConfigView _configView;
Establish context = () =>
{
_configView = Mock.Create<IConfigView>();
_configRepository = Mock.Create<IConfigRepository>();
Mock.Arrange(() => _configRepository.GetStockItems()).Returns(new List<StockDataItem>
{
StockDataItem.GainLoss,
StockDataItem.Change
});
_presenter = new ConfigPresenter(_configRepository);
};
}
public class When_initialize_the_config_presenter : Given_a_Config_Presenter
{
static List<StockDataItem> _allStockDataItems;
Establish context = () =>
{
_allStockDataItems = StockDataItem.Volume.GetValues<StockDataItem>().ToList();
};
Because of = () =>
{
_presenter.Initialize(_configView);
};
It should_send_two_checked_items = () =>
Mock.Assert(() =>
_configView.PrepopulateConfiguration(
Arg.IsAny<IList<StockDataItem>>(),
Arg.Matches<IEnumerable<StockDataItem>>(i => i.Count() == 2)),
Occurs.Exactly(1));
It should_send_GainLoss_as_a_checked_item = () =>
Mock.Assert(() =>
_configView.PrepopulateConfiguration(
Arg.IsAny<IList<StockDataItem>>(),
Arg.Matches<IEnumerable<StockDataItem>>(i => i.Any(p => p == StockDataItem.GainLoss))),
Occurs.Exactly(1));
It should_send_Change_as_a_checked_item = () =>
Mock.Assert(() =>
_configView.PrepopulateConfiguration(
Arg.IsAny<IList<StockDataItem>>(),
Arg.Matches<IEnumerable<StockDataItem>>(i => i.Any(p => p == StockDataItem.Change))),
Occurs.Exactly(1));
It should_send_an_enumerated_list_of_all_stock_items = () =>
Mock.Assert(() =>
_configView.PrepopulateConfiguration(
Arg.Matches<IList<StockDataItem>>(i => i.Count == _allStockDataItems.Count),
Arg.IsAny<IEnumerable<StockDataItem>>()),
Occurs.Exactly(1));
}
public class When_the_user_wants_to_save_configuration : Given_a_Config_Presenter
{
Establish context = () =>
{
_presenter.Initialize(_configView);
};
Because of = () =>
{
_presenter.SaveConfig(new List<StockDataItem> {StockDataItem.Ticker, StockDataItem.Time});
};
It should_use_the_repo_to_update_to_2_stock_items = () =>
Mock.Assert(() => _configRepository.UpdateStockItems(Arg.Matches<List<StockDataItem>>(i => i.Count == 2)));
It should_use_the_repo_to_update_stock_items_with_Time = () =>
Mock.Assert(() => _configRepository.UpdateStockItems(Arg.Matches<List<StockDataItem>>(i => i.Any(s => s == StockDataItem.Time))));
It should_use_the_repo_to_update_stock_items_with_Ticker = () =>
Mock.Assert(() => _configRepository.UpdateStockItems(Arg.Matches<List<StockDataItem>>(i => i.Any(s => s == StockDataItem.Ticker))));
}
}

View file

@ -4,61 +4,19 @@ using Android.App;
using Android.Content;
using Android.OS;
using Android.Widget;
using MonoStockPortfolio.Core.Config;
using MonoStockPortfolio.Entities;
using MonoStockPortfolio.Framework;
using MonoStockPortfolio.Core;
namespace MonoStockPortfolio.Activites
namespace MonoStockPortfolio.Activites.ConfigScreen
{
[Activity(Label = "Config", Name = "monostockportfolio.activites.ConfigActivity")]
public class ConfigActivity : Activity
public class ConfigActivity : Activity, IConfigView
{
[IoC] private IConfigRepository _repo;
[LazyView(Resource.Id.configList)] private ListView ConfigList;
[LazyView(Resource.Id.btnSaveConfig)] private Button SaveConfigButton;
protected override void OnCreate(Bundle bundle)
{
base.OnCreate(bundle);
SetContentView(Resource.Layout.config);
var allitems = StockDataItem.Volume.GetValues<StockDataItem>().ToList();
var allitemsLabels = allitems.Select(i => i.GetStringValue()).ToList();
var checkeditems = _repo.GetStockItems();
var configAdapter = new ArrayAdapter<string>(this, Android.Resource.Layout.SimpleListItemMultipleChoice, allitemsLabels);
ConfigList.Adapter = configAdapter;
ConfigList.ChoiceMode = ChoiceMode.Multiple;
for(int i=0;i<ConfigList.Count;i++)
{
if (checkeditems.Contains(allitems[i]))
{
ConfigList.SetItemChecked(i, true);
}
}
SaveConfigButton.Click += SaveConfigButton_Click;
}
void SaveConfigButton_Click(object sender, System.EventArgs e)
{
var allitems = StockDataItem.Volume.GetValues<StockDataItem>().ToList();
var newConfig = new List<StockDataItem>();
for (int i = 0; i < ConfigList.Count; i++)
{
if(ConfigList.IsItemChecked(i))
{
newConfig.Add(allitems[i]);
}
}
_repo.UpdateStockItems(newConfig);
this.LongToast("Configuration updated!");
}
[IoC] IConfigPresenter _presenter;
public static Intent GotoIntent(Context context)
{
@ -66,5 +24,59 @@ namespace MonoStockPortfolio.Activites
intent.SetClassName(context, ManifestNames.GetName<ConfigActivity>());
return intent;
}
protected override void OnCreate(Bundle bundle)
{
base.OnCreate(bundle);
SetContentView(Resource.Layout.config);
_presenter.Initialize(this);
WireUpEvents();
}
void WireUpEvents()
{
SaveConfigButton.Click += SaveConfigButton_Click;
}
#region IConfigView members
public void PrepopulateConfiguration(IList<StockDataItem> allitems, IEnumerable<StockDataItem> checkeditems)
{
var allitemsLabels = allitems.Select(i => i.GetStringValue()).ToList();
var configAdapter = new ArrayAdapter<string>(this, Android.Resource.Layout.SimpleListItemMultipleChoice, allitemsLabels);
ConfigList.Adapter = configAdapter;
ConfigList.ChoiceMode = ChoiceMode.Multiple;
for (int i = 0; i < ConfigList.Count; i++)
{
if (checkeditems.Contains(allitems[i]))
{
ConfigList.SetItemChecked(i, true);
}
}
}
public void ShowToastMessage(string message)
{
this.LongToast(message);
}
#endregion
void SaveConfigButton_Click(object sender, System.EventArgs e)
{
var checkedItems = new List<StockDataItem>();
for(int i =0;i<ConfigList.Count;i++)
{
if (ConfigList.IsItemChecked(i))
{
checkedItems.Add((StockDataItem) i);
}
}
_presenter.SaveConfig(checkedItems);
}
}
}

View file

@ -0,0 +1,36 @@
using System.Collections.Generic;
using System.Linq;
using MonoStockPortfolio.Core.Config;
using MonoStockPortfolio.Entities;
using MonoStockPortfolio.Core;
namespace MonoStockPortfolio.Activites.ConfigScreen
{
public class ConfigPresenter : IConfigPresenter
{
private IConfigView _currentView;
private readonly IConfigRepository _configRepository;
public ConfigPresenter(IConfigRepository configRepository)
{
_configRepository = configRepository;
}
public void Initialize(IConfigView configView)
{
_currentView = configView;
var allitems = StockDataItem.Volume.GetValues<StockDataItem>().ToList();
var checkeditems = _configRepository.GetStockItems();
_currentView.PrepopulateConfiguration(allitems, checkeditems);
}
public void SaveConfig(List<StockDataItem> checkedItems)
{
_configRepository.UpdateStockItems(checkedItems);
_currentView.ShowToastMessage("Configuration updated!");
}
}
}

View file

@ -0,0 +1,11 @@
using System.Collections.Generic;
using MonoStockPortfolio.Entities;
namespace MonoStockPortfolio.Activites.ConfigScreen
{
public interface IConfigPresenter
{
void Initialize(IConfigView configView);
void SaveConfig(List<StockDataItem> checkedItems);
}
}

View file

@ -0,0 +1,11 @@
using System.Collections.Generic;
using MonoStockPortfolio.Entities;
namespace MonoStockPortfolio.Activites.ConfigScreen
{
public interface IConfigView
{
void PrepopulateConfiguration(IList<StockDataItem> allitems, IEnumerable<StockDataItem> checkeditems);
void ShowToastMessage(string message);
}
}

View file

@ -5,6 +5,7 @@ using Android.Content;
using Android.OS;
using Android.Views;
using Android.Widget;
using MonoStockPortfolio.Activites.ConfigScreen;
using MonoStockPortfolio.Activites.EditPortfolioScreen;
using MonoStockPortfolio.Activites.PortfolioScreen;
using MonoStockPortfolio.Framework;

View file

@ -1,4 +1,4 @@
namespace MonoStockPortfolio.Activites
namespace MonoStockPortfolio.Activites.PortfolioScreen
{
public class MenuOption
{

View file

@ -1,6 +1,7 @@
using System;
using Android.Content;
using Android.Util;
using MonoStockPortfolio.Activites.ConfigScreen;
using MonoStockPortfolio.Activites.EditPortfolioScreen;
using MonoStockPortfolio.Activites.EditPositionScreen;
using MonoStockPortfolio.Activites.MainScreen;
@ -30,6 +31,7 @@ namespace MonoStockPortfolio.Framework
IttyBittyIoC.Register<IPortfolioPresenter, PortfolioPresenter>();
IttyBittyIoC.Register<IEditPortfolioPresenter, EditPortfolioPresenter>();
IttyBittyIoC.Register<IEditPositionPresenter, EditPositionPresenter>();
IttyBittyIoC.Register<IConfigPresenter, ConfigPresenter>();
}
public static object Get(Type serviceType)

View file

@ -54,7 +54,10 @@
<Reference Include="System.Xml" />
</ItemGroup>
<ItemGroup>
<Compile Include="Activites\ConfigActivity.cs" />
<Compile Include="Activites\ConfigScreen\ConfigActivity.cs" />
<Compile Include="Activites\ConfigScreen\ConfigPresenter.cs" />
<Compile Include="Activites\ConfigScreen\IConfigPresenter.cs" />
<Compile Include="Activites\ConfigScreen\IConfigView.cs" />
<Compile Include="Activites\EditPortfolioScreen\EditPortfolioActivity.cs" />
<Compile Include="Activites\EditPortfolioScreen\EditPortfolioPresenter.cs" />
<Compile Include="Activites\EditPortfolioScreen\IEditPortfolioPresenter.cs" />
@ -67,7 +70,7 @@
<Compile Include="Activites\MainScreen\IMainPresenter.cs" />
<Compile Include="Activites\MainScreen\IMainView.cs" />
<Compile Include="Activites\MainScreen\MainPresenter.cs" />
<Compile Include="Activites\MenuOption.cs" />
<Compile Include="Activites\PortfolioScreen\MenuOption.cs" />
<Compile Include="Activites\PortfolioScreen\IPortfolioPresenter.cs" />
<Compile Include="Activites\PortfolioScreen\IPortfolioView.cs" />
<Compile Include="Activites\PortfolioScreen\PortfolioPresenter.cs" />