view API/Objects/Requirement/UnitRequiresNParentModelsForMUnitsRequirementTests.cs @ 235:d122354eeebc

Re #410: N per M models in parent requirement * Add tests for adding * Change text on adding to make more sense (tell users N, M, and how many there are now)
author IBBoard <dev@ibboard.co.uk>
date Wed, 01 Aug 2012 21:01:43 +0100
parents 99248d05ba9c
children
line wrap: on
line source

// This file (UnitRequiresNoMoreThanNUnitsPerMModelsInParentUnitRequirementTests.cs) is a part of the IBBoard.WarFoundry.API.Tests project and is copyright 2012 IBBoard
//
// The file and the library/program it is in are licensed and distributed, without warranty, under the GNU Affero GPL license, either version 3 of the License or (at your option) any later version. Please see COPYING for more information and the full license.
using System;
using NUnit.Framework;
using NUnit.Framework.SyntaxHelpers;
using IBBoard.WarFoundry.API.Objects.Requirement.Context;
using System.Collections.Generic;

namespace IBBoard.WarFoundry.API.Objects.Requirement
{
	[TestFixture()]
	public class UnitRequiresNParentModelsForMUnitsRequirementTests: AbstractUnitTypeUnitRequirementTest<UnitType, UnitRequiresNParentModelsForMUnitsRequirement>
	{
		[Test()]
		public void TestAddingUnitTypeWithNoParentAndOneUnitTypeRequiredIsAllowed()
		{
			Army army = new Army(mockRace, "Test", 1000);
			UnitRequiresNParentModelsForMUnitsRequirement req = new UnitRequiresNParentModelsForMUnitsRequirement(unitType1);
			req.AddUnitTypeRequirement(unitType2);
			Assert_That__AddingNotApplicable(req, unitType1, army);
		}
		
		[Test()]
		public void TestAddingUnitTypeWithParentAndOneUnitTypeRequiredIsAllowed()
		{
			Army army = new Army(mockRace, "Test", 1000);
			Unit parent = AddUnitOfTypeToArmy(unitType2, army);
			UnitRequiresNParentModelsForMUnitsRequirement req = new UnitRequiresNParentModelsForMUnitsRequirement(unitType1);
			req.AddUnitTypeRequirement(unitType2);
			Assert_That__PassesAdding(req, unitType1, parent, army);
		}
		
		[Test()]
		public void TestAddingUnitTypeWithParentAndTwoForOneIsAllowed()
		{
			Army army = new Army(mockRace, "Test", 1000);
			Unit parent = AddUnitOfTypeToArmy(unitType2, army);
			UnitRequiresNParentModelsForMUnitsRequirement req = new UnitRequiresNParentModelsForMUnitsRequirement(unitType1);
			req.AddUnitTypeRequirement(unitType2, 2);
			AddUnitOfTypeToArmy(unitType1, army, parent);
			Assert_That__PassesAdding(req, unitType1, parent, army);
		}
		
		[Test()]
		public void TestAddingUnitTypeWithParentAndOneForTwoIsAllowed()
		{
			Army army = new Army(mockRace, "Test", 1000);
			Unit parent = AddUnitOfTypeToArmy(unitType2, army);
			parent.Size = 2;
			UnitRequiresNParentModelsForMUnitsRequirement req = new UnitRequiresNParentModelsForMUnitsRequirement(unitType1);
			req.AddUnitTypeRequirement(unitType2, 1, 2);
			Assert_That__PassesAdding(req, unitType1, parent, army);
		}
		
		[Test()]
		public void TestAddingUnitTypeWithWrongParentAndOneUnitTypeRequiredIsNotApplicable()
		{
			Army army = new Army(mockRace, "Test", 1000);
			Unit parent = AddUnitOfTypeToArmy(unitType2, army);
			UnitRequiresNParentModelsForMUnitsRequirement req = new UnitRequiresNParentModelsForMUnitsRequirement(unitType1);
			req.AddUnitTypeRequirement(unitType3);
			Assert_That__AddingNotApplicable(req, unitType1, parent, army);
		}
		
		[Test()]
		public void TestAddingTooManyUnitTypesWithParentAndOneUnitTypeRequiredFails()
		{
			Army army = new Army(mockRace, "Test", 1000);
			Unit parent = AddUnitOfTypeToArmy(unitType3, army);
			AddUnitOfTypeToArmy(unitType1, army, parent);
			UnitRequiresNParentModelsForMUnitsRequirement req = new UnitRequiresNParentModelsForMUnitsRequirement(unitType1);
			req.AddUnitTypeRequirement(unitType3);
			string msg = String.Format("Units of type {0} can only have {1} x {2} for every {3} models, would have {4} for {5}", unitType3.Name, 1, unitType1.Name, 1, 2, 1);
			Assert_That__FailsAdding(req, unitType1, parent, army, msg);
		}
		
		[Test()]
		public void TestAddingTooManyUnitTypesWithParentAndTwoForOneFails()
		{
			Army army = new Army(mockRace, "Test", 1000);
			Unit parent = AddUnitOfTypeToArmy(unitType3, army);
			AddUnitOfTypeToArmy(unitType1, army, parent);
			AddUnitOfTypeToArmy(unitType1, army, parent);
			UnitRequiresNParentModelsForMUnitsRequirement req = new UnitRequiresNParentModelsForMUnitsRequirement(unitType1);
			req.AddUnitTypeRequirement(unitType3, 2);
			string msg = String.Format("Units of type {0} can only have {1} x {2} for every {3} models, would have {4} for {5}", unitType3.Name, 2, unitType1.Name, 1, 3, 1);
			Assert_That__FailsAdding(req, unitType1, parent, army, msg);
		}
		
		[Test()]
		public void TestAddingTooManyUnitTypesWithParentAndOneForTwoFails()
		{
			Army army = new Army(mockRace, "Test", 1000);
			Unit parent = AddUnitOfTypeToArmy(unitType3, army);
			parent.Size = 2;
			AddUnitOfTypeToArmy(unitType1, army, parent);
			UnitRequiresNParentModelsForMUnitsRequirement req = new UnitRequiresNParentModelsForMUnitsRequirement(unitType1);
			req.AddUnitTypeRequirement(unitType3, 1, 2);
			string msg = String.Format("Units of type {0} can only have {1} x {2} for every {3} models, would have {4} for {5}", unitType3.Name, 1, unitType1.Name, 2, 2, 2);
			Assert_That__FailsAdding(req, unitType1, parent, army, msg);
		}
		
		[Test()]
		public void TestAddingTooManyUnitTypesWithParentAndFiveUnitTypeRequiredFails()
		{
			Army army = new Army(mockRace, "Test", 1000);
			Unit parent = AddUnitOfTypeToArmy(unitType2, army);
			AddUnitsOfTypeToArmy(5, unitType1, army, parent);
			UnitRequiresNParentModelsForMUnitsRequirement req = new UnitRequiresNParentModelsForMUnitsRequirement(unitType1);
			req.AddUnitTypeRequirement(unitType2);
			string msg = String.Format("Units of type {0} can only have {1} x {2} for every {3} models, would have {4} for {5}", unitType2.Name, 1, unitType1.Name, 1, 6, 5);
			Assert_That__FailsAdding(req, unitType1, parent, army, msg);
		}
		
		[Test()]
		public void TestAddingTooManyUnitsAtThreshold()
		{
			Army army = new Army(mockRace, "Test", 1000);
			Unit parent = AddUnitOfTypeToArmy(unitType2, army);
			AddUnitsOfTypeToArmy(4, unitType1, army, parent);
			UnitRequiresNParentModelsForMUnitsRequirement req = new UnitRequiresNParentModelsForMUnitsRequirement(unitType1);
			req.AddUnitTypeRequirement(unitType2);
			Assert_That__PassesAdding(req, unitType1, parent, army);
			AddUnitOfTypeToArmy(unitType1, army, parent);
			string msg = String.Format("Units of type {0} can only have {1} x {2} for every {3} models, would have {4} for {5}", unitType2.Name, 1, unitType1.Name, 1, 6, 5);
			Assert_That__FailsAdding(req, unitType1, parent, army, msg);
		}

		[Test()]
		public void TestValidatingUnitTypeWithNoParentAndOneUnitTypeRequiredIsAllowed()
		{
			Army army = new Army(mockRace, "Test", 1000);
			UnitRequiresNParentModelsForMUnitsRequirement req = new UnitRequiresNParentModelsForMUnitsRequirement(unitType1);
			req.AddUnitTypeRequirement(unitType2);
			AddUnitOfTypeToArmy(unitType1, army);
			Assert_That__NotApplicable(req, army);
		}
		
		[Test()]
		public void TestValidatingUnitTypeWithParentAndOneUnitTypeRequiredIsAllowed()
		{
			Army army = new Army(mockRace, "Test", 1000);
			Unit parent = AddUnitOfTypeToArmy(unitType2, army);
			AddUnitOfTypeToArmy(unitType1, army, parent);
			UnitRequiresNParentModelsForMUnitsRequirement req = new UnitRequiresNParentModelsForMUnitsRequirement(unitType1);
			req.AddUnitTypeRequirement(unitType2);
			Assert_That__ValidationPasses(req, army);
		}
		
		[Test()]
		public void TestValidatingUnitTypeWithWrongParentAndOneUnitTypeRequiredIsNotApplicable()
		{
			Army army = new Army(mockRace, "Test", 1000);
			Unit parent = AddUnitOfTypeToArmy(unitType2, army);
			AddUnitOfTypeToArmy(unitType1, army, parent);
			UnitRequiresNParentModelsForMUnitsRequirement req = new UnitRequiresNParentModelsForMUnitsRequirement(unitType1);
			req.AddUnitTypeRequirement(unitType3);
			Assert_That__NotApplicable(req, army);
		}
		
		[Test()]
		public void TestValidatingTooManyUnitTypesWithParentAndOneUnitTypeRequiredFails()
		{
			Army army = new Army(mockRace, "Test", 1000);
			Unit parent = AddUnitOfTypeToArmy(unitType3, army, "TheParent");
			AddUnitsOfTypeToArmy(2, unitType1, army, parent);
			UnitRequiresNParentModelsForMUnitsRequirement req = new UnitRequiresNParentModelsForMUnitsRequirement(unitType1);
			req.AddUnitTypeRequirement(unitType3);
			Assert_That__ValidationFails(req, army, "Army can only contain 1 × " + unitType1.Name + " for every 1 model in a parent unit of " + unitType3.Name + ": TheParent has 2 for 1.");
		}
		
		[Test()]
		public void TestValidatingTooManyUnitTypesWithParentAndFiveUnitTypeRequiredFails()
		{
			Army army = new Army(mockRace, "Test", 1000);
			Unit parent = AddUnitOfTypeToArmy(unitType2, army, "TheParent");
			AddUnitsOfTypeToArmy(6, unitType1, army, parent);
			UnitRequiresNParentModelsForMUnitsRequirement req = new UnitRequiresNParentModelsForMUnitsRequirement(unitType1);
			req.AddUnitTypeRequirement(unitType2);
			Assert_That__ValidationFails(req, army, "Army can only contain 1 × " + unitType1.Name + " for every 1 model in a parent unit of " + unitType2.Name + ": TheParent has 6 for 5.");
		}
		
		[Test()]
		public void TestValidatingTooManyUnitsAtThreshold()
		{
			Army army = new Army(mockRace, "Test", 1000);
			Unit parent = AddUnitOfTypeToArmy(unitType2, army, "TheParent");
			AddUnitsOfTypeToArmy(5, unitType1, army, parent);
			UnitRequiresNParentModelsForMUnitsRequirement req = new UnitRequiresNParentModelsForMUnitsRequirement(unitType1);
			req.AddUnitTypeRequirement(unitType2);
			Assert_That__ValidationPasses(req, army);
			AddUnitOfTypeToArmy(unitType1, army, parent);
			Assert_That__ValidationFails(req, army, "Army can only contain 1 × " + unitType1.Name + " for every 1 model in a parent unit of " + unitType2.Name + ": TheParent has 6 for 5.");
		}

		protected override UnitRequiresNParentModelsForMUnitsRequirement CreateRequirement(UnitType requirementOn)
		{
			return new UnitRequiresNParentModelsForMUnitsRequirement(requirementOn);
		}
		
		protected static void Assert_That__PassesAdding(AbstractUnitRequirement<UnitType> req, UnitType unitType, Unit parent, Army army)
		{
			AddingToParentContext ctx = new AddingToParentContext(parent);
			Assert.That(req.AllowsAdding(unitType, army, ctx), Is.EqualTo(Validation.Passed));
			Assert.That(req.GetAllowsAddingMessage(unitType, army, ctx), Is.Empty);
			Unit unit = CreateUnitOfType(unitType, army);
			Assert.That(req.AllowsAdding(unit, army, ctx), Is.EqualTo(Validation.Passed));
			Assert.That(req.GetAllowsAddingMessage(unit, army, ctx), Is.Empty);
		}
		
		protected static void Assert_That__AddingNotApplicable(AbstractUnitRequirement<UnitType> req, UnitType unitType, Unit parent, Army army)
		{
			AddingToParentContext ctx = new AddingToParentContext(parent);
			Assert.That(req.AllowsAdding(unitType, army, ctx), Is.EqualTo(Validation.NotApplicable));
			Assert.That(req.GetAllowsAddingMessage(unitType, army, ctx), Is.Empty);
			Unit unit = CreateUnitOfType(unitType, army);
			Assert.That(req.AllowsAdding(unit, army, ctx), Is.EqualTo(Validation.NotApplicable));
			Assert.That(req.GetAllowsAddingMessage(unit, army, ctx), Is.Empty);
		}
		
		protected static void Assert_That__FailsAdding(AbstractUnitRequirement<UnitType> req, UnitType unitType, Unit parent, Army army, string message)
		{
			AddingToParentContext ctx = new AddingToParentContext(parent);
			Assert.That(req.AllowsAdding(unitType, army, ctx), Is.EqualTo(Validation.Failed));
			Assert.That(req.GetAllowsAddingMessage(unitType, army, ctx), Is.EqualTo(message));
			Unit unit = CreateUnitOfType(unitType, army);
			Assert.That(req.AllowsAdding(unit, army, ctx), Is.EqualTo(Validation.Failed));
			Assert.That(req.GetAllowsAddingMessage(unit, army, ctx), Is.EqualTo(message));
		}

		private Unit AddUnitOfTypeToArmy(UnitType unitType, Army army, Unit parent)
		{
			Unit child = AddUnitOfTypeToArmy(unitType, army);
			parent.AddContainedUnit(child);
			return child;
		}
		
		private ICollection<Unit> AddUnitsOfTypeToArmy(int count, UnitType unitType, Army army, Unit parent)
		{
			ICollection<Unit> units = new List<Unit>();

			for (int i = 0; i < count; i++)
			{
				units.Add(AddUnitOfTypeToArmy(unitType, army, parent));
			}

			return units;
		}
	}
}