#region CPL License
/*
Nuclex Framework
Copyright (C) 2002-2014 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.Collections.Generic;
#if UNITTEST
using NUnit.Framework;
using NMock;
namespace Nuclex.Support.Collections {
  /// Unit Test for the observable list class
  [TestFixture]
  internal class ObservableListTest {
    #region interface IObservableCollectionSubscriber
    /// Interface used to test the observable collection
    public interface IObservableCollectionSubscriber {
      /// Called when the collection is about to clear its contents
      /// Collection that is clearing its contents
      /// Not used
      void Clearing(object sender, EventArgs arguments);
      /// Called when the collection has been cleared of its contents
      /// Collection that was cleared of its contents
      /// Not used
      void Cleared(object sender, EventArgs arguments);
      /// Called when an item is added to the collection
      /// Collection to which an item is being added
      /// Contains the item that is being added
      void ItemAdded(object sender, ItemEventArgs arguments);
      /// Called when an item is removed from the collection
      /// Collection from which an item is being removed
      /// Contains the item that is being removed
      void ItemRemoved(object sender, ItemEventArgs arguments);
      /// Called when an item is replaced in the dictionary
      /// Dictionary in which an item is being replaced
      /// Contains the replaced item and its replacement
      void ItemReplaced(object sender, ItemReplaceEventArgs arguments);
    }
    #endregion // interface IObservableCollectionSubscriber
    /// Initialization routine executed before each test is run
    [SetUp]
    public void Setup() {
      this.mockery = new MockFactory();
      this.mockedSubscriber = this.mockery.CreateMock();
      this.observedList = new ObservableList();
      this.observedList.Clearing += new EventHandler(
        this.mockedSubscriber.MockObject.Clearing
      );
      this.observedList.Cleared += new EventHandler(
        this.mockedSubscriber.MockObject.Cleared
      );
      this.observedList.ItemAdded += new EventHandler>(
        this.mockedSubscriber.MockObject.ItemAdded
      );
      this.observedList.ItemRemoved += new EventHandler>(
        this.mockedSubscriber.MockObject.ItemRemoved
      );
      this.observedList.ItemReplaced += new EventHandler>(
        this.mockedSubscriber.MockObject.ItemReplaced
      );
    }
    /// Tests whether the Clearing event is fired
    [Test]
    public void TestClearingEvent() {
      this.mockedSubscriber.Expects.One.Method(m => m.Clearing(null, null)).WithAnyArguments();
      this.mockedSubscriber.Expects.One.Method(m => m.Cleared(null, null)).WithAnyArguments();
      this.observedList.Clear();
      this.mockery.VerifyAllExpectationsHaveBeenMet();
    }
    /// Tests whether the ItemAdded event is fired
    [Test]
    public void TestItemAddedEvent() {
      this.mockedSubscriber.Expects.One.Method(m => m.ItemAdded(null, null)).WithAnyArguments();
      this.observedList.Add(123);
      this.mockery.VerifyAllExpectationsHaveBeenMet();
    }
    /// Tests whether the ItemRemoved event is fired
    [Test]
    public void TestItemRemovedEvent() {
      this.mockedSubscriber.Expects.One.Method(m => m.ItemAdded(null, null)).WithAnyArguments();
      this.observedList.Add(123);
      this.mockedSubscriber.Expects.One.Method(m => m.ItemRemoved(null, null)).WithAnyArguments();
      this.observedList.Remove(123);
      this.mockery.VerifyAllExpectationsHaveBeenMet();
    }
    /// Tests whether items in the collection can be replaced
    [Test]
    public void TestItemReplacement() {
      this.mockedSubscriber.Expects.Exactly(3).Method(
        m => m.ItemAdded(null, null)
      ).WithAnyArguments();
      this.observedList.Add(1);
      this.observedList.Add(2);
      this.observedList.Add(3);
      this.mockedSubscriber.Expects.One.Method(m => m.ItemReplaced(null, null)).WithAnyArguments();
      // Replace the middle item with something else
      this.observedList[1] = 4;
      Assert.AreEqual(
        1, this.observedList.IndexOf(4)
      );
      this.mockery.VerifyAllExpectationsHaveBeenMet();
    }
    /// Tests whether a the list constructor is working
    [Test]
    public void TestListConstructor() {
      int[] integers = new int[] { 12, 34, 56, 78 };
      var testList = new ObservableList(integers);
      CollectionAssert.AreEqual(integers, testList);
    }
    /// Mock object factory
    private MockFactory mockery;
    /// The mocked observable collection subscriber
    private Mock mockedSubscriber;
    /// An observable collection to which a mock will be subscribed
    private ObservableList observedList;
  }
} // namespace Nuclex.Support.Collections
#endif // UNITTEST