#region CPL License /* Nuclex Framework Copyright (C) 2002-2009 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; using System.Collections.Generic; using Microsoft.Xna.Framework; using Microsoft.Xna.Framework.Graphics; using NUnit.Framework; namespace Nuclex.Graphics.SpecialEffects.Particles { /// Unit tests for the affector collection [TestFixture] internal class AffectorCollectionTest { #region class CoalescableAffector /// A dummy particle affector that can be coalesced private class CoalescableAffector : IParticleAffector { /// /// Whether the affector can do multiple updates in a single step without /// changing the outcome of the simulation /// public bool IsCoalescable { get { return true; } } /// Applies the affector's effect to a series of particles /// Particles the affector will be applied to /// Index of the first particle that will be affected /// Number of particles that will be affected /// Number of updates to perform in the affector public void Affect(int[] particles, int start, int count, int updates) { } } #endregion // class CoalescableAffector #region class NoncoalescableAffector /// A dummy particle affector that can not be coalesced private class NoncoalescableAffector : IParticleAffector { /// /// Whether the affector can do multiple updates in a single step without /// changing the outcome of the simulation /// public bool IsCoalescable { get { return false; } } /// Applies the affector's effect to a series of particles /// Particles the affector will be applied to /// Index of the first particle that will be affected /// Number of particles that will be affected /// Number of updates to perform in the affector public void Affect(int[] particles, int start, int count, int updates) { } } #endregion // class NoncoalescableAffector /// Unit test for the affector collection's enumerator [TestFixture] public class EnumeratorTest { /// /// Tests whether an exception is thrown if the 'Current' property is called /// with the enumerator at an invalid location /// [Test] public void TestThrowOnCurrentFromInvalidPosition() { AffectorCollection affectors = new AffectorCollection(); using( IEnumerator> enumerator = affectors.GetEnumerator() ) { Assert.Throws( delegate() { Assert.AreNotEqual(enumerator.Current, enumerator.Current); } ); } } /// /// Verifies that the enumerator behaves correctly if it is advanced /// past its end /// [Test] public void TestAdvanceEnumeratorPastEnd() { AffectorCollection affectors = new AffectorCollection(); affectors.Add(new CoalescableAffector()); affectors.Add(new NoncoalescableAffector()); using( IEnumerator> enumerator = affectors.GetEnumerator() ) { Assert.IsTrue(enumerator.MoveNext()); Assert.IsTrue(enumerator.MoveNext()); Assert.IsFalse(enumerator.MoveNext()); Assert.IsFalse(enumerator.MoveNext()); Assert.IsFalse(enumerator.MoveNext()); } } /// /// Verifies that the affectors can be retrieved through the enumerator /// [Test] public void TestCurrent() { NoncoalescableAffector affector = new NoncoalescableAffector(); AffectorCollection affectors = new AffectorCollection(); affectors.Add(affector); using( IEnumerator> enumerator = affectors.GetEnumerator() ) { Assert.IsTrue(enumerator.MoveNext()); Assert.AreSame(affector, enumerator.Current); Assert.IsFalse(enumerator.MoveNext()); } } /// /// Verifies that the affectors can be retrieved through the enumerator /// through a non-typesafe IEnumerator interface /// [Test] public void TestCurrentAsObject() { NoncoalescableAffector affector = new NoncoalescableAffector(); AffectorCollection affectors = new AffectorCollection(); affectors.Add(affector); IEnumerator enumerator = (affectors as ICollection).GetEnumerator(); Assert.IsTrue(enumerator.MoveNext()); Assert.AreSame(affector, enumerator.Current); Assert.IsFalse(enumerator.MoveNext()); } /// /// Verifies that the affectors can be retrieved through the enumerator /// [Test] public void TestReset() { AffectorCollection affectors = new AffectorCollection(); affectors.Add(new CoalescableAffector()); using( IEnumerator> enumerator = affectors.GetEnumerator() ) { Assert.IsTrue(enumerator.MoveNext()); Assert.IsFalse(enumerator.MoveNext()); enumerator.Reset(); Assert.IsTrue(enumerator.MoveNext()); Assert.IsFalse(enumerator.MoveNext()); } } } /// /// Verifies that the constructor of the affector collection is working /// [Test] public void TestConstructor() { AffectorCollection affectors = new AffectorCollection(); Assert.IsNotNull(affectors); // nonsense; prevents compiler warning } /// /// Verifies that the Add() method splits affectors in coalescable and /// non-coalescable affectors /// [Test] public void TestAdd() { AffectorCollection affectors = new AffectorCollection(); affectors.Add(new CoalescableAffector()); affectors.Add(new NoncoalescableAffector()); Assert.AreEqual(2, affectors.Count); Assert.AreEqual(1, affectors.CoalescableAffectors.Count); Assert.AreEqual(1, affectors.NoncoalescableAffectors.Count); } /// /// Tests whether the Remove() method correctly removes affectors from /// the internal lists of coalescable and non-coalescable affectors. /// [Test] public void TestRemove() { CoalescableAffector coalescable = new CoalescableAffector(); NoncoalescableAffector noncoalescable = new NoncoalescableAffector(); AffectorCollection affectors = new AffectorCollection(); affectors.Add(coalescable); affectors.Add(noncoalescable); Assert.IsTrue(affectors.Remove(coalescable)); Assert.IsFalse(affectors.Remove(coalescable)); Assert.IsTrue(affectors.Remove(noncoalescable)); Assert.IsFalse(affectors.Remove(noncoalescable)); } /// Verifies that the affector collection is not read-only [Test] public void TestIsReadOnly() { AffectorCollection affectors = new AffectorCollection(); Assert.IsFalse(affectors.IsReadOnly); } /// /// Tests whether the Contains() method of the affector collection is /// working correctly /// [Test] public void TestContains() { CoalescableAffector coalescable = new CoalescableAffector(); NoncoalescableAffector noncoalescable = new NoncoalescableAffector(); AffectorCollection affectors = new AffectorCollection(); affectors.Add(coalescable); affectors.Add(noncoalescable); Assert.IsTrue(affectors.Contains(coalescable)); Assert.IsFalse(affectors.Contains(new CoalescableAffector())); Assert.IsTrue(affectors.Contains(noncoalescable)); Assert.IsFalse(affectors.Contains(new NoncoalescableAffector())); } /// /// Verifies that the typesafe CopyTo() method is working correctly /// [Test] public void TestCopyTo() { CoalescableAffector coalescable = new CoalescableAffector(); NoncoalescableAffector noncoalescable = new NoncoalescableAffector(); AffectorCollection affectors = new AffectorCollection(); affectors.Add(coalescable); affectors.Add(noncoalescable); IParticleAffector[] array = new IParticleAffector[3]; affectors.CopyTo(array, 1); Assert.IsNull(array[0]); Assert.Contains(coalescable, array); Assert.Contains(noncoalescable, array); } /// /// Verifies that the typesafe CopyTo() method is working correctly /// [Test] public void TestThrowOnCopyTo() { CoalescableAffector coalescable = new CoalescableAffector(); NoncoalescableAffector noncoalescable = new NoncoalescableAffector(); AffectorCollection affectors = new AffectorCollection(); affectors.Add(coalescable); affectors.Add(noncoalescable); IParticleAffector[] array = new IParticleAffector[3]; Assert.Throws( delegate() { affectors.CopyTo(array, 2); } ); } /// /// Verifies that the non-typesafe CopyTo() method is working correctly /// [Test] public void TestCopyToAsObject() { CoalescableAffector coalescable = new CoalescableAffector(); NoncoalescableAffector noncoalescable = new NoncoalescableAffector(); AffectorCollection affectors = new AffectorCollection(); affectors.Add(coalescable); affectors.Add(noncoalescable); object[] array = new object[3]; (affectors as ICollection).CopyTo(array, 1); Assert.IsNull(array[0]); Assert.Contains(coalescable, array); Assert.Contains(noncoalescable, array); } /// /// Verifies that the typesafe CopyTo() method is working correctly /// [Test] public void TestThrowOnCopyToAsObject() { CoalescableAffector coalescable = new CoalescableAffector(); NoncoalescableAffector noncoalescable = new NoncoalescableAffector(); AffectorCollection affectors = new AffectorCollection(); affectors.Add(coalescable); affectors.Add(noncoalescable); object[] array = new object[3]; Assert.Throws( delegate() { (affectors as ICollection).CopyTo(array, 2); } ); } /// whether the collection can clear its contents [Test] public void TestClear() { AffectorCollection affectors = new AffectorCollection(); affectors.Add(new CoalescableAffector()); affectors.Add(new NoncoalescableAffector()); affectors.Clear(); Assert.AreEqual(0, affectors.Count); Assert.AreEqual(0, affectors.CoalescableAffectors.Count); Assert.AreEqual(0, affectors.NoncoalescableAffectors.Count); } /// /// Tests whether the SyncRoot property returns a lockable object /// [Test] public void TestSyncRoot() { AffectorCollection affectors = new AffectorCollection(); lock((affectors as ICollection).SyncRoot) { } } /// /// Tests whether the IsSynchronized property returns the right result /// [Test] public void TestIsSynchronized() { AffectorCollection affectors = new AffectorCollection(); Assert.IsFalse((affectors as ICollection).IsSynchronized); } /// /// Tests whether a typesafe enumerator can be obtained for the collection /// [Test] public void TestGetEnumerator() { AffectorCollection affectors = new AffectorCollection(); using(IEnumerator> enumerator = affectors.GetEnumerator()) { Assert.IsNotNull(enumerator); Assert.IsFalse(enumerator.MoveNext()); } } /// /// Tests whether a non-typesafe enumerator can be obtained for the collection /// [Test] public void TestGetEnumeratorForObject() { AffectorCollection affectors = new AffectorCollection(); IEnumerator enumerator = (affectors as ICollection).GetEnumerator(); Assert.IsNotNull(enumerator); Assert.IsFalse(enumerator.MoveNext()); } } } // namespace Nuclex.Graphics.SpecialEffects.Particles #endif // UNITTEST