#region CPL License
/*
Nuclex Framework
Copyright (C) 2002-2008 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
using System;
using System.IO;
#if UNITTEST
using NUnit.Framework;
using NUnit.Framework.SyntaxHelpers;
namespace Nuclex.Support.Plugins {
  /// Unit Test for the factory employer class
  [TestFixture]
  public class FactoryEmployerTest {
    #region class Base
    /// 
    ///   Abstract base class to serve as abstract product for testing the factory employer
    /// 
    private abstract class Base { }
    #endregion // class Base
    #region class Derived
    /// 
    ///   Class derived from the abstract base to serve as concrete product for
    ///   testing the factory employer
    /// 
    private class Derived : Base { }
    #endregion // class Derived
    #region class Unrelated
    /// Unrelated class used to test the factory employer
    private class Unrelated { }
    #endregion // class Unrelated
    /// 
    ///   Tests whether the factory employer can detect employable types
    /// 
    [Test]
    public void TestCanEmploy() {
      FactoryEmployer testEmployer = new FactoryEmployer();
      Assert.IsFalse(testEmployer.CanEmploy(typeof(Base)));
      Assert.IsTrue(testEmployer.CanEmploy(typeof(Derived)));
      Assert.IsFalse(testEmployer.CanEmploy(typeof(Unrelated)));
    }
    /// 
    ///   Tests whether the factory employer throws an exception when it is asked to
    ///   employ an abstract class
    /// 
    [Test, ExpectedException(typeof(MissingMethodException))]
    public void TestThrowOnEmployAbstractClass() {
      FactoryEmployer testEmployer = new FactoryEmployer();
      testEmployer.Employ(typeof(Base));
    }
    /// 
    ///   Tests whether the factory employer throws an exception when it is asked to
    ///   employ a class that is not the product type or a derivative thereof
    /// 
    [Test, ExpectedException(typeof(InvalidCastException))]
    public void TestThrowOnEmployUnrelatedClass() {
      FactoryEmployer testEmployer = new FactoryEmployer();
      testEmployer.Employ(typeof(Unrelated));
    }
    /// 
    ///   Tests whether the factory employer can employ a class derived from the product
    /// 
    [Test]
    public void TestEmployClassDerivedFromProduct() {
      FactoryEmployer testEmployer = new FactoryEmployer();
      testEmployer.Employ(typeof(Derived));
      Assert.AreEqual(1, testEmployer.Factories.Count);
      Assert.AreEqual(typeof(Derived), testEmployer.Factories[0].ConcreteType);
      Assert.IsInstanceOfType(
        typeof(Derived), testEmployer.Factories[0].CreateInstance()
      );
    }
    /// 
    ///   Tests whether the factory employer can employ the product class itself if it
    ///   isn't abstract
    /// 
    [Test]
    public void TestEmployProduct() {
      FactoryEmployer testEmployer = new FactoryEmployer();
      testEmployer.Employ(typeof(Unrelated));
      Assert.AreEqual(1, testEmployer.Factories.Count);
      Assert.AreEqual(typeof(Unrelated), testEmployer.Factories[0].ConcreteType);
      Assert.IsInstanceOfType(
        typeof(Unrelated), testEmployer.Factories[0].CreateInstance()
      );
    }
  }
} // namespace Nuclex.Support.Plugins
#endif // UNITTEST