#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