#region CPL License /* Nuclex Framework Copyright (C) 2002-2010 Nuclex Development Labs This library is free software; you can redistribute it and/or modify it under the terms of the IBM Common Public License as published by the IBM Corporation; either version 1.0 of the License, or (at your option) any later version. This library 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 IBM Common Public License for more details. You should have received a copy of the IBM Common Public License along with this library */ #endregion #if UNITTEST using System; using System.Collections.Generic; using System.Globalization; using System.IO; using Microsoft.Xna.Framework; using Microsoft.Xna.Framework.Graphics; using NUnit.Framework; using Nuclex.Testing.Xna; using Nuclex.UserInterface.Controls; namespace Nuclex.UserInterface.Visuals.Flat { /// Unit tests for flat GUI visualizer [TestFixture] internal class FlatGuiVisualizerTest { #region class ResourceFileKeeper /// /// Temporarily extracts the unit test resources to the local file system /// private class ResourceFileKeeper : IDisposable { /// Initializes a new resource file keeper public ResourceFileKeeper() { this.tempFile = Path.GetTempFileName(); try { string tempPath = this.tempFile + ".dir"; Directory.CreateDirectory(tempPath); this.tempPath = tempPath; extractResource(Resources.UnitTestResources.UnitTestSkin, "UnitTest.skin.xml"); extractResource(Resources.UnitTestResources.BadColorSkin, "BadColor.skin.xml"); extractResource(Resources.UnitTestResources.UnitTestFont, "UnitTestFont.xnb"); } catch(Exception) { Dispose(); throw; } } /// Immediately releases all resources owned by the instance public void Dispose() { if(this.tempPath != null) { File.Delete(Path.Combine(this.tempPath, "UnitTest.skin.xml")); File.Delete(Path.Combine(this.tempPath, "BadColor.skin.xml")); File.Delete(Path.Combine(this.tempPath, "UnitTestFont.xnb")); Directory.Delete(this.tempPath); this.tempPath = null; } if(this.tempFile != null) { File.Delete(this.tempFile); this.tempFile = null; } } /// Directory into which the resources were extracted public string ResourcePath { get { return this.tempPath; } } /// Extracts the specified resource to the provided file /// Resource that will be extracted /// File to which the resource will be written private void extractResource(byte[] resource, string file) { using( FileStream stream = new FileStream( Path.Combine(this.tempPath, file), FileMode.Create, FileAccess.Write, FileShare.None ) ) { stream.Write(resource, 0, resource.Length); } } /// /// Temporary file created by the OS and kept around until the instance is /// disposed to occupy the temp file name /// private string tempFile; /// /// Path to the temporary directory the resources are extracted into /// private string tempPath; } #endregion // classs ResourceFileKeeper #region class NonRenderableControl /// Control for which no renderer exists private class NonRenderableControl : Controls.Control { } #endregion // class NonRenderableControl #region class NotAControlRenderer /// Dummy class that is not a control renderer private class NotAControlRenderer : IFlatControlRenderer { } #endregion // class NotAControlRenderer #region class LabelControlRenderer1 /// First of two ambiguous renderers for the label control private class LabelControlRenderer1 : IFlatControlRenderer { public void Render(LabelControl control, IFlatGuiGraphics graphics) { } } #endregion // class LabelControlRenderer1 #region class LabelControlRenderer2 /// Second of two ambiguous renderers for the label control private class LabelControlRenderer2 : IFlatControlRenderer { public void Render(LabelControl control, IFlatGuiGraphics graphics) { } } #endregion // class LabelControlRenderer2 #region MultiInterfaceControlRenderer /// Control renderer which implements multiple interfaces private class MultiInterfaceControlRenderer : IFlatControlRenderer, IDisposable { public void Render(LabelControl control, IFlatGuiGraphics graphics) { } public void Dispose() { } } #endregion // class MultiInterfaceControlRenderer #region class NonConstructableRenderer /// Control renderer which cannot be constructed publicly private class NonConstructableRenderer : IFlatControlRenderer { private NonConstructableRenderer() { } public void Render(LabelControl control, IFlatGuiGraphics graphics) { } } #endregion // class NonConstrutableRenderer /// Called before each test is run [SetUp] public void Setup() { this.mockedGraphicsDeviceService = new MockedGraphicsDeviceService( DeviceType.Reference ); this.mockedGraphicsDeviceService.CreateDevice(); } /// Called after each test has run [TearDown] public void Teardown() { if(this.mockedGraphicsDeviceService != null) { this.mockedGraphicsDeviceService.DestroyDevice(); this.mockedGraphicsDeviceService = null; } } /// /// Verifies that a flat GUI visualizer can be constructed from a file /// [Test] public void TestConstructFromFile() { using(ResourceFileKeeper keeper = new ResourceFileKeeper()) { using( FlatGuiVisualizer visualizer = FlatGuiVisualizer.FromFile( this.mockedGraphicsDeviceService.ServiceProvider, Path.Combine(keeper.ResourcePath, "UnitTest.skin.xml") ) ) { Assert.IsNotNull(visualizer); // nonsense to avoid compiler warning } } } /// /// Verifies that a flat GUI visualizer can handle exceptions during loading /// from a file /// [Test] public void TestThrowOnConstructFromBrokenFile() { using(ResourceFileKeeper keeper = new ResourceFileKeeper()) { Assert.Throws( delegate() { using( FlatGuiVisualizer visualizer = FlatGuiVisualizer.FromFile( this.mockedGraphicsDeviceService.ServiceProvider, Path.Combine(keeper.ResourcePath, "BadColor.skin.xml") ) ) { } } ); } } /// /// Verifies that a flat GUI visualizer can be constructed from a resource /// [Test] public void TestConstructFromResource() { using( FlatGuiVisualizer visualizer = FlatGuiVisualizer.FromResource( this.mockedGraphicsDeviceService.ServiceProvider, Resources.UnitTestResources.ResourceManager, "UnitTestSkin" ) ) { Assert.IsNotNull(visualizer); // nonsense to avoid compiler warning } } /// /// Verifies that a flat GUI visualizer can handle exceptions when attempting /// to load a non-existing resource /// [Test] public void TestThrowOnConstructFromNonExistingResource() { Assert.Throws( delegate() { using( FlatGuiVisualizer visualizer = FlatGuiVisualizer.FromResource( this.mockedGraphicsDeviceService.ServiceProvider, Resources.UnitTestResources.ResourceManager, "DoesnExistSkin" ) ) { } } ); } /// /// Verifies that a flat GUI visualizer can handle exceptions during loading /// from a resource containing a broken skin description /// [Test] public void TestThrowOnConstructFromBrokenResource() { Assert.Throws( delegate() { using( FlatGuiVisualizer visualizer = FlatGuiVisualizer.FromResource( this.mockedGraphicsDeviceService.ServiceProvider, Resources.UnitTestResources.ResourceManager, "BadColorSkin" ) ) { } } ); } /// /// Verifies that a flat GUI visualizer can handle exceptions during loading /// from a resource containing a broken skin description /// [Test] public void TestDraw() { using( FlatGuiVisualizer visualizer = FlatGuiVisualizer.FromResource( this.mockedGraphicsDeviceService.ServiceProvider, Resources.UnitTestResources.ResourceManager, "UnitTestSkin" ) ) { Screen screen = new Screen(800, 600); screen.Desktop.Children.Add(new Controls.Control()); screen.Desktop.Children.Add(new Controls.LabelControl()); visualizer.Draw(screen); } } /// /// Tests whether the visualizer can cope with a non-renderable control /// [Test] public void TestDrawNonRenderableControl() { using( FlatGuiVisualizer visualizer = FlatGuiVisualizer.FromResource( this.mockedGraphicsDeviceService.ServiceProvider, Resources.UnitTestResources.ResourceManager, "UnitTestSkin" ) ) { Screen screen = new Screen(800, 600); screen.Desktop.Children.Add(new NonRenderableControl()); visualizer.Draw(screen); } } /// /// Tests whether the visualizer can cope with a non-renderable control /// [Test] public void TestEmployAmbiguousRenderers() { FlatGuiVisualizer.ControlRendererEmployer employer = new FlatGuiVisualizer.ControlRendererEmployer(); employer.Employ(typeof(LabelControlRenderer1)); employer.Employ(typeof(LabelControlRenderer2)); } /// /// Tests whether the visualizer can cope with a non-renderable control /// [Test] public void TestCannotEmployNonRendererType() { FlatGuiVisualizer.ControlRendererEmployer employer = new FlatGuiVisualizer.ControlRendererEmployer(); Assert.IsFalse(employer.CanEmploy(typeof(NotAControlRenderer))); } /// /// Tests whether the visualizer can cope with a non-renderable control /// [Test] public void TestCannotEmployNonConstructableRenderer() { FlatGuiVisualizer.ControlRendererEmployer employer = new FlatGuiVisualizer.ControlRendererEmployer(); Assert.IsFalse(employer.CanEmploy(typeof(NonConstructableRenderer))); } /// /// Verifies that the visualizer's control renderer repository can be accessed /// [Test] public void TestAccessControlRepository() { using( FlatGuiVisualizer visualizer = FlatGuiVisualizer.FromResource( this.mockedGraphicsDeviceService.ServiceProvider, Resources.UnitTestResources.ResourceManager, "UnitTestSkin" ) ) { // The visualizer should have added its own assembly to the list automatically Assert.AreEqual(1, visualizer.RendererRepository.LoadedAssemblies.Count); } } /// Mocked graphics device used for running the unit tests private MockedGraphicsDeviceService mockedGraphicsDeviceService; } } // namespace Nuclex.UserInterface.Visuals.Flat #endif // UNITTEST