diff options
| author | mo <mo.khan@gmail.com> | 2018-11-04 15:22:16 -0700 |
|---|---|---|
| committer | mo <mo.khan@gmail.com> | 2018-11-04 15:22:16 -0700 |
| commit | 5ee1f55497a4e30322a56f133f897ecde1612967 (patch) | |
| tree | bf544e0879234c3623869627d8786776cb19b8e9 /src/Notepad/Presentation/Model | |
Diffstat (limited to 'src/Notepad/Presentation/Model')
23 files changed, 1006 insertions, 0 deletions
diff --git a/src/Notepad/Presentation/Model/Menu/File/Commands/ExitCommandSpecs.cs b/src/Notepad/Presentation/Model/Menu/File/Commands/ExitCommandSpecs.cs new file mode 100644 index 0000000..00855b6 --- /dev/null +++ b/src/Notepad/Presentation/Model/Menu/File/Commands/ExitCommandSpecs.cs @@ -0,0 +1,34 @@ +using MbUnit.Framework;
+using Notepad.Infrastructure.System;
+using Rhino.Mocks;
+
+namespace Notepad.Presentation.Model.Menu.File.Commands {
+ public class ExitCommandSpecs {}
+
+ [TestFixture]
+ public class when_executing_the_exit_command_specs_ {
+ private MockRepository mockery;
+ private IApplicationEnvironment application;
+
+ [SetUp]
+ public void SetUp() {
+ mockery = new MockRepository();
+ application = mockery.DynamicMock<IApplicationEnvironment>();
+ }
+
+ [Test]
+ public void should_ask_the_application_environment_to_shut_down() {
+ using (mockery.Record()) {
+ application.ShutDown();
+ }
+
+ using (mockery.Playback()) {
+ CreateSUT().Execute();
+ }
+ }
+
+ private IExitCommand CreateSUT() {
+ return new ExitCommand(application);
+ }
+ }
+}
\ No newline at end of file diff --git a/src/Notepad/Presentation/Model/Menu/File/Commands/IExitCommand.cs b/src/Notepad/Presentation/Model/Menu/File/Commands/IExitCommand.cs new file mode 100644 index 0000000..a78c32b --- /dev/null +++ b/src/Notepad/Presentation/Model/Menu/File/Commands/IExitCommand.cs @@ -0,0 +1,18 @@ +using Notepad.Infrastructure.Core;
+using Notepad.Infrastructure.System;
+
+namespace Notepad.Presentation.Model.Menu.File.Commands {
+ public interface IExitCommand : ICommand {}
+
+ public class ExitCommand : IExitCommand {
+ private readonly IApplicationEnvironment application;
+
+ public ExitCommand(IApplicationEnvironment application) {
+ this.application = application;
+ }
+
+ public void Execute() {
+ application.ShutDown();
+ }
+ }
+}
\ No newline at end of file diff --git a/src/Notepad/Presentation/Model/Menu/File/Commands/ISaveCommand.cs b/src/Notepad/Presentation/Model/Menu/File/Commands/ISaveCommand.cs new file mode 100644 index 0000000..ea7c396 --- /dev/null +++ b/src/Notepad/Presentation/Model/Menu/File/Commands/ISaveCommand.cs @@ -0,0 +1,27 @@ +using Notepad.Infrastructure.Core;
+using Notepad.Presentation.Core;
+using Notepad.Presentation.Presenters.Menu.File;
+using Notepad.Tasks;
+
+namespace Notepad.Presentation.Model.Menu.File.Commands {
+ public interface ISaveCommand : ICommand {}
+
+ public class SaveCommand : ISaveCommand {
+ private readonly IApplicationController controller;
+ private readonly IDocumentTasks tasks;
+
+ public SaveCommand(IApplicationController controller, IDocumentTasks tasks) {
+ this.controller = controller;
+ this.tasks = tasks;
+ }
+
+ public void Execute() {
+ if (!tasks.HasAPathToSaveToBeenSpecified()) {
+ controller.Run<ISaveAsPresenter>();
+ }
+ else {
+ tasks.SaveTheActiveDocument();
+ }
+ }
+ }
+}
\ No newline at end of file diff --git a/src/Notepad/Presentation/Model/Menu/File/Commands/SaveCommandSpecs.cs b/src/Notepad/Presentation/Model/Menu/File/Commands/SaveCommandSpecs.cs new file mode 100644 index 0000000..7e4d827 --- /dev/null +++ b/src/Notepad/Presentation/Model/Menu/File/Commands/SaveCommandSpecs.cs @@ -0,0 +1,95 @@ +using MbUnit.Framework;
+using Notepad.Presentation.Core;
+using Notepad.Presentation.Presenters.Menu.File;
+using Notepad.Tasks;
+using Rhino.Mocks;
+
+namespace Notepad.Presentation.Model.Menu.File.Commands {
+ public class SaveCommandSpecs {}
+
+ [TestFixture]
+ public class when_executing_the_save_command_and_a_file_path_to_save_to_has_not_been_specified_ {
+ private MockRepository mockery;
+ private IApplicationController applicationController;
+ private IDocumentTasks tasks;
+
+ [SetUp]
+ public void SetUp() {
+ mockery = new MockRepository();
+ applicationController = mockery.DynamicMock<IApplicationController>();
+ tasks = mockery.DynamicMock<IDocumentTasks>();
+
+ SetupResult.For(tasks.HasAPathToSaveToBeenSpecified()).Return(false);
+ }
+
+ [Test]
+ public void should_run_the_save_as_presenter() {
+ using (mockery.Record()) {
+ applicationController.Run<ISaveAsPresenter>();
+ }
+
+ using (mockery.Playback()) {
+ CreateSUT().Execute();
+ }
+ }
+
+ [Test]
+ public void should_not_save_the_active_document() {
+ using (mockery.Record()) {
+ tasks.SaveTheActiveDocument();
+ LastCall.Repeat.Never();
+ }
+
+ using (mockery.Playback()) {
+ CreateSUT().Execute();
+ }
+ }
+
+ private ISaveCommand CreateSUT() {
+ return new SaveCommand(applicationController, tasks);
+ }
+ }
+
+ [TestFixture]
+ public class when_executing_the_save_command_and_a_path_to_save_to_has_already_been_specified_ {
+ private MockRepository mockery;
+ private IApplicationController applicationController;
+ private IDocumentTasks tasks;
+
+ [SetUp]
+ public void SetUp() {
+ mockery = new MockRepository();
+ applicationController = mockery.DynamicMock<IApplicationController>();
+ tasks = mockery.DynamicMock<IDocumentTasks>();
+
+ SetupResult.For(tasks.HasAPathToSaveToBeenSpecified()).Return(true);
+ }
+
+ [Test]
+ public void should_not_run_the_save_as_presenter() {
+ using (mockery.Record()) {
+ applicationController.Run<ISaveAsPresenter>();
+ LastCall.Repeat.Never();
+ }
+
+ using (mockery.Playback()) {
+ CreateSUT().Execute();
+ }
+ }
+
+ [Test]
+ public void should_save_the_active_document() {
+ using (mockery.Record()) {
+ tasks.SaveTheActiveDocument();
+ }
+
+ using (mockery.Playback()) {
+ CreateSUT().Execute();
+ }
+ }
+
+ private ISaveCommand CreateSUT() {
+ return new SaveCommand(applicationController, tasks);
+ }
+ }
+}
\ No newline at end of file diff --git a/src/Notepad/Presentation/Model/Menu/File/ExitMenuItem.cs b/src/Notepad/Presentation/Model/Menu/File/ExitMenuItem.cs new file mode 100644 index 0000000..c926dac --- /dev/null +++ b/src/Notepad/Presentation/Model/Menu/File/ExitMenuItem.cs @@ -0,0 +1,23 @@ +using Notepad.Presentation.Model.Menu.File.Commands;
+
+namespace Notepad.Presentation.Model.Menu.File {
+ public class ExitMenuItem : IMenuItem {
+ private readonly IExitCommand exitCommand;
+
+ public ExitMenuItem(IExitCommand exitCommand) {
+ this.exitCommand = exitCommand;
+ }
+
+ public string Name() {
+ return "E&xit";
+ }
+
+ public void Click() {
+ exitCommand.Execute();
+ }
+
+ public bool BelongsTo(ISubMenu menu) {
+ return menu.Name().Equals(MenuNames.File);
+ }
+ }
+}
\ No newline at end of file diff --git a/src/Notepad/Presentation/Model/Menu/File/ExitMenuItemSpecs.cs b/src/Notepad/Presentation/Model/Menu/File/ExitMenuItemSpecs.cs new file mode 100644 index 0000000..3220ae5 --- /dev/null +++ b/src/Notepad/Presentation/Model/Menu/File/ExitMenuItemSpecs.cs @@ -0,0 +1,72 @@ +using MbUnit.Framework;
+using Notepad.Presentation.Model.Menu.File.Commands;
+using Notepad.Test.Extensions;
+using Rhino.Mocks;
+
+namespace Notepad.Presentation.Model.Menu.File {
+ public class ExitMenuItemSpecs {}
+
+ [TestFixture]
+ public class when_asking_the_exit_menu_item_for_its_name_ {
+ [Test]
+ public void should_return_the_correct_name() {
+ CreateSUT().Name().ShouldBeEqualTo("E&xit");
+ }
+
+ private IMenuItem CreateSUT() {
+ return new ExitMenuItem(null);
+ }
+ }
+
+ [TestFixture]
+ public class when_clicking_on_the_exit_menu_item_ {
+ private MockRepository mockery;
+ private IExitCommand exitCommand;
+
+ [SetUp]
+ public void SetUp() {
+ mockery = new MockRepository();
+ exitCommand = mockery.DynamicMock<IExitCommand>();
+ }
+
+ [Test]
+ public void should_execute_the_exit_command() {
+ using (mockery.Record()) {}
+
+ using (mockery.Playback()) {
+ CreateSUT().Click();
+ }
+ }
+
+ private IMenuItem CreateSUT() {
+ return new ExitMenuItem(exitCommand);
+ }
+ }
+
+ [TestFixture]
+ public class when_asking_the_exit_menu_item_if_it_belongs_to_a_menu_that_it_does {
+ private MockRepository mockery;
+ private ISubMenu fileMenu;
+
+ [SetUp]
+ public void SetUp() {
+ mockery = new MockRepository();
+ fileMenu = mockery.DynamicMock<ISubMenu>();
+
+ SetupResult.For(fileMenu.Name()).Return(MenuNames.File);
+ }
+
+ [Test]
+ public void should_return_true() {
+ using (mockery.Record()) {}
+
+ using (mockery.Playback()) {
+ CreateSUT().BelongsTo(fileMenu).ShouldBeEqualTo(true);
+ }
+ }
+
+ private IMenuItem CreateSUT() {
+ return new ExitMenuItem(null);
+ }
+ }
+}
\ No newline at end of file diff --git a/src/Notepad/Presentation/Model/Menu/File/FileMenu.cs b/src/Notepad/Presentation/Model/Menu/File/FileMenu.cs new file mode 100644 index 0000000..98b5a47 --- /dev/null +++ b/src/Notepad/Presentation/Model/Menu/File/FileMenu.cs @@ -0,0 +1,26 @@ +using System.Collections.Generic;
+using Notepad.Domain.Repositories;
+using Notepad.Infrastructure.Extensions;
+
+namespace Notepad.Presentation.Model.Menu.File {
+ public class FileMenu : ISubMenu {
+ private readonly IRepository<IMenuItem> repository;
+ private readonly IMenuItemComparer menuItemComparer;
+
+ public FileMenu(IRepository<IMenuItem> repository, IMenuItemComparer menuItemComparer) {
+ this.repository = repository;
+ this.menuItemComparer = menuItemComparer;
+ }
+
+ public IEnumerable<IMenuItem> AllMenuItems() {
+ return repository
+ .All()
+ .ThatSatisfy(menuItem => menuItem.BelongsTo(this))
+ .SortedUsing(menuItemComparer);
+ }
+
+ public string Name() {
+ return MenuNames.File;
+ }
+ }
+}
\ No newline at end of file diff --git a/src/Notepad/Presentation/Model/Menu/File/FileMenuSpecs.cs b/src/Notepad/Presentation/Model/Menu/File/FileMenuSpecs.cs new file mode 100644 index 0000000..8630ad3 --- /dev/null +++ b/src/Notepad/Presentation/Model/Menu/File/FileMenuSpecs.cs @@ -0,0 +1,105 @@ +using System.Collections.Generic;
+using MbUnit.Framework;
+using Notepad.Domain.Repositories;
+using Notepad.Infrastructure.Extensions;
+using Notepad.Test.Extensions;
+using Rhino.Mocks;
+
+namespace Notepad.Presentation.Model.Menu.File {
+ public class FileMenuSpecs {}
+
+ [TestFixture]
+ public class when_asking_the_file_menu_for_its_name_ {
+ [Test]
+ public void should_return_the_correct_name() {
+ CreateSUT().Name().ShouldBeEqualTo(MenuNames.File);
+ }
+
+ private ISubMenu CreateSUT() {
+ return new FileMenu(null, null);
+ }
+ }
+
+ [TestFixture]
+ public class when_asking_the_file_menu_for_its_menu_items_ {
+ private MockRepository mockery;
+ private IRepository<IMenuItem> repository;
+ private ISubMenu sut;
+ private IMenuItemComparer menuItemComparer;
+
+ [SetUp]
+ public void SetUp() {
+ mockery = new MockRepository();
+ repository = mockery.DynamicMock<IRepository<IMenuItem>>();
+ menuItemComparer = mockery.DynamicMock<IMenuItemComparer>();
+
+ sut = CreateSUT();
+ }
+
+ [Test]
+ public void should_ask_the_repository_for_all_the_menu_items() {
+ using (mockery.Record()) {
+ Expect
+ .Call(repository.All())
+ .Return(new List<IMenuItem>())
+ .Repeat
+ .AtLeastOnce();
+ }
+
+ using (mockery.Playback()) {
+ sut.AllMenuItems().Walk();
+ }
+ }
+
+ [Test]
+ public void should_return_the_menu_items_that_belong_to_the_file_menu() {
+ var saveMenuItem = mockery.DynamicMock<IMenuItem>();
+ var helpMenuItem = mockery.DynamicMock<IMenuItem>();
+
+ var allMenuItems = new List<IMenuItem> {saveMenuItem, helpMenuItem};
+
+ using (mockery.Record()) {
+ SetupResult.For(repository.All()).Return(allMenuItems);
+ SetupResult.For(saveMenuItem.BelongsTo(sut)).Return(true);
+ SetupResult.For(helpMenuItem.BelongsTo(sut)).Return(false);
+ }
+
+ using (mockery.Playback()) {
+ var returnedItems = sut.AllMenuItems();
+ returnedItems.ShouldContain(saveMenuItem);
+ returnedItems.ShouldNotContain(helpMenuItem);
+ }
+ }
+
+ [Test]
+ public void should_sort_the_items_in_the_file_menu() {
+ var firstItem = mockery.DynamicMock<IMenuItem>();
+ var secondItem = mockery.DynamicMock<IMenuItem>();
+
+ var allMenuItems = new List<IMenuItem> {firstItem, secondItem};
+
+ using (mockery.Record()) {
+ SetupResult.For(repository.All()).Return(allMenuItems);
+ SetupResult.For(firstItem.BelongsTo(null))
+ .IgnoreArguments()
+ .Return(true);
+ SetupResult.For(secondItem.BelongsTo(null))
+ .IgnoreArguments()
+ .Return(true);
+ Expect
+ .Call(menuItemComparer.Compare(firstItem, secondItem))
+ .Return(1)
+ .Repeat
+ .AtLeastOnce();
+ }
+
+ using (mockery.Playback()) {
+ sut.AllMenuItems().Walk();
+ }
+ }
+
+ private ISubMenu CreateSUT() {
+ return new FileMenu(repository, menuItemComparer);
+ }
+ }
+}
\ No newline at end of file diff --git a/src/Notepad/Presentation/Model/Menu/File/NewMenuItem.cs b/src/Notepad/Presentation/Model/Menu/File/NewMenuItem.cs new file mode 100644 index 0000000..ab527d8 --- /dev/null +++ b/src/Notepad/Presentation/Model/Menu/File/NewMenuItem.cs @@ -0,0 +1,17 @@ +using System;
+
+namespace Notepad.Presentation.Model.Menu.File {
+ public class NewMenuItem : IMenuItem {
+ public void Click() {
+ throw new NotImplementedException();
+ }
+
+ public bool BelongsTo(ISubMenu menu) {
+ return menu.Name().Equals(MenuNames.File);
+ }
+
+ public string Name() {
+ return "&New";
+ }
+ }
+}
\ No newline at end of file diff --git a/src/Notepad/Presentation/Model/Menu/File/NewMenuItemSpecs.cs b/src/Notepad/Presentation/Model/Menu/File/NewMenuItemSpecs.cs new file mode 100644 index 0000000..54a7b20 --- /dev/null +++ b/src/Notepad/Presentation/Model/Menu/File/NewMenuItemSpecs.cs @@ -0,0 +1,46 @@ +using MbUnit.Framework;
+using Notepad.Test.Extensions;
+using Rhino.Mocks;
+
+namespace Notepad.Presentation.Model.Menu.File {
+ public class NewMenuItemSpecs {}
+
+ [TestFixture]
+ public class when_asking_the_new_file_menu_if_it_belongs_to_the_file_menu_ {
+ private MockRepository mockery;
+ private ISubMenu fileMenu;
+
+ [SetUp]
+ public void SetUp() {
+ mockery = new MockRepository();
+ fileMenu = mockery.DynamicMock<ISubMenu>();
+
+ SetupResult.For(fileMenu.Name()).Return("&File");
+ }
+
+ [Test]
+ public void should_return_true() {
+ using (mockery.Record()) {}
+
+ using (mockery.Playback()) {
+ CreateSUT().BelongsTo(fileMenu).ShouldBeEqualTo(true);
+ }
+ }
+
+ private IMenuItem CreateSUT() {
+ return new NewMenuItem();
+ }
+ }
+
+ [TestFixture]
+ public class when_asking_the_new_file_menu_item_for_its_name_ {
+ [Test]
+ public void should_return_the_correct_name() {
+ CreateSUT().Name().ShouldBeEqualTo("&New");
+ }
+
+ private IMenuItem CreateSUT() {
+ return new NewMenuItem();
+ }
+ }
+}
\ No newline at end of file diff --git a/src/Notepad/Presentation/Model/Menu/File/SaveAsMenuItem.cs b/src/Notepad/Presentation/Model/Menu/File/SaveAsMenuItem.cs new file mode 100644 index 0000000..859ad32 --- /dev/null +++ b/src/Notepad/Presentation/Model/Menu/File/SaveAsMenuItem.cs @@ -0,0 +1,24 @@ +using Notepad.Presentation.Presenters.Commands;
+using Notepad.Presentation.Presenters.Menu.File;
+
+namespace Notepad.Presentation.Model.Menu.File {
+ public class SaveAsMenuItem : IMenuItem {
+ private readonly IRunPresenterCommand<ISaveAsPresenter> saveAsCommand;
+
+ public SaveAsMenuItem(IRunPresenterCommand<ISaveAsPresenter> saveAsCommand) {
+ this.saveAsCommand = saveAsCommand;
+ }
+
+ public string Name() {
+ return "Save &As...";
+ }
+
+ public void Click() {
+ saveAsCommand.Execute();
+ }
+
+ public bool BelongsTo(ISubMenu menu) {
+ return menu.Name().Equals(MenuNames.File);
+ }
+ }
+}
\ No newline at end of file diff --git a/src/Notepad/Presentation/Model/Menu/File/SaveAsMenuItemSpecs.cs b/src/Notepad/Presentation/Model/Menu/File/SaveAsMenuItemSpecs.cs new file mode 100644 index 0000000..a7c7fd0 --- /dev/null +++ b/src/Notepad/Presentation/Model/Menu/File/SaveAsMenuItemSpecs.cs @@ -0,0 +1,102 @@ +using MbUnit.Framework;
+using Notepad.Presentation.Model.Menu.File.Commands;
+using Notepad.Presentation.Presenters.Commands;
+using Notepad.Presentation.Presenters.Menu.File;
+using Notepad.Test.Extensions;
+using Rhino.Mocks;
+
+namespace Notepad.Presentation.Model.Menu.File {
+ public class SaveAsMenuItemSpecs {}
+
+ [TestFixture]
+ public class when_asking_the_save_as_menu_item_for_its_name_ {
+ [Test]
+ public void should_return_the_correct_name() {
+ CreateSUT().Name().ShouldBeEqualTo("Save &As...");
+ }
+
+ private IMenuItem CreateSUT() {
+ return new SaveAsMenuItem(null);
+ }
+ }
+
+ [TestFixture]
+ public class when_clicking_on_the_save_as_menu_item_ {
+ private MockRepository mockery;
+ private IRunPresenterCommand<ISaveAsPresenter> saveAsCommand;
+
+ [SetUp]
+ public void SetUp() {
+ mockery = new MockRepository();
+ saveAsCommand = mockery.DynamicMock<IRunPresenterCommand<ISaveAsPresenter>>();
+ }
+
+ [Test]
+ public void should_execute_the_save_as_command() {
+ using (mockery.Record()) {}
+
+ using (mockery.Playback()) {
+ CreateSUT().Click();
+ }
+ }
+
+ private IMenuItem CreateSUT() {
+ return new SaveAsMenuItem(saveAsCommand);
+ }
+ }
+
+ [TestFixture]
+ public class when_asking_the_save_as_menu_item_if_it_belongs_to_a_menu_that_it_does {
+ private MockRepository mockery;
+ private ISubMenu fileMenu;
+
+ [SetUp]
+ public void SetUp() {
+ mockery = new MockRepository();
+ fileMenu = mockery.DynamicMock<ISubMenu>();
+
+ SetupResult.For(fileMenu.Name()).Return(MenuNames.File);
+ }
+
+ [Test]
+ public void should_return_true() {
+ using (mockery.Record()) {}
+
+ using (mockery.Playback()) {
+ CreateSUT().BelongsTo(fileMenu).ShouldBeEqualTo(true);
+ }
+ }
+
+ private IMenuItem CreateSUT() {
+ return new SaveAsMenuItem(null);
+ }
+ }
+
+ [TestFixture]
+ public class when_asking_the_save_as_menu_item_if_it_belongs_to_a_menu_item_that_it_does_not {
+ private MockRepository mockery;
+ private ISubMenu unknownMenu;
+
+ [SetUp]
+ public void SetUp() {
+ mockery = new MockRepository();
+ unknownMenu = mockery.DynamicMock<ISubMenu>();
+
+ SetupResult.For(unknownMenu.Name()).Return("blah");
+ }
+
+ [Test]
+ public void should_return_false() {
+ using (mockery.Record()) {}
+
+ using (mockery.Playback()) {
+ CreateSUT().BelongsTo(unknownMenu).ShouldBeEqualTo(false);
+ }
+ }
+
+
+ private IMenuItem CreateSUT() {
+ return new SaveAsMenuItem(null);
+ }
+ }
+}
\ No newline at end of file diff --git a/src/Notepad/Presentation/Model/Menu/File/SaveMenuItem.cs b/src/Notepad/Presentation/Model/Menu/File/SaveMenuItem.cs new file mode 100644 index 0000000..f99c179 --- /dev/null +++ b/src/Notepad/Presentation/Model/Menu/File/SaveMenuItem.cs @@ -0,0 +1,23 @@ +using Notepad.Presentation.Model.Menu.File.Commands;
+
+namespace Notepad.Presentation.Model.Menu.File {
+ public class SaveMenuItem : IMenuItem {
+ private readonly ISaveCommand saveCommand;
+
+ public SaveMenuItem(ISaveCommand saveCommand) {
+ this.saveCommand = saveCommand;
+ }
+
+ public bool BelongsTo(ISubMenu menu) {
+ return menu.Name().Equals(MenuNames.File);
+ }
+
+ public void Click() {
+ saveCommand.Execute();
+ }
+
+ public string Name() {
+ return "&Save";
+ }
+ }
+}
\ No newline at end of file diff --git a/src/Notepad/Presentation/Model/Menu/File/SaveMenuItemSpecs.cs b/src/Notepad/Presentation/Model/Menu/File/SaveMenuItemSpecs.cs new file mode 100644 index 0000000..071adf8 --- /dev/null +++ b/src/Notepad/Presentation/Model/Menu/File/SaveMenuItemSpecs.cs @@ -0,0 +1,99 @@ +using MbUnit.Framework;
+using Notepad.Presentation.Model.Menu.File.Commands;
+using Notepad.Test.Extensions;
+using Rhino.Mocks;
+
+namespace Notepad.Presentation.Model.Menu.File {
+ public class SaveMenuItemSpecs {}
+
+ [TestFixture]
+ public class when_asking_the_save_menu_item_for_its_name_ {
+ [Test]
+ public void should_return_the_correct_name() {
+ CreateSUT().Name().ShouldBeEqualTo("&Save");
+ }
+
+ private IMenuItem CreateSUT() {
+ return new SaveMenuItem(null);
+ }
+ }
+
+ [TestFixture]
+ public class when_clicking_on_the_save_menu_item_ {
+ private MockRepository mockery;
+ private ISaveCommand saveCommand;
+
+ [SetUp]
+ public void SetUp() {
+ mockery = new MockRepository();
+ saveCommand = mockery.DynamicMock<ISaveCommand>();
+ }
+
+ [Test]
+ public void should_execute_the_save_command() {
+ using (mockery.Record()) {}
+
+ using (mockery.Playback()) {
+ CreateSUT().Click();
+ }
+ }
+
+ private IMenuItem CreateSUT() {
+ return new SaveMenuItem(saveCommand);
+ }
+ }
+
+ [TestFixture]
+ public class when_asking_the_save_menu_item_if_it_belongs_to_a_menu_that_it_does {
+ private MockRepository mockery;
+ private ISubMenu fileMenu;
+
+ [SetUp]
+ public void SetUp() {
+ mockery = new MockRepository();
+ fileMenu = mockery.DynamicMock<ISubMenu>();
+
+ SetupResult.For(fileMenu.Name()).Return(MenuNames.File);
+ }
+
+ [Test]
+ public void should_return_true() {
+ using (mockery.Record()) {}
+
+ using (mockery.Playback()) {
+ CreateSUT().BelongsTo(fileMenu).ShouldBeEqualTo(true);
+ }
+ }
+
+ private IMenuItem CreateSUT() {
+ return new SaveMenuItem(null);
+ }
+ }
+
+ [TestFixture]
+ public class when_asking_the_save_menu_item_if_it_belongs_to_a_menu_item_that_it_does_not {
+ private MockRepository mockery;
+ private ISubMenu unknownMenu;
+
+ [SetUp]
+ public void SetUp() {
+ mockery = new MockRepository();
+ unknownMenu = mockery.DynamicMock<ISubMenu>();
+
+ SetupResult.For(unknownMenu.Name()).Return("blah");
+ }
+
+ [Test]
+ public void should_return_false() {
+ using (mockery.Record()) {}
+
+ using (mockery.Playback()) {
+ CreateSUT().BelongsTo(unknownMenu).ShouldBeEqualTo(false);
+ }
+ }
+
+ private IMenuItem CreateSUT() {
+ return new SaveMenuItem(null);
+ }
+ }
+}
\ No newline at end of file diff --git a/src/Notepad/Presentation/Model/Menu/Help/AboutMenuItem.cs b/src/Notepad/Presentation/Model/Menu/Help/AboutMenuItem.cs new file mode 100644 index 0000000..82a2839 --- /dev/null +++ b/src/Notepad/Presentation/Model/Menu/Help/AboutMenuItem.cs @@ -0,0 +1,24 @@ +using Notepad.Presentation.Presenters.Commands;
+using Notepad.Presentation.Presenters.Menu.Help;
+
+namespace Notepad.Presentation.Model.Menu.Help {
+ public class AboutMenuItem : IMenuItem {
+ private readonly IRunPresenterCommand<IAboutApplicationPresenter> displayAboutCommand;
+
+ public AboutMenuItem(IRunPresenterCommand<IAboutApplicationPresenter> displayAboutCommand) {
+ this.displayAboutCommand = displayAboutCommand;
+ }
+
+ public bool BelongsTo(ISubMenu menu) {
+ return menu.Name().Equals(MenuNames.Help);
+ }
+
+ public void Click() {
+ displayAboutCommand.Execute();
+ }
+
+ public string Name() {
+ return MenuItemNames.About;
+ }
+ }
+}
\ No newline at end of file diff --git a/src/Notepad/Presentation/Model/Menu/Help/AboutMenuItemSpecs.cs b/src/Notepad/Presentation/Model/Menu/Help/AboutMenuItemSpecs.cs new file mode 100644 index 0000000..74d7663 --- /dev/null +++ b/src/Notepad/Presentation/Model/Menu/Help/AboutMenuItemSpecs.cs @@ -0,0 +1,101 @@ +using MbUnit.Framework;
+using Notepad.Presentation.Presenters.Commands;
+using Notepad.Presentation.Presenters.Menu.Help;
+using Notepad.Test.Extensions;
+using Rhino.Mocks;
+
+namespace Notepad.Presentation.Model.Menu.Help {
+ public class AboutMenuItemSpecs {}
+
+ [TestFixture]
+ public class when_asking_the_about_menu_item_for_its_name_ {
+ [Test]
+ public void should_return_the_correct_name() {
+ CreateSUT().Name().ShouldBeEqualTo(MenuItemNames.About);
+ }
+
+ private IMenuItem CreateSUT() {
+ return new AboutMenuItem(null);
+ }
+ }
+
+ [TestFixture]
+ public class when_clicking_on_the_about_menu_item_ {
+ private MockRepository mockery;
+ private IRunPresenterCommand<IAboutApplicationPresenter> displayAboutCommand;
+
+ [SetUp]
+ public void SetUp() {
+ mockery = new MockRepository();
+ displayAboutCommand = mockery.DynamicMock<IRunPresenterCommand<IAboutApplicationPresenter>>();
+ }
+
+ [Test]
+ public void should_execute_the_display_about_command() {
+ using (mockery.Record()) {}
+
+ using (mockery.Playback()) {
+ CreateSUT().Click();
+ }
+ }
+
+ private IMenuItem CreateSUT() {
+ return new AboutMenuItem(displayAboutCommand);
+ }
+ }
+
+ [TestFixture]
+ public class when_asking_the_about_menu_item_if_it_belongs_to_a_menu_that_it_does {
+ private MockRepository mockery;
+ private ISubMenu menuThatThisItemBelongsTo;
+
+ [SetUp]
+ public void SetUp() {
+ mockery = new MockRepository();
+ menuThatThisItemBelongsTo = mockery.DynamicMock<ISubMenu>();
+
+ SetupResult.For(menuThatThisItemBelongsTo.Name()).Return(MenuNames.Help);
+ }
+
+ [Test]
+ public void should_return_true() {
+ using (mockery.Record()) {}
+
+ using (mockery.Playback()) {
+ CreateSUT().BelongsTo(menuThatThisItemBelongsTo).ShouldBeEqualTo(true);
+ }
+ }
+
+ private IMenuItem CreateSUT() {
+ return new AboutMenuItem(null);
+ }
+ }
+
+ [TestFixture]
+ public class when_asking_the_about_menu_item_if_it_belongs_to_a_menu_item_that_it_does_not {
+ private MockRepository mockery;
+ private ISubMenu unknownMenu;
+
+ [SetUp]
+ public void SetUp() {
+ mockery = new MockRepository();
+ unknownMenu = mockery.DynamicMock<ISubMenu>();
+
+ SetupResult.For(unknownMenu.Name()).Return("blah");
+ }
+
+ [Test]
+ public void should_return_false() {
+ using (mockery.Record()) {}
+
+ using (mockery.Playback()) {
+ CreateSUT().BelongsTo(unknownMenu).ShouldBeEqualTo(false);
+ }
+ }
+
+
+ private IMenuItem CreateSUT() {
+ return new AboutMenuItem(null);
+ }
+ }
+}
\ No newline at end of file diff --git a/src/Notepad/Presentation/Model/Menu/Help/HelpMenu.cs b/src/Notepad/Presentation/Model/Menu/Help/HelpMenu.cs new file mode 100644 index 0000000..ace9696 --- /dev/null +++ b/src/Notepad/Presentation/Model/Menu/Help/HelpMenu.cs @@ -0,0 +1,21 @@ +using System.Collections.Generic;
+using Notepad.Domain.Repositories;
+using Notepad.Infrastructure.Extensions;
+
+namespace Notepad.Presentation.Model.Menu.Help {
+ public class HelpMenu : ISubMenu {
+ private readonly IRepository<IMenuItem> menuItems;
+
+ public HelpMenu(IRepository<IMenuItem> repository) {
+ menuItems = repository;
+ }
+
+ public IEnumerable<IMenuItem> AllMenuItems() {
+ return menuItems.All().ThatSatisfy(m => m.BelongsTo(this));
+ }
+
+ public string Name() {
+ return MenuNames.Help;
+ }
+ }
+}
\ No newline at end of file diff --git a/src/Notepad/Presentation/Model/Menu/Help/HelpMenuSpecs.cs b/src/Notepad/Presentation/Model/Menu/Help/HelpMenuSpecs.cs new file mode 100644 index 0000000..c716376 --- /dev/null +++ b/src/Notepad/Presentation/Model/Menu/Help/HelpMenuSpecs.cs @@ -0,0 +1,76 @@ +using System.Collections.Generic;
+using MbUnit.Framework;
+using Notepad.Domain.Repositories;
+using Notepad.Infrastructure.Extensions;
+using Notepad.Presentation.Model.Menu.Help;
+using Notepad.Test.Extensions;
+using Rhino.Mocks;
+
+namespace Notepad.Presentation.Model.Menu.Help {
+ public class HelpMenuSpecs {}
+
+ [TestFixture]
+ public class when_asking_the_help_menu_for_its_name_ {
+ [Test]
+ public void should_return_the_correct_name() {
+ CreateSUT().Name().ShouldBeEqualTo(MenuNames.Help);
+ }
+
+ private ISubMenu CreateSUT() {
+ return new HelpMenu(null);
+ }
+ }
+
+ [TestFixture]
+ public class when_asking_the_help_menu_for_its_menu_items_ {
+ private MockRepository mockery;
+ private IRepository<IMenuItem> repository;
+ private ISubMenu sut;
+
+ [SetUp]
+ public void SetUp() {
+ mockery = new MockRepository();
+ repository = mockery.DynamicMock<IRepository<IMenuItem>>();
+ sut = CreateSUT();
+ }
+
+ [Test]
+ public void should_ask_the_repository_for_all_the_menu_items() {
+ using (mockery.Record()) {
+ Expect
+ .Call(repository.All())
+ .Return(new List<IMenuItem>())
+ .Repeat
+ .AtLeastOnce();
+ }
+
+ using (mockery.Playback()) {
+ sut.AllMenuItems().Walk();
+ }
+ }
+
+ [Test]
+ public void should_return_the_menu_items_that_belong_to_the_help_menu() {
+ var saveMenuItem = mockery.DynamicMock<IMenuItem>();
+ var helpMenuItem = mockery.DynamicMock<IMenuItem>();
+
+ var allMenuItems = new List<IMenuItem> {saveMenuItem, helpMenuItem};
+
+ using (mockery.Record()) {
+ SetupResult.For(repository.All()).Return(allMenuItems);
+ SetupResult.For(saveMenuItem.BelongsTo(sut)).Return(false);
+ SetupResult.For(helpMenuItem.BelongsTo(sut)).Return(true);
+ }
+
+ using (mockery.Playback()) {
+ var returnedItems = sut.AllMenuItems();
+ returnedItems.ShouldNotContain(saveMenuItem);
+ returnedItems.ShouldContain(helpMenuItem);
+ }
+ }
+
+ private ISubMenu CreateSUT() {
+ return new HelpMenu(repository);
+ }
+ }
+}
\ No newline at end of file diff --git a/src/Notepad/Presentation/Model/Menu/IMenuItem.cs b/src/Notepad/Presentation/Model/Menu/IMenuItem.cs new file mode 100644 index 0000000..26483a0 --- /dev/null +++ b/src/Notepad/Presentation/Model/Menu/IMenuItem.cs @@ -0,0 +1,7 @@ +namespace Notepad.Presentation.Model.Menu {
+ public interface IMenuItem {
+ string Name();
+ void Click();
+ bool BelongsTo(ISubMenu menu);
+ }
+}
\ No newline at end of file diff --git a/src/Notepad/Presentation/Model/Menu/IMenuItemComparer.cs b/src/Notepad/Presentation/Model/Menu/IMenuItemComparer.cs new file mode 100644 index 0000000..2fd15c7 --- /dev/null +++ b/src/Notepad/Presentation/Model/Menu/IMenuItemComparer.cs @@ -0,0 +1,23 @@ +using System.Collections.Generic;
+
+namespace Notepad.Presentation.Model.Menu {
+ public interface IMenuItemComparer : IComparer<IMenuItem> {}
+
+ public class MenuItemComparer : IMenuItemComparer {
+ private IList<string> rankedMenuItems;
+
+ public MenuItemComparer() {
+ rankedMenuItems = new List<string> {
+ MenuItemNames.New,
+ MenuItemNames.Save,
+ MenuItemNames.SaveAs,
+ MenuItemNames.Exit,
+ MenuItemNames.About
+ };
+ }
+
+ public int Compare(IMenuItem x, IMenuItem y) {
+ return rankedMenuItems.IndexOf(x.Name()).CompareTo(rankedMenuItems.IndexOf(y.Name()));
+ }
+ }
+}
\ No newline at end of file diff --git a/src/Notepad/Presentation/Model/Menu/ISubMenu.cs b/src/Notepad/Presentation/Model/Menu/ISubMenu.cs new file mode 100644 index 0000000..f06a0b9 --- /dev/null +++ b/src/Notepad/Presentation/Model/Menu/ISubMenu.cs @@ -0,0 +1,9 @@ +using System.Collections.Generic;
+using Notepad.Presentation.Model.Menu;
+
+namespace Notepad.Presentation.Model.Menu {
+ public interface ISubMenu {
+ string Name();
+ IEnumerable<IMenuItem> AllMenuItems();
+ }
+}
\ No newline at end of file diff --git a/src/Notepad/Presentation/Model/Menu/ISubMenuItemComparer.cs b/src/Notepad/Presentation/Model/Menu/ISubMenuItemComparer.cs new file mode 100644 index 0000000..74f30db --- /dev/null +++ b/src/Notepad/Presentation/Model/Menu/ISubMenuItemComparer.cs @@ -0,0 +1,20 @@ +using System.Collections.Generic;
+
+namespace Notepad.Presentation.Model.Menu {
+ public interface ISubMenuItemComparer : IComparer<ISubMenu> {}
+
+ public class SubMenuItemComparer : ISubMenuItemComparer {
+ private List<string> rankings;
+
+ public SubMenuItemComparer() {
+ rankings = new List<string> {
+ MenuNames.File,
+ MenuNames.Help
+ };
+ }
+
+ public int Compare(ISubMenu x, ISubMenu y) {
+ return rankings.IndexOf(x.Name()).CompareTo(rankings.IndexOf(y.Name()));
+ }
+ }
+}
\ No newline at end of file diff --git a/src/Notepad/Presentation/Model/Menu/MenuNames.cs b/src/Notepad/Presentation/Model/Menu/MenuNames.cs new file mode 100644 index 0000000..f5ef21f --- /dev/null +++ b/src/Notepad/Presentation/Model/Menu/MenuNames.cs @@ -0,0 +1,14 @@ +namespace Notepad.Presentation.Model.Menu {
+ public static class MenuNames {
+ public static readonly string File = "&File";
+ public static readonly string Help = "&Help";
+ }
+
+ public static class MenuItemNames {
+ public static readonly string New = "&New";
+ public static readonly string Save = "&Save";
+ public static readonly string SaveAs = "Save &As...";
+ public static readonly string Exit = "E&xit";
+ public static readonly string About = "&About";
+ }
+}
\ No newline at end of file |
