// Copyright (C) Stichting Deltares 2017. All rights reserved.
//
// This file is part of Ringtoets.
//
// Ringtoets is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with this program. If not, see .
//
// All names, logos, and references to "Deltares" are registered trademarks of
// Stichting Deltares and remain full property of Stichting Deltares at all times.
// All rights reserved.
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using System.Windows.Forms;
using System.Windows.Forms.VisualStyles;
using System.Windows.Threading;
using Core.Common.Base.Data;
using Core.Common.Base.Storage;
using Core.Common.Controls.TreeView;
using Core.Common.Controls.Views;
using Core.Common.Gui.Commands;
using Core.Common.Gui.ContextMenu;
using Core.Common.Gui.Forms.MainWindow;
using Core.Common.Gui.Forms.MessageWindow;
using Core.Common.Gui.Forms.PropertyGridView;
using Core.Common.Gui.Forms.ViewHost;
using Core.Common.Gui.Plugin;
using Core.Common.Gui.Settings;
using Core.Common.TestUtil;
using Core.Common.Utils.Settings;
using log4net;
using log4net.Appender;
using log4net.Repository.Hierarchy;
using NUnit.Framework;
using Rhino.Mocks;
namespace Core.Common.Gui.Test
{
[TestFixture]
public class GuiCoreTests
{
private MessageWindowLogAppender originalMessageWindowLogAppender;
private IViewCommands originalViewPropertyEditor;
[SetUp]
public void SetUp()
{
originalMessageWindowLogAppender = MessageWindowLogAppender.Instance;
MessageWindowLogAppender.Instance = new MessageWindowLogAppender();
originalViewPropertyEditor = ViewPropertyEditor.ViewCommands;
}
[TearDown]
public void TearDown()
{
MessageWindowLogAppender.Instance = originalMessageWindowLogAppender;
ViewPropertyEditor.ViewCommands = originalViewPropertyEditor;
Dispatcher.CurrentDispatcher.InvokeShutdown();
}
[Test]
[Apartment(ApartmentState.STA)]
public void ParameteredConstructor_ValidArguments_ExpectedValues()
{
// Setup
var mocks = new MockRepository();
var projectStore = mocks.Stub();
var projectMigrator = mocks.Stub();
var projectFactory = mocks.Stub();
var project = mocks.Stub();
projectFactory.Stub(pf => pf.CreateNewProject()).Return(project);
mocks.ReplayAll();
var guiCoreSettings = new GuiCoreSettings();
// Call
using (var mainWindow = new MainWindow())
using (var gui = new GuiCore(mainWindow, projectStore, projectMigrator, projectFactory, guiCoreSettings))
{
// Assert
Assert.AreEqual(null, gui.PropertyResolver);
Assert.IsNull(gui.ProjectFilePath);
Assert.AreSame(project, gui.Project);
Assert.AreEqual(null, gui.Selection);
Assert.IsInstanceOf(gui.StorageCommands);
Assert.IsInstanceOf(gui.ViewCommands);
Assert.AreEqual(null, gui.ApplicationCommands);
Assert.AreEqual(null, gui.ViewHost);
Assert.AreEqual(null, gui.DocumentViewController);
Assert.AreSame(guiCoreSettings, gui.FixedSettings);
CollectionAssert.IsEmpty(gui.Plugins);
Assert.AreEqual(mainWindow, gui.MainWindow);
Assert.AreSame(ViewPropertyEditor.ViewCommands, gui.ViewCommands);
// Check for OS settings that allow visual styles to be rendered in the first place:
if (VisualStyleInformation.IsSupportedByOS && VisualStyleInformation.IsEnabledByUser &&
(Application.VisualStyleState == VisualStyleState.ClientAreaEnabled ||
Application.VisualStyleState == VisualStyleState.ClientAndNonClientAreasEnabled))
{
Assert.IsTrue(Application.RenderWithVisualStyles,
"OS configured to support visual styles, therefore GUI should enable this rendering style.");
}
else
{
//
Assert.IsFalse(Application.RenderWithVisualStyles,
"OS not supporting visual styles, therefore application shouldn't be render with visual styles.");
}
}
mocks.VerifyAll();
}
[Test]
[Apartment(ApartmentState.STA)]
[TestCase(0)]
[TestCase(1)]
[TestCase(2)]
[TestCase(3)]
public void ParameteredConstructor_SomeArgumentIsNull_ThrowsArgumentNullException(int nullArgumentIndex)
{
// Setup
var mocks = new MockRepository();
IStoreProject projectStore = nullArgumentIndex == 1 ? null : mocks.Stub();
IMigrateProject projectMigrator = nullArgumentIndex == 2 ? null : mocks.Stub();
IProjectFactory projectFactory = CreateProjectFactory(mocks);
mocks.ReplayAll();
GuiCoreSettings guiCoreSettings = nullArgumentIndex == 3 ? null : new GuiCoreSettings();
// Call
using (var mainWindow = new MainWindow())
{
// Call
TestDelegate call = () => new GuiCore(nullArgumentIndex == 0 ? null : mainWindow,
projectStore, projectMigrator, projectFactory, guiCoreSettings);
// Assert
const string expectedMessage = "Value cannot be null.";
TestHelper.AssertThrowsArgumentExceptionAndTestMessage(call, expectedMessage);
}
mocks.VerifyAll();
}
[Test]
[Apartment(ApartmentState.STA)]
public void Constructor_ConstructedAfterAnotherInstanceHasBeenCreated_ThrowsInvalidOperationException()
{
// Setup
var mocks = new MockRepository();
var projectStore = mocks.Stub();
var projectMigrator = mocks.Stub();
IProjectFactory projectFactory = CreateProjectFactory(mocks);
mocks.ReplayAll();
var guiCoreSettings = new GuiCoreSettings();
using (var mainWindow = new MainWindow())
using (new GuiCore(mainWindow, projectStore, projectMigrator, projectFactory, guiCoreSettings))
{
// Call
TestDelegate call = () =>
{
using (new GuiCore(mainWindow, projectStore, projectMigrator, projectFactory, guiCoreSettings)) {}
};
// Assert
Assert.Throws(call);
}
mocks.VerifyAll();
}
[Test]
[Apartment(ApartmentState.STA)]
public void SetProject_SetNull_ThrowsArgumentNullException()
{
var mocks = new MockRepository();
var projectStore = mocks.Stub();
var projectMigrator = mocks.Stub();
var pluginMock = mocks.Stub();
pluginMock.Expect(p => p.Deactivate());
pluginMock.Expect(p => p.Dispose());
IProjectFactory projectFactory = CreateProjectFactory(mocks);
mocks.ReplayAll();
using (var gui = new GuiCore(new MainWindow(), projectStore, projectMigrator, projectFactory, new GuiCoreSettings()))
{
gui.Plugins.Add(pluginMock);
// Call
TestDelegate test = () => gui.SetProject(null, null);
// Assert
Assert.Throws(test);
}
mocks.VerifyAll();
}
[Test]
[Apartment(ApartmentState.STA)]
public void Dispose_PluginsAdded_PluginsDisabledAndRemovedAndDisposed()
{
// Setup
var mocks = new MockRepository();
var projectStore = mocks.Stub();
var projectMigrator = mocks.Stub();
var pluginMock = mocks.Stub();
pluginMock.Expect(p => p.Deactivate());
pluginMock.Expect(p => p.Dispose());
IProjectFactory projectFactory = CreateProjectFactory(mocks);
mocks.ReplayAll();
var gui = new GuiCore(new MainWindow(), projectStore, projectMigrator, projectFactory, new GuiCoreSettings());
gui.Plugins.Add(pluginMock);
// Call
gui.Dispose();
// Assert
Assert.IsNull(gui.Plugins);
mocks.VerifyAll();
}
[Test]
[Apartment(ApartmentState.STA)]
public void Dispose_PluginAddedButThrowsExceptionDuringDeactivation_LogErrorAndStillDisposeAndRemove()
{
// Setup
var mocks = new MockRepository();
var projectStore = mocks.Stub();
var projectMigrator = mocks.Stub();
var pluginMock = mocks.Stub();
pluginMock.Expect(p => p.Deactivate()).Throw(new Exception("Bad stuff happening!"));
pluginMock.Expect(p => p.Dispose());
IProjectFactory projectFactory = CreateProjectFactory(mocks);
mocks.ReplayAll();
var gui = new GuiCore(new MainWindow(), projectStore, projectMigrator, projectFactory, new GuiCoreSettings());
gui.Plugins.Add(pluginMock);
// Call
Action call = () => gui.Dispose();
// Assert
TestHelper.AssertLogMessageIsGenerated(call, "Kritieke fout opgetreden tijdens deactivering van de grafische interface plugin.", 1);
Assert.IsNull(gui.Plugins);
mocks.VerifyAll();
}
[Test]
[Apartment(ApartmentState.STA)]
public void Dispose_HasSelection_ClearSelection()
{
// Setup
var mocks = new MockRepository();
var projectStore = mocks.Stub();
var projectMigrator = mocks.Stub();
IProjectFactory projectFactory = CreateProjectFactory(mocks);
mocks.ReplayAll();
var gui = new GuiCore(new MainWindow(), projectStore, projectMigrator, projectFactory, new GuiCoreSettings())
{
Selection = new object()
};
// Call
gui.Dispose();
// Assert
Assert.IsNull(gui.Selection);
mocks.VerifyAll();
}
[Test]
[Apartment(ApartmentState.STA)]
public void Dispose_HasMainWindow_DiposeOfMainWindow()
{
// Setup
var mocks = new MockRepository();
var projectStore = mocks.Stub();
var projectMigrator = mocks.Stub();
IProjectFactory projectFactory = CreateProjectFactory(mocks);
mocks.ReplayAll();
using (var mainWindow = new MainWindow())
{
var gui = new GuiCore(mainWindow, projectStore, projectMigrator, projectFactory, new GuiCoreSettings());
// Call
gui.Dispose();
// Assert
Assert.IsTrue(mainWindow.IsWindowDisposed);
Assert.IsNull(gui.MainWindow);
}
mocks.VerifyAll();
}
[Test]
[Apartment(ApartmentState.STA)]
public void Dispose_HasInitializedMessageWindowForLogAppender_ClearMessageWindow()
{
// Setup
var mocks = new MockRepository();
var projectStore = mocks.Stub();
var projectMigrator = mocks.Stub();
IProjectFactory projectFactory = CreateProjectFactory(mocks);
mocks.ReplayAll();
var messageWindowLogAppender = new MessageWindowLogAppender();
Logger rootLogger = ((Hierarchy) LogManager.GetRepository()).Root;
rootLogger.AddAppender(messageWindowLogAppender);
try
{
using (var gui = new GuiCore(new MainWindow(), projectStore, projectMigrator, projectFactory, new GuiCoreSettings()))
{
gui.Run();
// Precondition:
Assert.IsNotNull(MessageWindowLogAppender.Instance.MessageWindow);
Assert.IsNotNull(messageWindowLogAppender.MessageWindow);
// Call
gui.Dispose();
// Assert
Assert.IsNull(MessageWindowLogAppender.Instance.MessageWindow);
Assert.IsNull(messageWindowLogAppender.MessageWindow);
CollectionAssert.DoesNotContain(rootLogger.Appenders, messageWindowLogAppender);
}
}
finally
{
rootLogger.RemoveAppender(messageWindowLogAppender);
}
mocks.VerifyAll();
}
[Test]
[Apartment(ApartmentState.STA)]
public void Dispose_HasOpenedToolView_ToolViewsClearedAndViewsDisposed()
{
// Setup
var mocks = new MockRepository();
var projectStore = mocks.Stub();
var projectMigrator = mocks.Stub();
IProjectFactory projectFactory = CreateProjectFactory(mocks);
mocks.ReplayAll();
using (var toolView = new TestView())
using (var gui = new GuiCore(new MainWindow(), projectStore, projectMigrator, projectFactory, new GuiCoreSettings()))
{
gui.Run();
gui.ViewHost.AddToolView(toolView, ToolViewLocation.Left);
// Call
gui.Dispose();
// Assert
Assert.IsEmpty(gui.ViewHost.ToolViews);
Assert.IsTrue(toolView.IsDisposed);
}
mocks.VerifyAll();
}
[Test]
[Apartment(ApartmentState.STA)]
public void Dispose_HasOpenedDocumentView_DocumentViewsClearedAndViewsDisposed()
{
// Setup
var mocks = new MockRepository();
var projectStore = mocks.Stub();
var projectMigrator = mocks.Stub();
IProjectFactory projectFactory = CreateProjectFactory(mocks);
mocks.ReplayAll();
using (var documentView = new TestView())
using (var gui = new GuiCore(new MainWindow(), projectStore, projectMigrator, projectFactory, new GuiCoreSettings()))
{
gui.Run();
gui.ViewHost.AddDocumentView(documentView);
// Call
gui.Dispose();
// Assert
Assert.IsEmpty(gui.ViewHost.DocumentViews);
Assert.IsNull(gui.DocumentViewController);
Assert.IsTrue(documentView.IsDisposed);
}
mocks.VerifyAll();
}
[Test]
[Apartment(ApartmentState.STA)]
public void Run_NoMessageWindowLogAppender_AddNewLogAppender()
{
// Setup
var mocks = new MockRepository();
var projectStore = mocks.Stub();
var projectMigrator = mocks.Stub();
IProjectFactory projectFactory = CreateProjectFactory(mocks);
mocks.ReplayAll();
Logger rootLogger = ((Hierarchy) LogManager.GetRepository()).Root;
IAppender[] originalAppenders = rootLogger.Appenders.ToArray();
rootLogger.RemoveAllAppenders();
try
{
using (var gui = new GuiCore(new MainWindow(), projectStore, projectMigrator, projectFactory, new GuiCoreSettings()))
{
// Call
gui.Run();
// Assert
Assert.AreEqual(1, rootLogger.Appenders.Count);
IAppender appender = rootLogger.Appenders[0];
Assert.IsInstanceOf(appender);
Assert.AreSame(appender, MessageWindowLogAppender.Instance);
Assert.IsTrue(rootLogger.Repository.Configured);
Assert.IsTrue(MessageWindowLogAppender.Instance.Enabled);
}
}
finally
{
rootLogger.RemoveAllAppenders();
foreach (IAppender appender in originalAppenders)
{
rootLogger.AddAppender(appender);
}
}
mocks.VerifyAll();
}
[Test]
[Apartment(ApartmentState.STA)]
public void Run_AlreadyHasMessageWindowLogAppender_NoChangesToLogAppenders()
{
// Setup
var mocks = new MockRepository();
var projectStore = mocks.Stub();
var projectMigrator = mocks.Stub();
IProjectFactory projectFactory = CreateProjectFactory(mocks);
mocks.ReplayAll();
var appender = new MessageWindowLogAppender();
Logger rootLogger = ((Hierarchy) LogManager.GetRepository()).Root;
IAppender[] originalAppenders = rootLogger.Appenders.ToArray();
rootLogger.RemoveAllAppenders();
rootLogger.AddAppender(appender);
bool rootloggerConfigured = rootLogger.Repository.Configured;
try
{
using (var gui = new GuiCore(new MainWindow(), projectStore, projectMigrator, projectFactory, new GuiCoreSettings()))
{
// Call
gui.Run();
// Assert
Assert.AreEqual(1, rootLogger.Appenders.Count);
Assert.AreSame(appender, rootLogger.Appenders[0]);
Assert.AreSame(appender, MessageWindowLogAppender.Instance);
Assert.AreEqual(rootloggerConfigured, rootLogger.Repository.Configured);
Assert.IsTrue(MessageWindowLogAppender.Instance.Enabled);
}
}
finally
{
rootLogger.RemoveAllAppenders();
foreach (IAppender originalAppender in originalAppenders)
{
rootLogger.AddAppender(originalAppender);
}
}
mocks.VerifyAll();
}
[Test]
[Apartment(ApartmentState.STA)]
public void Run_WithFile_LoadProjectFromFile()
{
// Setup
const string fileName = "SomeFile";
string testFile = $"{fileName}.rtd";
var mocks = new MockRepository();
var projectStore = mocks.Stub();
var projectMigrator = mocks.Stub();
projectMigrator.Stub(m => m.ShouldMigrate(testFile)).Return(MigrationRequired.No);
var deserializedProject = mocks.Stub();
projectStore.Expect(ps => ps.LoadProject(testFile)).Return(deserializedProject);
IProjectFactory projectFactory = CreateProjectFactory(mocks);
mocks.ReplayAll();
var fixedSettings = new GuiCoreSettings
{
MainWindowTitle = ""
};
using (var mainWindow = new MainWindow())
using (var gui = new GuiCore(mainWindow, projectStore, projectMigrator, projectFactory, fixedSettings))
{
// Call
Action call = () => gui.Run(testFile);
// Assert
var expectedMessages = new[]
{
Tuple.Create("Openen van project is gestart.", LogLevelConstant.Info),
Tuple.Create("Openen van project is gelukt.", LogLevelConstant.Info)
};
TestHelper.AssertLogMessagesWithLevelAreGenerated(call, expectedMessages);
Assert.AreEqual(testFile, gui.ProjectFilePath);
Assert.AreSame(deserializedProject, gui.Project);
Assert.AreEqual(fileName, gui.Project.Name,
"Project name should be updated to the name of the file.");
string expectedTitle = $"{fileName} - {fixedSettings.MainWindowTitle} {SettingsHelper.Instance.ApplicationVersion}";
Assert.AreEqual(expectedTitle, mainWindow.Title);
}
mocks.VerifyAll();
}
[Test]
[Apartment(ApartmentState.STA)]
public void Run_LoadingFromOutdatedFileAndMigrationCancelled_LoadDefaultProjectInstead()
{
// Setup
const string fileName = "SomeFile";
string testFile = $"{fileName}.rtd";
var mocks = new MockRepository();
var projectStore = mocks.Stub();
var projectMigrator = mocks.Stub();
projectMigrator.Stub(pm => pm.ShouldMigrate(testFile)).Return(MigrationRequired.Yes);
projectMigrator.Stub(pm => pm.DetermineMigrationLocation(testFile)).Return(null);
const string expectedProjectName = "Project";
var project = mocks.Stub();
project.Name = expectedProjectName;
var projectFactory = mocks.Stub();
projectFactory.Stub(ph => ph.CreateNewProject()).Return(project);
mocks.ReplayAll();
var fixedSettings = new GuiCoreSettings
{
MainWindowTitle = ""
};
using (var mainWindow = new MainWindow())
using (var gui = new GuiCore(mainWindow, projectStore, projectMigrator, projectFactory, fixedSettings))
{
// Call
gui.Run(testFile);
// Assert
Assert.IsNull(gui.ProjectFilePath);
string expectedTitle = $"{expectedProjectName} - {fixedSettings.MainWindowTitle} {SettingsHelper.Instance.ApplicationVersion}";
Assert.AreEqual(expectedTitle, mainWindow.Title);
}
mocks.VerifyAll();
}
[Test]
[Apartment(ApartmentState.STA)]
public void Run_LoadingFromOutdatedAndShouldMigrateThrowsArgumentException_LogErrorAndLoadDefaultProjectInstead()
{
// Setup
const string fileName = "SomeFile";
string testFile = $"{fileName}.rtd";
const string expectedErrorMessage = "You shall not migrate!";
var mocks = new MockRepository();
var projectStore = mocks.Stub();
var projectMigrator = mocks.Stub();
projectMigrator.Stub(pm => pm.ShouldMigrate(testFile))
.Throw(new ArgumentException(expectedErrorMessage));
const string expectedProjectName = "Project";
var project = mocks.Stub();
project.Name = expectedProjectName;
var projectFactory = mocks.Stub();
projectFactory.Stub(ph => ph.CreateNewProject()).Return(project);
mocks.ReplayAll();
var fixedSettings = new GuiCoreSettings
{
MainWindowTitle = ""
};
using (var mainWindow = new MainWindow())
using (var gui = new GuiCore(mainWindow, projectStore, projectMigrator, projectFactory, fixedSettings))
{
// Call
Action call = () => gui.Run(testFile);
// Assert
TestHelper.AssertLogMessageWithLevelIsGenerated(call, Tuple.Create(expectedErrorMessage, LogLevelConstant.Error));
Assert.IsNull(gui.ProjectFilePath);
string expectedTitle = $"{expectedProjectName} - {fixedSettings.MainWindowTitle} {SettingsHelper.Instance.ApplicationVersion}";
Assert.AreEqual(expectedTitle, mainWindow.Title);
}
mocks.VerifyAll();
}
[Test]
[Apartment(ApartmentState.STA)]
public void Run_LoadingFromOutdatedAndMigrateThrowsArgumentException_LogErrorAndLoadDefaultProjectInstead()
{
// Setup
const string fileName = "SomeFile";
string testFile = $"{fileName}.rtd";
string targetFile = $"{fileName}_17_1.rtd";
const string expectedErrorMessage = "You shall not migrate!";
var mocks = new MockRepository();
var projectStore = mocks.Stub();
var projectMigrator = mocks.Stub();
projectMigrator.Stub(pm => pm.ShouldMigrate(testFile)).Return(MigrationRequired.Yes);
projectMigrator.Stub(pm => pm.DetermineMigrationLocation(testFile)).Return(targetFile);
projectMigrator.Stub(pm => pm.Migrate(testFile, targetFile))
.Throw(new ArgumentException(expectedErrorMessage));
const string expectedProjectName = "Project";
var project = mocks.Stub();
project.Name = expectedProjectName;
var projectFactory = mocks.Stub();
projectFactory.Stub(ph => ph.CreateNewProject()).Return(project);
mocks.ReplayAll();
var fixedSettings = new GuiCoreSettings
{
MainWindowTitle = ""
};
using (var mainWindow = new MainWindow())
using (var gui = new GuiCore(mainWindow, projectStore, projectMigrator, projectFactory, fixedSettings))
{
// Call
Action call = () => gui.Run(testFile);
// Assert
var expectedMessages = new[]
{
Tuple.Create("Openen van project is gestart.", LogLevelConstant.Info),
Tuple.Create(expectedErrorMessage, LogLevelConstant.Error),
Tuple.Create("Openen van project is mislukt.", LogLevelConstant.Error)
};
TestHelper.AssertLogMessagesWithLevelAreGenerated(call, expectedMessages);
Assert.IsNull(gui.ProjectFilePath);
string expectedTitle = $"{expectedProjectName} - {fixedSettings.MainWindowTitle} {SettingsHelper.Instance.ApplicationVersion}";
Assert.AreEqual(expectedTitle, mainWindow.Title);
}
mocks.VerifyAll();
}
[Test]
[Apartment(ApartmentState.STA)]
public void Run_LoadingFromFileThrowsStorageException_LogErrorAndLoadDefaultProjectInstead()
{
// Setup
const string fileName = "SomeFile";
string testFile = $"{fileName}.rtd";
const string storageExceptionText = "";
var mocks = new MockRepository();
var projectStore = mocks.Stub();
var projectMigrator = mocks.Stub();
projectMigrator.Stub(m => m.ShouldMigrate(testFile)).Return(MigrationRequired.No);
projectStore.Expect(ps => ps.LoadProject(testFile)).Throw(new StorageException(storageExceptionText));
const string expectedProjectName = "Project";
var project = mocks.Stub();
project.Name = expectedProjectName;
var projectFactory = mocks.Stub();
projectFactory.Stub(ph => ph.CreateNewProject()).Return(project);
mocks.ReplayAll();
var fixedSettings = new GuiCoreSettings
{
MainWindowTitle = ""
};
using (var mainWindow = new MainWindow())
using (var gui = new GuiCore(mainWindow, projectStore, projectMigrator, projectFactory, fixedSettings))
{
// Call
Action call = () => gui.Run(testFile);
// Assert
var expectedMessages = new[]
{
Tuple.Create("Openen van project is gestart.", LogLevelConstant.Info),
Tuple.Create(storageExceptionText, LogLevelConstant.Error),
Tuple.Create("Openen van project is mislukt.", LogLevelConstant.Error)
};
TestHelper.AssertLogMessagesWithLevelAreGenerated(call, expectedMessages);
Assert.IsNull(gui.ProjectFilePath);
string expectedTitle = $"{expectedProjectName} - {fixedSettings.MainWindowTitle} {SettingsHelper.Instance.ApplicationVersion}";
Assert.AreEqual(expectedTitle, mainWindow.Title);
}
mocks.VerifyAll();
}
[Test]
[TestCase("")]
[TestCase(" ")]
[TestCase(null)]
[Apartment(ApartmentState.STA)]
public void Run_WithoutFile_DefaultProjectStillSet(string path)
{
// Setup
var mocks = new MockRepository();
var projectStore = mocks.StrictMock();
var projectMigrator = mocks.Stub();
const string expectedProjectName = "Project";
var project = mocks.Stub();
project.Name = expectedProjectName;
var projectFactory = mocks.Stub();
projectFactory.Stub(ph => ph.CreateNewProject()).Return(project);
mocks.ReplayAll();
var fixedSettings = new GuiCoreSettings
{
MainWindowTitle = ""
};
using (var mainWindow = new MainWindow())
using (var gui = new GuiCore(mainWindow, projectStore, projectMigrator, projectFactory, fixedSettings))
{
// Call
gui.Run(path);
// Assert
Assert.IsNull(gui.ProjectFilePath);
Assert.AreSame(project, gui.Project);
string expectedTitle = $"{expectedProjectName} - {fixedSettings.MainWindowTitle} {SettingsHelper.Instance.ApplicationVersion}";
Assert.AreEqual(expectedTitle, mainWindow.Title);
}
mocks.VerifyAll();
}
[Test]
[Apartment(ApartmentState.STA)]
public void Run_WithPlugins_SetGuiAndActivatePlugins()
{
var mocks = new MockRepository();
var projectStore = mocks.Stub();
var projectMigrator = mocks.Stub();
var plugin = mocks.Stub();
plugin.Stub(p => p.Deactivate());
plugin.Stub(p => p.Dispose());
plugin.Expect(p => p.Activate());
plugin.Expect(p => p.GetViewInfos()).Return(Enumerable.Empty());
plugin.Expect(p => p.GetPropertyInfos()).Return(Enumerable.Empty());
IProjectFactory projectFactory = CreateProjectFactory(mocks);
mocks.ReplayAll();
// Setup
using (var gui = new GuiCore(new MainWindow(), projectStore, projectMigrator, projectFactory, new GuiCoreSettings()))
{
gui.Plugins.Add(plugin);
// Call
gui.Run();
// Assert
Assert.AreSame(gui, plugin.Gui);
}
mocks.VerifyAll();
}
[Test]
[Apartment(ApartmentState.STA)]
public void Run_WithPluginThatThrowsExceptionWhenActivated_DeactivateAndDisposePlugin()
{
var mocks = new MockRepository();
var projectStore = mocks.Stub();
var projectMigrator = mocks.Stub();
var plugin = mocks.Stub();
plugin.Stub(p => p.GetViewInfos()).Return(Enumerable.Empty());
plugin.Stub(p => p.GetPropertyInfos()).Return(Enumerable.Empty());
plugin.Stub(p => p.Activate()).Throw(new Exception("ERROR!"));
plugin.Expect(p => p.Deactivate());
plugin.Expect(p => p.Dispose());
IProjectFactory projectFactory = CreateProjectFactory(mocks);
mocks.ReplayAll();
// Setup
using (var gui = new GuiCore(new MainWindow(), projectStore, projectMigrator, projectFactory, new GuiCoreSettings()))
{
gui.Plugins.Add(plugin);
// Call
gui.Run();
}
// Assert
mocks.VerifyAll(); // Expect calls on plugin
}
[Test]
[Apartment(ApartmentState.STA)]
public void Run_WithPluginThatThrowsExceptionWhenActivatedAndDeactivated_LogErrorForDeactivatingThenDispose()
{
var mocks = new MockRepository();
var projectStore = mocks.Stub();
var projectMigrator = mocks.Stub();
var plugin = mocks.Stub();
plugin.Stub(p => p.GetViewInfos()).Return(Enumerable.Empty());
plugin.Stub(p => p.GetPropertyInfos()).Return(Enumerable.Empty());
plugin.Stub(p => p.Activate()).Throw(new Exception("ERROR!"));
plugin.Stub(p => p.Deactivate()).Throw(new Exception("MORE ERROR!"));
plugin.Expect(p => p.Dispose());
IProjectFactory projectFactory = CreateProjectFactory(mocks);
mocks.ReplayAll();
// Setup
using (var gui = new GuiCore(new MainWindow(), projectStore, projectMigrator, projectFactory, new GuiCoreSettings()))
{
gui.Plugins.Add(plugin);
// Call
Action call = () => gui.Run();
// Assert
const string expectedMessage = "Kritieke fout opgetreden tijdens deactivering van de grafische interface plugin.";
Tuple expectedMessageAndLogLevel = Tuple.Create(expectedMessage, LogLevelConstant.Error);
TestHelper.AssertLogMessageWithLevelIsGenerated(call, expectedMessageAndLogLevel);
}
mocks.VerifyAll(); // Expect Dispose call on plugin
}
[Test]
[Apartment(ApartmentState.STA)]
public void Run_InitializesViewController()
{
// Setup
var mocks = new MockRepository();
var projectStore = mocks.Stub();
var projectMigrator = mocks.Stub();
IProjectFactory projectFactory = CreateProjectFactory(mocks);
mocks.ReplayAll();
using (var gui = new GuiCore(new MainWindow(), projectStore, projectMigrator, projectFactory, new GuiCoreSettings()))
{
// Call
gui.Run();
// Assert
CollectionAssert.IsEmpty(gui.ViewHost.DocumentViews);
Assert.IsNull(gui.ViewHost.ActiveDocumentView);
Assert.AreEqual(2, gui.ViewHost.ToolViews.Count());
Assert.AreEqual(1, gui.ViewHost.ToolViews.Count(v => v is PropertyGridView));
Assert.AreEqual(1, gui.ViewHost.ToolViews.Count(v => v is MessageWindow));
Assert.IsNotNull(gui.DocumentViewController);
CollectionAssert.IsEmpty(gui.DocumentViewController.DefaultViewTypes);
}
mocks.VerifyAll();
}
[Test]
[Apartment(ApartmentState.STA)]
public void GetAllDataWithViewDefinitionsRecursively_DataHasNoViewDefinitions_ReturnEmpty()
{
// Setup
var mocks = new MockRepository();
var projectStore = mocks.Stub();
var projectMigrator = mocks.Stub();
IProjectFactory projectFactory = CreateProjectFactory(mocks);
mocks.ReplayAll();
using (var gui = new GuiCore(new MainWindow(), projectStore, projectMigrator, projectFactory, new GuiCoreSettings()))
{
var rootData = new object();
// Call
IEnumerable dataInstancesWithViewDefinitions = gui.GetAllDataWithViewDefinitionsRecursively(rootData);
// Assert
CollectionAssert.IsEmpty(dataInstancesWithViewDefinitions);
}
mocks.VerifyAll();
}
[Test]
[Apartment(ApartmentState.STA)]
public void GetAllDataWithViewDefinitionsRecursively_MultiplePluginsHaveViewDefinitionsForRoot_ReturnRootObject()
{
// Setup
var rootData = new object();
var mocks = new MockRepository();
var projectStore = mocks.Stub();
var projectMigrator = mocks.Stub();
var plugin1 = mocks.StrictMock();
plugin1.Expect(p => p.GetChildDataWithViewDefinitions(rootData))
.Return(new[]
{
rootData
});
plugin1.Stub(p => p.Dispose());
plugin1.Stub(p => p.Deactivate());
var plugin2 = mocks.StrictMock();
plugin2.Expect(p => p.GetChildDataWithViewDefinitions(rootData))
.Return(new[]
{
rootData
});
plugin2.Stub(p => p.Dispose());
plugin2.Stub(p => p.Deactivate());
IProjectFactory projectFactory = CreateProjectFactory(mocks);
mocks.ReplayAll();
using (var gui = new GuiCore(new MainWindow(), projectStore, projectMigrator, projectFactory, new GuiCoreSettings()))
{
gui.Plugins.Add(plugin1);
gui.Plugins.Add(plugin2);
// Call
object[] dataInstancesWithViewDefinitions = gui.GetAllDataWithViewDefinitionsRecursively(rootData).OfType