code:
package classes{
	import classes.BodyParts.LowerBody;
	import classes.CoC;
	import classes.Creature;
	import classes.GlobalFlags.kGAMECLASS;
	import classes.PerkLib;
	import classes.helper.StageLocator;
	import classes.internals.RandomNumberGenerator;
	import classes.internals.ActionScriptRNG;
	import classes.lists.Gender;
	import classes.lists.BreastCup;
	import org.flexunit.asserts.*;
	import org.hamcrest.assertThat;
	import org.hamcrest.collection.*;
	import org.hamcrest.core.*;
	import org.hamcrest.number.*;
	import org.hamcrest.object.*;
	import org.hamcrest.text.*;

    public class CreatureTest {
		private const MAX_SUPPORTED_VAGINAS:Number = 2;
		private const DEFAULT_CLIT_LENGTH:Number = 0.5;
		private const TEST_CLIT_LENGTH:Number = 3;
		private const CUNT_CHANGE_VALUE:Number = 5;
		private const VAGINAL_LOOSENESS_VALUE:Number = Vagina.LOOSENESS_LOOSE;
		private const VAGINAL_CAPCITY_OFFSET:Number = 2;
		private const VAGINAL_CAPCITY_TEST_DELTA:Number = 2;
		private const RECOVERY_COUNT:Number = 5;
		private const ANAL_LOOSENESS:Number = 1;
		private const ANAL_CAPACITY:Number = 6;

        	private var cut:Creature;
		private var noVagina:Creature;
		private var oneVagina:Creature;
		private var maxVagina:Creature;
		private var fullEquip:Creature;
		private var alwaysZero:RandomNumberGenerator;

		private function createVaginas(numberOfVaginas:Number, instance:Creature):void {
			var i:Number;

			for(i=0; i<numberOfVaginas; i++) {
				instance.createVagina();
			}
		}

		private function createMaxVaginas(instance:Creature):void {
			createVaginas(MAX_SUPPORTED_VAGINAS, instance);
		}

		private function createPerk(perk:PerkType, instance:Creature): void {
			instance.createPerk(perk, 1, 1, 1, 1);
		}

		[BeforeClass]
		public static function setUpClass():void {
		 /* Hidden dependencies on global variables can cause tests to fail spectacularly.
		  *
		  * Seriously people, DONT use global variables.
		  */

			kGAMECLASS = new CoC(StageLocator.stage);
		}

        [Before]
        public function setUp():void {
			alwaysZero = new AlwaysZeroRNG();

			cut = new Creature();
			cut.rng = alwaysZero;
			cut.ass.analLooseness = ANAL_LOOSENESS;
						cut.tou = 100;
			cut.HP = 1;

			noVagina = new Creature();

			oneVagina = new Creature();
			oneVagina.createVagina();
			oneVagina.vaginas[0].recoveryProgress = RECOVERY_COUNT;

			maxVagina = new Creature();
			createMaxVaginas(maxVagina);

			for each (var vag:Vagina in maxVagina.vaginas){
				vag.recoveryProgress = RECOVERY_COUNT;
			}

			fullEquip = new Creature();
			fullEquip.createCock();
			fullEquip.createCock();
			fullEquip.createVagina();
			fullEquip.createVagina();
			fullEquip.createBreastRow(BreastCup.B);
			fullEquip.createBreastRow(BreastCup.B);
			fullEquip.balls = 4;

			// verify created test instances
			assertThat(noVagina.hasVagina(), equalTo(false));

			assertThat(oneVagina.hasVagina(), equalTo(true));
			assertThat(oneVagina.vaginas, arrayWithSize(1));

			assertThat(maxVagina.hasVagina(),equalTo(true));
			assertThat(maxVagina.vaginas, arrayWithSize(MAX_SUPPORTED_VAGINAS));

			assertThat(fullEquip.isHerm(), equalTo(true));
        }

		[Test]
        public function testValidation():void {
            assertThat(noVagina.validate(), equalTo("Empty 'weaponName'. Empty 'weaponVerb'. Empty 'armorName'. "));
        }

		[Test]
        public function testWetnessWithNoVagina():void {
			assertThat(noVagina.wetness(), equalTo(0));
        }

		[Test]
        public function testWetnessWithVagina():void {
			assertThat(oneVagina.wetness(), equalTo(1));
        }

		[Test]
        public function testVaginaTypeWithNoVagina():void {
			assertThat(noVagina.vaginaType(), equalTo(-1));
        }

		[Test]
        public function testVaginaTypeWithVagina():void {
			assertThat(oneVagina.vaginaType(), equalTo(Vagina.HUMAN));
        }

		[Test]
        public function testSetVaginaTypeWithNoVagina():void {
			assertThat(noVagina.vaginaType(Vagina.EQUINE), equalTo(-1));
        }

		[Test]
        public function testSetVaginaTypeWithVagina():void {
			assertThat(oneVagina.vaginaType(Vagina.EQUINE), equalTo(Vagina.EQUINE));
        }

		[Test]
        public function testReadVaginaTypeAfterSet():void {
			oneVagina.vaginaType(Vagina.EQUINE);

			assertThat(oneVagina.vaginaType(), equalTo(Vagina.EQUINE));
        }

		[Test]
        public function testLoosenessVaginaWithNoVagina():void {
			assertThat(noVagina.looseness(), equalTo(0));
        }

		[Test]
        public function testLoosenessVaginaWithVagina():void {
			assertThat(oneVagina.looseness(), equalTo(0));
        }

		[Test]
        public function testLoosenessAnus():void {
			assertThat(noVagina.looseness(false), equalTo(0));
        }

		[Test]
        public function testVaginalCapacityNoVagina():void {
			assertThat(noVagina.vaginalCapacity(), equalTo(0));
        }

		[Test]
        public function testVaginalCapacityWithVagina():void {
			assertThat(oneVagina.vaginalCapacity(), equalTo(0));
        }

		[Test]
		public function testVaginalCapacityTaurBodyBonus():void {
			oneVagina.lowerBody.legCount = 4;
			assertThat(oneVagina.isTaur(), equalTo(true)); //guard assert

			assertThat(oneVagina.vaginalCapacity(), closeTo(55, 0.001));
		}

		[Test]
		public function testVaginalCapacityNagaBodyBonus():void {
			oneVagina.lowerBody.type= LowerBody.NAGA;
			assertThat(oneVagina.isNaga(), equalTo(true)); //guard assert

			assertThat(oneVagina.vaginalCapacity(), equalTo(22));
		}

		[Test]
		public function testVaginalCapacityWetPussyPerkBonus():void {
			oneVagina.createPerk(PerkLib.WetPussy, 1, 1, 1, 1);

			assertThat(oneVagina.vaginalCapacity(), equalTo(22));
		}

		[Test]
		public function testVaginalCapacityHistorySlutPerkBonus():void {
			oneVagina.createPerk(PerkLib.HistorySlut, 1, 1, 1, 1);

			assertThat(oneVagina.vaginalCapacity(), equalTo(22));
		}

		[Test]
		public function testVaginalCapacityOneTrackMindPerkBonus():void {
			oneVagina.createPerk(PerkLib.OneTrackMind, 1, 1, 1, 1);

			assertThat(oneVagina.vaginalCapacity(), closeTo(10 + VAGINAL_CAPCITY_OFFSET, VAGINAL_CAPCITY_TEST_DELTA));
		}

		[Test]
		public function testVaginalCapacityCornucopiaPerkBonus():void {
			oneVagina.createPerk(PerkLib.Cornucopia, 1, 1, 1, 1);

			assertThat(oneVagina.vaginalCapacity(), closeTo(30 + VAGINAL_CAPCITY_OFFSET, VAGINAL_CAPCITY_TEST_DELTA));
		}

		[Test]
		public function testVaginalCapacityFerasBoonWideOpenPerkBonus():void {
			oneVagina.createPerk(PerkLib.FerasBoonWideOpen, 1, 1, 1, 1);

			assertThat(oneVagina.vaginalCapacity(), closeTo(25 + VAGINAL_CAPCITY_OFFSET, VAGINAL_CAPCITY_TEST_DELTA));
		}

		[Test]
		public function testVaginalCapacityFerasBoonMilkingTwatPerkBonus():void {
			oneVagina.createPerk(PerkLib.FerasBoonMilkingTwat, 1, 1, 1, 1);

			assertThat(oneVagina.vaginalCapacity(), closeTo(40 + VAGINAL_CAPCITY_OFFSET, VAGINAL_CAPCITY_TEST_DELTA));
		}

		[Test]
		public function testVaginalCapacityBonusVCapacityStatusEffect():void {
			noVagina.createVagina(true, 1, 4);
			noVagina.createStatusEffect(StatusEffects.BonusVCapacity, 1, 1, 1, 1);

			assertThat(noVagina.vaginalCapacity(), equalTo(141.9));
		}

		[Test]
		public function testVaginalCapacityBasedOnLooseness():void {
			noVagina.createVagina(true, 0, 4);

			assertThat(noVagina.vaginalCapacity(), equalTo(128));
		}

		[Test]
		public function testVaginalCapacityBasedOnWetness():void {
			noVagina.createVagina(true, 4, 1);

			assertThat(noVagina.vaginalCapacity(), equalTo(11.2));
		}

		[Test]
        public function testVaginalCapacityWithVaginaAfterStrech():void {
			oneVagina.cuntChangeNoDisplay(CUNT_CHANGE_VALUE)

			assertThat(oneVagina.vaginalCapacity(), equalTo(8.8));
        }

		[Test]
        public function testHasVaginaWithNoVagina():void {
            assertThat(noVagina.hasVagina(), equalTo(false));
        }

		[Test]
        public function testHasVaginaWithVagina():void {
            assertThat(oneVagina.hasVagina(), equalTo(true));
        }

		[Test]
        public function testHasVirginVaginaWithNoVagina():void {
            assertThat(noVagina.hasVirginVagina(), equalTo(false));
        }

		[Test]
        public function testHasVirginVaginaWithVirginVagina():void {
            assertThat(oneVagina.hasVirginVagina(), equalTo(true));
        }

		[Test]
        public function testHasVirginVaginaWithNonVirginVagina():void {
			assertThat(noVagina.createVagina(false), equalTo(true));

            assertThat(noVagina.hasVirginVagina(), equalTo(false));
        }

		[Test]
        public function testCreateVaginaVirgin():void {
			assertThat(noVagina.createVagina(), equalTo(true));

            assertThat(noVagina.hasVirginVagina(), equalTo(true));
        }

		[Test]
        public function testCreateVaginaNonVirgin():void {
			assertThat(noVagina.createVagina(false), equalTo(true));

            assertThat(noVagina.hasVirginVagina(), equalTo(false));
        }

		[Test]
        public function testCreateVaginaWetness():void {
			assertThat(noVagina.createVagina(true, 3), equalTo(true));

            assertThat(noVagina.wetness(), equalTo(3));
        }

		[Test]
        public function testCreateVaginaLooseness():void {
			assertThat(noVagina.createVagina(true, 1, 3), equalTo(true));

            assertThat(noVagina.looseness(), equalTo(3));
        }

		[Test]
        public function testCreateVaginaMaxVaginas():void {
			assertThat(maxVagina.createVagina(), equalTo(false));
        }

		[Test]
        public function testCreateVaginaMaxVaginasArraySize():void {
			maxVagina.createVagina();

			assertThat(maxVagina.vaginas, arrayWithSize(MAX_SUPPORTED_VAGINAS));
        }

		[Test]
        public function testRemoveVaginaNegativeIndex():void {
			maxVagina.removeVagina(-2);

			assertThat(maxVagina.vaginas, arrayWithSize(MAX_SUPPORTED_VAGINAS));
        }

		[Test]
        public function testRemoveVaginaNegativeRemoveCount():void {
			maxVagina.removeVagina(0, -1);

			assertThat(maxVagina.vaginas, arrayWithSize(MAX_SUPPORTED_VAGINAS));
        }

		[Test]
        public function testRemoveVaginaIndexToLarge():void {
			maxVagina.removeVagina(MAX_SUPPORTED_VAGINAS + 1);

			assertThat(maxVagina.vaginas, arrayWithSize(MAX_SUPPORTED_VAGINAS));
        }

		[Test]
        public function testRemoveVaginaSpecificIndexFirst():void {
			assertThat(noVagina.createVagina(true, 1, 2), equalTo(true));
			assertThat(noVagina.createVagina(true, 1, 3), equalTo(true));

			noVagina.removeVagina(0);

			assertThat(noVagina.looseness(), equalTo(3));
        }

		[Test]
        public function testRemoveVaginaRemoveLastWithMinusOne():void {
			assertThat(noVagina.createVagina(true, 1, 2), equalTo(true));
			assertThat(noVagina.createVagina(true, 1, 3), equalTo(true));

			noVagina.removeVagina(-1);

			assertThat(noVagina.looseness(), equalTo(2));
			assertThat(noVagina.vaginas, arrayWithSize(1));
        }

		[Test]
        public function testRemoveVaginaSpecificIndexLast():void {
			assertThat(noVagina.createVagina(true, 1, 2), equalTo(true));
			assertThat(noVagina.createVagina(true, 1, 3), equalTo(true));

			noVagina.removeVagina(1);

			assertThat(noVagina.looseness(), equalTo(2));
			assertThat(noVagina.vaginas, arrayWithSize(1));
        }

		[Test]
        public function testCuntChangeNoDisplayLoosnessChanged():void {
			assertThat(oneVagina.looseness(), equalTo(0)); // guard assert

			oneVagina.cuntChangeNoDisplay(CUNT_CHANGE_VALUE);

			assertThat(oneVagina.looseness(), equalTo(1));
        }

		[Test]
        public function testCuntChangeNoDisplayIsStretched():void {
			assertThat(oneVagina.cuntChangeNoDisplay(CUNT_CHANGE_VALUE), equalTo(true));
        }

		[Test]
        public function testCuntChangeNoDisplayWithFeraMilkingTwatAndAboveNormalLooseness():void {
			oneVagina.vaginas[0].vaginalLooseness = VAGINAL_LOOSENESS_VALUE;
			oneVagina.createPerk(PerkLib.FerasBoonMilkingTwat, 1, 1, 1, 1);

			assertThat(oneVagina.cuntChangeNoDisplay(Number.MAX_VALUE), equalTo(false));
        }

		[Test]
        public function testCuntChangeNoDisplayWithNoFeraMilkingTwatAndAboveNormalLooseness():void {
			oneVagina.vaginas[0].vaginalLooseness = VAGINAL_LOOSENESS_VALUE;

			assertThat(oneVagina.cuntChangeNoDisplay(Number.MAX_VALUE), equalTo(true));
        }

		[Test]
        public function testCuntChangeNoDisplayWithFeraMilkingTwatAndNormalLooseness():void {
			oneVagina.createPerk(PerkLib.FerasBoonMilkingTwat, 1, 1, 1, 1);

			assertThat(oneVagina.cuntChangeNoDisplay(Number.MAX_VALUE), equalTo(true));
        }

		[Test]
        public function testCuntChangeNoDisplayWithNoFeraMilkingTwatAndNormalLooseness():void {
			assertThat(oneVagina.cuntChangeNoDisplay(Number.MAX_VALUE), equalTo(true));
        }

		[Test]
        public function testFeraMilkingTwatPerkCheck():void {
			oneVagina.createPerk(PerkLib.FerasBoonMilkingTwat, 1, 1, 1, 1);

			assertThat(oneVagina.findPerk(PerkLib.FerasBoonMilkingTwat), equalTo(0));
        }

		[Test]
        public function testCuntChangeNoDisplayLooseVaginaNotStretched():void {
			assertThat(noVagina.createVagina(true,1,4), equalTo(true));

			assertThat(noVagina.cuntChangeNoDisplay(CUNT_CHANGE_VALUE), equalTo(false));
        }

		[Test]
        public function testCuntChangeNoDisplayLoseVirginity():void {
			oneVagina.cuntChangeNoDisplay(CUNT_CHANGE_VALUE);

			assertThat(oneVagina.hasVirginVagina(), equalTo(false));
        }

		[Test]
        public function testCuntChangeNoDisplayWithNoVagina():void {
			assertThat(noVagina.cuntChangeNoDisplay(CUNT_CHANGE_VALUE), equalTo(false));
        }

		[Test]
        public function testCuntChangeNoDisplayCuntStretchedRecoveryProgress():void {
			oneVagina.cuntChangeNoDisplay(Number.MAX_VALUE);

			assertThat(oneVagina.vaginas[0].recoveryProgress, equalTo(0));
        }

		[Test]

        public function testCuntChangeNoDisplayNoRecoveryProgressIncrease():void {
			oneVagina.cuntChangeNoDisplay(0);

			assertThat(oneVagina.vaginas[0].recoveryProgress, equalTo(RECOVERY_COUNT));
        }

		[Test]
        public function testAverageVaginalLoosenessNoVagina():void {
			assertThat(noVagina.averageVaginalLooseness(), equalTo(2));
        }

		[Test]
        public function testAverageVaginalLooseness():void {
			noVagina.createVagina(false, 1, 2);
			noVagina.createVagina(false, 1, 4);

			assertThat(noVagina.averageVaginalLooseness(), equalTo(3));
        }

		[Test]
        public function testAverageVaginalWetnessNoVagina():void {
			assertThat(noVagina.averageVaginalWetness(), equalTo(2));
        }

		[Test]
        public function testAverageVaginalWetness():void {
			noVagina.createVagina(false, 2, 1);
			noVagina.createVagina(false, 4, 1);

			assertThat(noVagina.averageVaginalWetness(), equalTo(3));
        }

		[Test]
        public function testAllVaginaDescriptOnlyOneVagina():void {
			assertThat(oneVagina.allVaginaDescript(), not(endsWith("s")));
        }

		[Test]
        public function testAllVaginaDescriptOnlyMultipleVaginas():void {
			assertThat(maxVagina.allVaginaDescript(), endsWith("s"));
        }

		[Test(expected="flash.errors.IllegalOperationError")]
        public function setClitLength_noVagina():void {
			noVagina.setClitLength(TEST_CLIT_LENGTH);
        }

		[Test(expected="flash.errors.IllegalOperationError")]
        public function getClitLength_noVagina():void {
			noVagina.getClitLength(TEST_CLIT_LENGTH);
        }

		[Test]
        public function setClitLength_oneVagina():void {
			oneVagina.setClitLength(TEST_CLIT_LENGTH);

			assertThat(oneVagina.getClitLength(), equalTo(TEST_CLIT_LENGTH));
        }

		[Test]
        public function getClitLength_oneVagina():void {
			assertThat(oneVagina.getClitLength(), equalTo(Vagina.DEFAULT_CLIT_LENGTH));
        }

		[Test]
        public function setClitLength_multiVagina():void {
			maxVagina.setClitLength(TEST_CLIT_LENGTH, 1);

			assertThat(maxVagina.getClitLength(1), equalTo(TEST_CLIT_LENGTH));
        }

		[Test]
        public function getClitLength_multiVagina():void {
			assertThat(maxVagina.getClitLength(1), equalTo(Vagina.DEFAULT_CLIT_LENGTH));
        }

		[Test(expected="flash.errors.IllegalOperationError")]
        public function changeClitLength_noVagina():void {
			noVagina.changeClitLength(1);
		}

		[Test]
        public function changeClitLength_increase():void {
			assertThat(oneVagina.changeClitLength(1), equalTo(Vagina.DEFAULT_CLIT_LENGTH + 1));
        }

		[Test]
        public function changeClitLength_decrease():void {
			assertThat(oneVagina.changeClitLength(-0.2), equalTo(Vagina.DEFAULT_CLIT_LENGTH - 0.2));
        }

		[Test]
        public function changeClitLength_noNegativeValues():void {
			assertThat(oneVagina.changeClitLength(-Number.MAX_VALUE), equalTo(0));
        }

		[Test(expected="RangeError")]
        public function changeClitLength_invalid_vagina_index():void {
			oneVagina.changeClitLength(1, int.MAX_VALUE);
        }

		[Test]
		public function noGender():void {
			assertThat(noVagina.gender, equalTo(Gender.NONE));
		}

		[Test]
		public function genderIsFemale():void {
			assertThat(oneVagina.gender, equalTo(Gender.FEMALE));
		}

		[Test]
		public function genderIsMale():void {
			noVagina.createCock(5, 1, CockTypesEnum.HUMAN);

			assertThat(noVagina.gender, equalTo(Gender.MALE));
		}

		[Test]
		public function genderIsHerm():void {
			noVagina.createCock(5, 1, CockTypesEnum.HUMAN);
			noVagina.createVagina();

			assertThat(noVagina.gender, equalTo(Gender.HERM));
		}

		[Test]
		public function setNewRng():void {
			var rng:RandomNumberGenerator = new ActionScriptRNG();

			cut.rng = rng;

			assertThat(cut.rng, strictlyEqualTo(rng))
		}

		[Test(expected="ArgumentError")]
		public function setNullForRng():void {
			cut.rng = null;
		}

		[Test]
		public function analStretchWithAreaGreaterThanCapacity(): void {
			assertThat(cut.buttChangeNoDisplay(ANAL_CAPACITY), equalTo(true));
		}

		[Test]
		public function analStretchWithArea80PercentOfCapacity(): void {
			assertThat(cut.buttChangeNoDisplay(ANAL_CAPACITY * 0.8), equalTo(true));
		}

		[Test]
		public function analStretchWithArea90PercentOfCapacity(): void {
			assertThat(cut.buttChangeNoDisplay(ANAL_CAPACITY * 0.9), equalTo(true));
		}

		[Test]
		public function clearGenderRemovesCock(): void {
			fullEquip.clearGender();

			assertThat(fullEquip.hasCock(), equalTo(false));
		}

		[Test]
		public function clearGenderRemovesVagina(): void {
			fullEquip.clearGender();

			assertThat(fullEquip.hasVagina(), equalTo(false));
		}

		[Test]
		public function clearGenderRemovesBreasts(): void {
			fullEquip.clearGender();

			assertThat(fullEquip.hasBreasts(), equalTo(false));
		}

		[Test]
		public function clearGenderRemovesBalls(): void {
			fullEquip.clearGender();

			assertThat(fullEquip.balls, equalTo(0));
		}

		[Test]
		public function clearGenderNoBreasts(): void {
			cut.clearGender();

			assertThat(cut.hasBreasts(), equalTo(false));
		}

		[Test]
		public function healToMaxHP():void {
			cut.restoreHP();

			assertThat(cut.HP, equalTo(250));
		}

		[Test]
		public function healByAmount():void {
			cut.restoreHP(1);

			assertThat(cut.HP, equalTo(2));
		}

		[Test]
		public function healOverflowCheck():void {
			cut.HP = 1000;

			cut.restoreHP();

			assertThat(cut.HP, equalTo(250));
		}

		[Test(expected="RangeError")]
		public function healByNegativeAmount():void {
			cut.restoreHP(-1);
		}
	}
}

import classes.internals.RandomNumberGenerator;

class AlwaysZeroRNG implements RandomNumberGenerator {
	public function random(max:int):int
	{
		return 0;
	}

	public function randomCorrected(max:int):int
	{
		return 0;
	}
}


code:
package classes {

import classes.helper.DummyOutputTest;
import classes.helper.FireButtonEventTest;
import classes.helper.MemoryLogTargetTest;
import classes.helper.StageLocatorTest;

[Suite]
[RunWith("org.flexunit.runners.Suite")]
	public class HelperSuit
	{
		 public var stageLocatorTest:StageLocatorTest;
		 public var memoryLogTargetTest:MemoryLogTargetTest;
		 public var fireButtonEventTest:FireButtonEventTest;
		 public var dummyOutputTest:DummyOutputTest;
	}
}

license: unknown


code:
package classes {
	import classes.helper.MemoryLogTarget;
	import classes.helper.MemoryLogTargetTest;
	import classes.internals.LoggerFactoryTest;
	import classes.internals.ActionScriptRNGTest;
	import classes.internals.SerializationUtilTest;
	import classes.internals.UtilsTest;
	import classes.internals.PregnancyUtilsTest;

	[Suite]
	[RunWith("org.flexunit.runners.Suite")]
	public class InternalsSuit
	{
		public var loggerFactoryTest:LoggerFactoryTest;
		public var serializationUtilTest:SerializationUtilTest;
		public var utilsTest:UtilsTest;
		public var actionScriptRNGTest:ActionScriptRNGTest;
		public var pregnancyUtilsTest:PregnancyUtilsTest;
	}
}


code:
package classes.Items
{
	import org.flexunit.asserts.*;
	import org.hamcrest.assertThat;
	import org.hamcrest.core.*;
	import org.hamcrest.number.*;
	import org.hamcrest.object.*;
	import org.hamcrest.text.*;

	import classes.helper.StageLocator;

	import classes.GlobalFlags.kGAMECLASS;
	import classes.Items.Mutations;
	import classes.Player;
	import classes.CoC;
	import classes.StatusEffects;

	public class ConsumableTest
	{
		private static const RECOVERY_PROGRESS:int = 5;

		private var player:Player;
		private var cut:Consumable;

		[BeforeClass]
		public static function setUpClass():void
		{
			kGAMECLASS = new CoC(StageLocator.stage);
		}

		[Before]
		public function setUp():void
		{
			cut = new TestConsumable();
			player = new Player();

			kGAMECLASS.player = player;
		}

		[Test]
		public function statChangeOnItemUse():void
		{
			cut.useItem();

			assertThat(player.str, equalTo(100))
		}
	}
}

import classes.Items.Consumable;

class TestConsumable extends Consumable
{
	public function TestConsumable()
	{
		super("test", "test", "test item",0,"Just testing!");
	}

	override public function useItem():Boolean
	{
		dynStats('str', +100);
		return false;
	}
}


code:
package classes.Items {
	import classes.Items.Consumables.LaBova;
	import org.flexunit.asserts.*;
	import org.hamcrest.assertThat;
	import org.hamcrest.core.*;
	import org.hamcrest.number.*;
	import org.hamcrest.object.*;
	import org.hamcrest.text.*;

	import classes.helper.StageLocator;

	import classes.GlobalFlags.kGAMECLASS;
	import classes.Items.Mutations;
	import classes.Player;
	import classes.CoC;
	import classes.StatusEffects;

    public class MutationsTest {
		private static const RECOVERY_PROGRESS:int = 5;

		private var player:Player;
		private var femalePlayer:Player;
        private var cut:Mutations;

		[BeforeClass]
		public static function setUpClass():void {
			kGAMECLASS = new CoC(StageLocator.stage);
		}

        [Before]
        public function setUp():void {
			cut = Mutations.init();
			player = new Player();

			femalePlayer = new Player();
			femalePlayer.createBreastRow(2);
			femalePlayer.createVagina();
			femalePlayer.vaginas[0].recoveryProgress = RECOVERY_PROGRESS;

			// guard asserts
			assertThat(player.hasVagina(), equalTo(false));
			assertThat(player.hasBreasts(), equalTo(false));
			assertThat(player.skin.tone, equalTo("albino"));

			assertThat(femalePlayer.hasVagina(), equalTo(true));
			assertThat(femalePlayer.hasBreasts(), equalTo(true));
			assertThat(femalePlayer.hasCock(), equalTo(false));
			assertThat(femalePlayer.vaginas[0].recoveryProgress, equalTo(RECOVERY_PROGRESS));
        }

		private function drinkBova(count:int, type:int, player:Player):void {
			var consumable:LaBova = new LaBova(type);

			for (var i:int = 0; i < count; i++) {
				consumable.applyEffect(player);
			}
		}

		[Test(expected="Error")]
        public function testConstructorFails():void {
            cut = new Mutations();
        }

		[Test]
		public function testLaBovaResetsRecoveryProgress():void {
			drinkBova(100, LaBova.STANDARD, femalePlayer);

			assertThat(femalePlayer.vaginas[0].recoveryProgress, equalTo(0))
        }
    }
}


code:
package classes {
	import classes.Items.ConsumableTest;
	import classes.Items.MutationsTest;

[Suite]
[RunWith("org.flexunit.runners.Suite")]
	public class ItemsSuit
	{
		 public var mutationsTest:MutationsTest;
		 public var consumableTest:ConsumableTest;
	}
}


code:
package classes {
	import classes.menus.GenderDebugTest;

	[Suite]
	[RunWith("org.flexunit.runners.Suite")]
	public class MenusSuit
	{
		public var genderDebugTest:GenderDebugTest
	}
}


code:
package classes{
    import org.flexunit.asserts.*;
	import org.hamcrest.assertThat;
	import org.hamcrest.core.*;
	import org.hamcrest.number.*;
	import org.hamcrest.object.*;
	import org.hamcrest.text.*;
	import org.hamcrest.collection.*;

	import classes.Monster;

    public class MonsterTest {
        private var cut:Monster;

        [Before]
        public function setUp():void {
			cut = new Monster();
        }

		[Test]
        public function testMonsterConstructor():void {
        	cut = new Monster();
		}

		[Test(description="Check that the array or vector for vaginas is correctly initialised")]
        public function testVaginasStoreLengthIsZero():void {
        	assertThat(cut.vaginas, emptyArray());
		}

		[Test(description="Check that the array or vector for vaginas is correctly initialised")]
        public function testVaginasStoreIsNotNull():void {
        	assertThat(cut.vaginas, notNullValue());
		}
    }
}


code:
package classes{
    import org.flexunit.asserts.*;
	import org.hamcrest.assertThat;
	import org.hamcrest.core.*;
	import org.hamcrest.number.*;
	import org.hamcrest.object.*;
	import org.hamcrest.text.*;

	import flash.display.Stage;

	import classes.GlobalFlags.kGAMECLASS;
	import classes.CoC;
	import classes.helper.StageLocator;
	import classes.PlayerEvents;
	import classes.Player;

    public class PlayerEventsTest {
		private const LOOSENESS:Number = Vagina.LOOSENESS_LOOSE;

        private var cut:PlayerEvents;
		private var player:Player;

		[BeforeClass]
		public static function setUpClass():void {
			kGAMECLASS = new CoC(StageLocator.stage);
		}

        [Before]
        public function setUp():void {
			player = new Player();
			kGAMECLASS.player = player;
			cut = new PlayerEvents();

			player.createVagina(false, 1, LOOSENESS);
			player.vaginas[0].recoveryProgress = Number.MAX_VALUE;
        }

		// most of the recovery tests are performed with a parametrized tests

        [Test]
        public function testVaginaLoosenessChangeWithNoVagina():void {
			player.removeVagina();

			cut.timeChange();

			assertThat(player.hasVagina(), equalTo(false));
        }

		[Test]
        public function testVaginaLoosenessChangeWithoutStatus():void {
			player.vaginas[0].resetRecoveryProgress();

			cut.timeChange();

			assertThat(player.looseness(), equalTo(LOOSENESS));
        }
    }
}


code:
package classes{
    import org.flexunit.asserts.*;
	import org.hamcrest.assertThat;
	import org.hamcrest.core.*;
	import org.hamcrest.number.*;
	import org.hamcrest.object.*;
	import org.hamcrest.text.*;

	import flash.display.Stage;

	import classes.GlobalFlags.kGAMECLASS;
	import classes.CoC;
	import classes.helper.StageLocator;
	import classes.PlayerEvents;
	import classes.Player;

	import org.flexunit.runners.Parameterized;

	/**
	 * Test treshold values for vagina looseness recovery.
	 */

    [RunWith("org.flexunit.runners.Parameterized")]
    public class PlayerEventsVaginaLoosenessRecoveryTest {
		private const LOOSENESS:Number = Vagina.LOOSENESS_LOOSE;

        private var cut:PlayerEvents;
		private var player:Player;

		[BeforeClass]
		public static function setUpClass():void {
			kGAMECLASS = new CoC(StageLocator.stage);
		}

        [Before]
        public function setUp():void {
			player = new Player();
			kGAMECLASS.player = player;
			cut = new PlayerEvents();
        }

		private function setVaginaSize(size:Number):void {
			player.removeVagina();
			player.createVagina(false, 1, size);
		}

		/**
		 * Sets 'cuntStretched' status to the give value - 1.
		 * The - 1 is required to counteract the code adding 1 to the value prior to checking.
		 */
		private function setVaginaRecoveryProgress(value:Number):void {
			player.vaginas[0].recoveryProgress = value - 1;
		}

          [Parameters]
          public static var testData:Array = [
		  	[Vagina.LOOSENESS_LOOSE, PlayerEvents.VAGINA_RECOVER_THRESHOLD_LOOSE, 0],
			[Vagina.LOOSENESS_GAPING, PlayerEvents.VAGINA_RECOVER_THRESHOLD_GAPING, 0],
			[Vagina.LOOSENESS_GAPING_WIDE, PlayerEvents.VAGINA_RECOVER_THRESHOLD_GAPING_WIDE, 0],
			[Vagina.LEVEL_CLOWN_CAR, PlayerEvents.VAGINA_RECOVER_THRESHOLD_CLOWN_CAR, 1]
			];

          private var looseness:Number;
          private var threshold:Number;
		   private var ferrasBoonChange:Number;

		public function PlayerEventsVaginaLoosenessRecoveryTest(looseness:Number, threshold:Number, ferrasBoonChange:Number){
               this.looseness = looseness;
               this.threshold = threshold;
			   this.ferrasBoonChange = ferrasBoonChange;
		}

		[Test]
        public function testAffectedByFerasBoon():void {
			player.createPerk(PerkLib.FerasBoonWideOpen, 1, 1, 1, 1);
			setVaginaSize(looseness);
			setVaginaRecoveryProgress(int.MAX_VALUE);

			cut.timeChange();

			assertThat(player.looseness(), equalTo(looseness - ferrasBoonChange));
        }

		[Test]
        public function testStatusEffectReset():void {
			setVaginaSize(looseness);
			setVaginaRecoveryProgress(threshold);

			cut.timeChange();

			assertThat(player.vaginas[0].recoveryProgress, equalTo(0));
        }

		[Test]
        public function testVaginaLoosenessChangeThreshold_above():void {
			setVaginaSize(looseness);
			setVaginaRecoveryProgress(threshold + 1);

			cut.timeChange();

			assertThat(player.looseness(), equalTo(looseness - 1));
        }

		[Test]
        public function testVaginaLoosenessChangeThreshold_at():void {
			setVaginaSize(looseness);
			setVaginaRecoveryProgress(threshold);

			cut.timeChange();

			assertThat(player.looseness(), equalTo(looseness - 1));
        }

		[Test]
        public function testVaginaLoosenessChangeThreshold_below():void {
			setVaginaSize(looseness);
			setVaginaRecoveryProgress(threshold - 1);

			cut.timeChange();

			assertThat(player.looseness(), equalTo(looseness));
        }
    }
}


code:
package classes
{
	import classes.BodyParts.*;
	import classes.CoC;
	import classes.GlobalFlags.kFLAGS;
	import classes.GlobalFlags.kGAMECLASS;
	import classes.PerkLib;
	import classes.Player;
	import classes.helper.StageLocator;
	import classes.lists.ColorLists;
	import org.flexunit.asserts.*;
	import org.hamcrest.assertThat;
	import org.hamcrest.collection.*;
	import org.hamcrest.core.*;
	import org.hamcrest.number.*;
	import org.hamcrest.object.*;
	import org.hamcrest.text.*;
	import classes.Items.ArmorLib;

	public class PlayerTest
	{
		private static const HP_OVER_HEAL:Number = 1000;
		private static const PLAYER_MAX_HP:Number = 250;
		private const MAX_SUPPORTED_VAGINAS:Number = 2;
		private const MAX_SUPPORTED_BREAST_ROWS:Number = 10;

		private var impPlayer:Player;
		private var minoPlayer:Player;
		private var cowPlayer:Player;
		private var wolfPlayer:Player;
		private var dogPlayer:Player;
		private var mutantPlayer:Player;
		private var cut:DummyPlayer;

		private function createVaginas(numberOfVaginas:Number, instance:Player):void
		{
			for (var i:Number = 0; i < numberOfVaginas; i++) {
				instance.createVagina();
			}
		}

		private function createMaxVaginas(instance:Player):void
		{
			createVaginas(MAX_SUPPORTED_VAGINAS, instance);
		}

		private function createBreastRows(numberOfRows:Number, instance:Player):void
		{
			removeAllBreasts(instance);
			for (var i:Number = 1; i < numberOfRows; i++) {
				instance.createBreastRow();
			}
		}

		private function createMaxBreastRows(instance:Player):void
		{
			createBreastRows(MAX_SUPPORTED_BREAST_ROWS, instance);
		}

		private function removeExtraBreastRows(instance:Player):void
		{
			if (instance.breastRows.length <= 1)
				return;

			instance.removeBreastRow(1, instance.breastRows.length - 1);
		}

		private function removeAllBreasts(instance:Player):void
		{
			if (instance.breastRows.length === 0) {
				instance.createBreastRow();
				return;
			}

			removeExtraBreastRows(instance);
			instance.breastRows[0].restore();
		}

		private function removeAllVags(instance:Player):void
		{
			if (instance.vaginas.length === 0)
				return;

			instance.removeVagina(0, instance.vaginas.length);
		}

		private function createCock(ctype:CockTypesEnum, instance:Player):void
		{
			instance.createCock(5.5, 1, ctype);
		}

		private function createPerk(perk:PerkType, instance:Player):void
		{
			instance.createPerk(perk, 1, 1, 1, 1);
		}

		private function createStatusEffect(stype:StatusEffectType, instance:Player):void
		{
			if (!instance.hasStatusEffect(stype))
				instance.createStatusEffect(stype, 1, 1, 1, 1);
		}

		[BeforeClass]
		public static function setUpClass():void
		{
			/* Hidden dependencies on global variables can cause tests to fail spectacularly.
			 *
			 * Seriously people, DONT use global variables.
			 */

			kGAMECLASS = new CoC(StageLocator.stage);
		}

		[Before]
		public function setUp():void
		{
			impPlayer = new Player();
			impPlayer.createBreastRow();
			impPlayer.ears.type = Ears.IMP;
			impPlayer.tail.type = Tail.IMP;
			impPlayer.wings.type = Wings.IMP;
			impPlayer.wings.type = Wings.IMP_LARGE;
			impPlayer.lowerBody.type = LowerBody.IMP;
			impPlayer.skin.type = Skin.PLAIN;
			impPlayer.skin.tone = "red";
			impPlayer.horns.type = Horns.IMP;
			impPlayer.arms.setType(Arms.PREDATOR, Claws.IMP);

			minoPlayer = new Player();
			minoPlayer.face.type = Face.COW_MINOTAUR;
			minoPlayer.ears.type = Ears.COW;
			minoPlayer.tail.type = Tail.COW;
			minoPlayer.horns.type = Horns.COW_MINOTAUR;
			minoPlayer.lowerBody.type = LowerBody.HOOFED;
			minoPlayer.tallness = 100;
			createCock(CockTypesEnum.HORSE, minoPlayer);

			cowPlayer = new Player();
			cowPlayer.ears.type = Ears.COW;
			cowPlayer.tail.type = Tail.COW;
			cowPlayer.horns.type = Horns.COW_MINOTAUR;
			cowPlayer.lowerBody.type = LowerBody.HOOFED;
			cowPlayer.tallness = 73;
			cowPlayer.createVagina();
			cowPlayer.createBreastRow(5);
			cowPlayer.breastRows[0].lactationMultiplier = 3;

			wolfPlayer = new Player();
			createCock(CockTypesEnum.WOLF, wolfPlayer);
			wolfPlayer.face.type = Face.WOLF;
			wolfPlayer.ears.type = Ears.WOLF;
			wolfPlayer.tail.type = Tail.WOLF;
			wolfPlayer.lowerBody.type = LowerBody.WOLF;
			wolfPlayer.eyes.type = Eyes.WOLF;
			wolfPlayer.skin.type = Skin.FUR;

			dogPlayer = new Player();
			createCock(CockTypesEnum.DOG, dogPlayer);
			dogPlayer.face.type = Face.DOG;
			dogPlayer.ears.type = Ears.DOG;
			dogPlayer.tail.type = Tail.DOG;
			dogPlayer.arms.setType(Arms.DOG);
			dogPlayer.lowerBody.type = LowerBody.DOG;
			dogPlayer.skin.type = Skin.FUR;

			mutantPlayer = new Player();
			createBreastRows(2, mutantPlayer);
			mutantPlayer.breastRows[0].fuckable = true;
			mutantPlayer.createCock();
			mutantPlayer.createCock();
			mutantPlayer.createVagina();

			cut = new DummyPlayer();
			cut.HP = 1;
			cut.tou = 100;
		}

		[Test]
		public function testRedPandaScore():void
		{
			var redPandaPlayer:Player = new Player();
			redPandaPlayer.ears.type = Ears.RED_PANDA;
			redPandaPlayer.tail.type = Tail.RED_PANDA;
			redPandaPlayer.arms.type = Arms.RED_PANDA;
			redPandaPlayer.face.type = Face.RED_PANDA;
			redPandaPlayer.lowerBody.type = LowerBody.RED_PANDA;
			redPandaPlayer.skin.type = Skin.FUR;
			redPandaPlayer.underBody.type = UnderBody.FURRY;
			redPandaPlayer.underBody.skin.type = Skin.FUR;

			assertThat(redPandaPlayer.redPandaScore(), greaterThan(0));
		}

		[Test]
		public function testCockatriceScore():void
		{
			var cockatricePlayer:Player = new Player();
			cockatricePlayer.ears.type = Ears.COCKATRICE;
			cockatricePlayer.tail.type = Tail.COCKATRICE;
			cockatricePlayer.lowerBody.type = LowerBody.COCKATRICE;
			cockatricePlayer.face.type = Face.COCKATRICE;
			cockatricePlayer.eyes.type = Eyes.COCKATRICE;
			cockatricePlayer.arms.type = Arms.COCKATRICE;
			cockatricePlayer.antennae.type = Antennae.COCKATRICE;
			cockatricePlayer.neck.type = Neck.COCKATRICE;
			cockatricePlayer.tongue.type = Tongue.LIZARD;
			cockatricePlayer.wings.type = Wings.FEATHERED_LARGE;
			cockatricePlayer.skin.type = Skin.LIZARD_SCALES;
			cockatricePlayer.underBody.type = UnderBody.COCKATRICE;
			createCock(CockTypesEnum.LIZARD, cockatricePlayer);

			assertThat(cockatricePlayer.cockatriceScore(), greaterThan(0));
		}

		[Test]
		public function testNormalImpScore():void
		{
			removeAllBreasts(impPlayer);
			impPlayer.tallness = 30;

			assertThat(impPlayer.impScore(), greaterThan(0));
		}

		[Test]
		public function testTitsImpScore():void
		{
			removeAllBreasts(impPlayer);
			impPlayer.tallness = 50;
			impPlayer.breastRows[0].breastRating = 5;
			impPlayer.createBreastRow(5);
			impPlayer.createBreastRow(5);
			impPlayer.createBreastRow(5);

			assertThat(impPlayer.impScore(), greaterThan(0));
		}

		[Test]
		public function testDemonScore():void
		{
			var demonPlayer:Player = new Player();
			demonPlayer.horns.type = Horns.DEMON;
			demonPlayer.horns.value = 12;
			demonPlayer.tail.type = Tail.DEMONIC;
			demonPlayer.wings.type = Wings.BAT_LIKE_LARGE;
			demonPlayer.skin.type = Skin.PLAIN;
			demonPlayer.cor = 100;
			demonPlayer.face.type = Face.HUMAN;
			demonPlayer.lowerBody.type = LowerBody.DEMONIC_CLAWS;
			createCock(CockTypesEnum.DEMON, demonPlayer);

			assertThat(demonPlayer.demonScore(), greaterThan(0));
		}

		[Test]
		public function testHumanScore():void
		{
			var humanPlayer:Player = new Player();
			humanPlayer.face.type = Face.HUMAN;
			humanPlayer.skin.type = Skin.PLAIN;
			humanPlayer.horns.type = Horns.NONE;
			humanPlayer.tail.type = Tail.NONE;
			humanPlayer.wings.type = Wings.NONE;
			humanPlayer.lowerBody.type = LowerBody.HUMAN;
			humanPlayer.skin.type = Skin.PLAIN;
			createCock(CockTypesEnum.HUMAN, humanPlayer);
			removeAllBreasts(humanPlayer); // auto-creates a breast row, if none exists

			assertThat(humanPlayer.humanScore(), greaterThan(0));
		}

		[Test]
		public function testMinoScore():void
		{
			removeAllVags(minoPlayer);

			assertThat(minoPlayer.minoScore(), greaterThan(0));
		}

		[Test]
		public function testVagMinoScore():void
		{
			minoPlayer.createVagina();

			assertThat(minoPlayer.minoScore(), greaterThan(0));
		}

		[Test]
		public function testCowScore():void
		{
			cowPlayer.face.type = Face.HUMAN;

			assertThat(cowPlayer.cowScore(), greaterThan(0));
		}

		[Test]
		public function testCowFaceCowScore():void
		{
			cowPlayer.face.type = Face.COW_MINOTAUR;

			assertThat(cowPlayer.cowScore(), greaterThan(0));
		}

		[Test]
		public function testSandTrapScore():void
		{
			var sandTrapPlayer:Player = new Player();
			createStatusEffect(StatusEffects.BlackNipples, sandTrapPlayer);
			createStatusEffect(StatusEffects.Uniball, sandTrapPlayer);
			sandTrapPlayer.createVagina();
			sandTrapPlayer.vaginaType(5);
			sandTrapPlayer.eyes.type = Eyes.BLACK_EYES_SAND_TRAP;
			sandTrapPlayer.wings.type = Wings.GIANT_DRAGONFLY;

			assertThat(sandTrapPlayer.sandTrapScore(), greaterThan(0));
		}

		[Test]
		public function testBeeScore():void
		{
			var beePlayer:Player = new Player();
			beePlayer.hair.color = "black and yellow";
			beePlayer.antennae.type = Antennae.BEE;
			beePlayer.face.type = Face.HUMAN;
			beePlayer.arms.type = Arms.BEE;
			beePlayer.lowerBody.type = LowerBody.BEE;
			beePlayer.createVagina();
			beePlayer.tail.type = Tail.BEE_ABDOMEN;
			beePlayer.wings.type = Wings.BEE_LIKE_SMALL;

			assertThat(beePlayer.beeScore(), greaterThan(0));
		}

		[Test]
		public function testFerretScore():void
		{
			var ferretPlayer:Player = new Player();
			ferretPlayer.face.type = Face.FERRET;
			ferretPlayer.ears.type = Ears.FERRET;
			ferretPlayer.tail.type = Tail.FERRET;
			ferretPlayer.lowerBody.type = LowerBody.FERRET;
			ferretPlayer.arms.type = Arms.FERRET;
			ferretPlayer.skin.type = Skin.FUR;

			assertThat(ferretPlayer.ferretScore(), greaterThan(0));
		}

		[Test]
		public function testMaleWolfScore():void
		{
			removeAllBreasts(wolfPlayer);

			assertThat(wolfPlayer.wolfScore(), greaterThan(0));
		}

		[Test]
		public function testHermWolfScore():void
		{
			createBreastRows(4, wolfPlayer);

			assertThat(wolfPlayer.wolfScore(), greaterThan(0));
		}

		[Test]
		public function testHermLottaBreastRowsWolfScore():void
		{
			createMaxBreastRows(wolfPlayer);

			assertThat(wolfPlayer.wolfScore(), greaterThan(0));
		}

		[Test]
		public function testMaleDogScore():void
		{
			removeAllBreasts(dogPlayer);

			assertThat(dogPlayer.dogScore(), greaterThan(0));
		}

		[Test]
		public function testHermDogScore():void
		{
			createBreastRows(3, dogPlayer);

			assertThat(dogPlayer.dogScore(), greaterThan(0));
		}

		[Test]
		public function testHermLottaBreastRowsDogScore():void
		{
			createMaxBreastRows(dogPlayer);

			assertThat(dogPlayer.dogScore(), greaterThan(0));
		}

		[Test]
		public function testMouseScore():void
		{
			var mousePlayer:Player = new Player();
			mousePlayer.ears.type = Ears.MOUSE;
			mousePlayer.tail.type = Tail.MOUSE;
			mousePlayer.face.type = Face.MOUSE;
			mousePlayer.skin.type = Skin.FUR;
			mousePlayer.tallness = 30;

			assertThat(mousePlayer.mouseScore(), greaterThan(0));
		}

		[Test]
		public function testRaccoonScore():void
		{
			var raccoonPlayer:Player = new Player();
			raccoonPlayer.face.type = Face.RACCOON;
			raccoonPlayer.ears.type = Ears.RACCOON;
			raccoonPlayer.tail.type = Tail.RACCOON;
			raccoonPlayer.lowerBody.type = LowerBody.RACCOON;
			raccoonPlayer.balls = 2;
			raccoonPlayer.skin.type = Skin.FUR;

			assertThat(raccoonPlayer.raccoonScore(), greaterThan(0));
		}

		[Test]
		public function testFoxScore():void
		{
			// No need to test variations of breastrow-count yet
			var foxPlayer:Player = new Player();
			createBreastRows(4, foxPlayer);
			createCock(CockTypesEnum.FOX, foxPlayer);
			foxPlayer.face.type = Face.FOX;
			foxPlayer.ears.type = Ears.FOX;
			foxPlayer.tail.type = Tail.FOX;
			foxPlayer.lowerBody.type = LowerBody.FOX;
			foxPlayer.arms.setType(Arms.FOX);
			foxPlayer.skin.type = Skin.FUR;

			assertThat(foxPlayer.foxScore(), greaterThan(0));
		}

		[Test]
		public function testCatScore():void
		{
			// No need to test variations of breastrow-count yet
			var catPlayer:Player = new Player();
			createBreastRows(3, catPlayer);
			createCock(CockTypesEnum.CAT, catPlayer);
			catPlayer.face.type = Face.CAT;
			catPlayer.ears.type = Ears.CAT;
			catPlayer.tail.type = Tail.CAT;
			catPlayer.lowerBody.type = LowerBody.CAT;
			catPlayer.arms.setType(Arms.CAT);
			catPlayer.skin.type = Skin.FUR;

			assertThat(catPlayer.catScore(), greaterThan(0));
		}

		[Test]
		public function testLizardScore():void
		{
			var lizardPlayer:Player = new Player();
			lizardPlayer.face.type = Face.LIZARD;
			lizardPlayer.ears.type = Ears.LIZARD;
			lizardPlayer.tail.type = Tail.LIZARD;
			lizardPlayer.lowerBody.type = LowerBody.LIZARD;
			lizardPlayer.horns.type = Horns.DRACONIC_X4_12_INCH_LONG;
			lizardPlayer.arms.setType(Arms.LIZARD, Claws.LIZARD);
			lizardPlayer.tongue.type = Tongue.LIZARD;
			createCock(CockTypesEnum.LIZARD, lizardPlayer);
			createCock(CockTypesEnum.LIZARD, lizardPlayer);
			lizardPlayer.eyes.type = Eyes.LIZARD;
			lizardPlayer.skin.type = Skin.LIZARD_SCALES;

			assertThat(lizardPlayer.lizardScore(), greaterThan(0));
		}

		[Test]
		public function testSpiderScore():void
		{
			var driderPlayer:Player = new Player();
			driderPlayer.eyes.setProps({type: Eyes.SPIDER, count: 4});
			driderPlayer.face.type = Face.SPIDER_FANGS;
			driderPlayer.arms.type = Arms.SPIDER;
			driderPlayer.lowerBody.type = LowerBody.DRIDER;
			driderPlayer.tail.type = Tail.SPIDER_ABDOMEN;
			driderPlayer.skin.type = Skin.PLAIN;

			assertThat(driderPlayer.spiderScore(), greaterThan(0));
		}

		[Test]
		public function testHorseScore():void
		{
			var horsePlayer:Player = new Player();
			createCock(CockTypesEnum.HORSE, horsePlayer);
			horsePlayer.face.type = Face.HORSE;
			horsePlayer.ears.type = Ears.HORSE;
			horsePlayer.tail.type = Tail.HORSE;
			horsePlayer.lowerBody.type = LowerBody.HOOFED;
			horsePlayer.skin.type = Skin.FUR;

			assertThat(horsePlayer.horseScore(), greaterThan(0));
		}

		[Test]
		public function testKitsuneScore():void
		{
			// Avoiding randomness for hair and fur colors now. Maybe later?
			var kitsunePlayer:Player = new Player();
			kitsunePlayer.createVagina();
			kitsunePlayer.createStatusEffect(StatusEffects.BonusVCapacity, 8000, 0, 0, 0);
			kitsunePlayer.ears.type = Ears.FOX;
			kitsunePlayer.tail.setProps({type: Tail.FOX, venom: 9});
			kitsunePlayer.face.type = Face.FOX;
			kitsunePlayer.hair.color = ColorLists.ELDER_KITSUNE[0];
			kitsunePlayer.skin.type = Skin.FUR;
			kitsunePlayer.setFurColor([ColorLists.ELDER_KITSUNE[0]], {type: UnderBody.FURRY}, true);
			kitsunePlayer.femininity = 40;
			kitsunePlayer.lowerBody.type = LowerBody.FOX;

			assertThat(kitsunePlayer.kitsuneScore(), greaterThan(0));
		}

		[Test]
		public function testDragonScore():void
		{
			var dragonPlayer:Player = new Player();
			createCock(CockTypesEnum.DRAGON, dragonPlayer);
			createPerk(PerkLib.Dragonfire, dragonPlayer);
			dragonPlayer.face.type = Face.DRAGON;
			dragonPlayer.ears.type = Ears.DRAGON;
			dragonPlayer.tail.type = Tail.DRACONIC;
			dragonPlayer.tongue.type = Tongue.DRACONIC;
			dragonPlayer.wings.type = Wings.DRACONIC_LARGE;
			dragonPlayer.lowerBody.type = LowerBody.DRAGON;
			dragonPlayer.skin.type = Skin.DRAGON_SCALES;
			dragonPlayer.horns.type = Horns.DRACONIC_X4_12_INCH_LONG;
			dragonPlayer.arms.setType(Arms.DRAGON, Claws.DRAGON);
			dragonPlayer.eyes.type = Eyes.DRAGON;
			dragonPlayer.neck.modify(Infinity, Neck.DRACONIC);
			dragonPlayer.rearBody.type = RearBody.DRACONIC_SPIKES;

			assertThat(dragonPlayer.dragonScore(), greaterThan(0));
		}

		[Test]
		public function testGoblinScore():void
		{
			var goblinPlayer:Player = new Player();
			goblinPlayer.createVagina();
			goblinPlayer.ears.type = Ears.ELFIN;
			goblinPlayer.skin.tone = ColorLists.GOBLIN_SKIN[0];
			goblinPlayer.face.type = Face.HUMAN;
			goblinPlayer.tallness = 40;
			goblinPlayer.lowerBody.type = LowerBody.HUMAN;

			assertThat(goblinPlayer.goblinScore(), greaterThan(0));
		}

		[Test]
		public function testGooScore():void
		{
			var gooPlayer:Player = new Player();
			gooPlayer.hair.type = Hair.GOO;
			gooPlayer.skin.adj = "slimy";
			gooPlayer.lowerBody.type = LowerBody.GOO;
			gooPlayer.createVagina();
			gooPlayer.createStatusEffect(StatusEffects.BonusVCapacity, 9000, 0, 0, 0);
			gooPlayer.createStatusEffect(StatusEffects.SlimeCraving, 0, 0, 0, 1);

			assertThat(gooPlayer.gooScore(), greaterThan(0));
		}

		[Test]
		public function testNagaScore():void
		{
			var nagaPlayer:Player = new Player();
			nagaPlayer.face.type = Face.SNAKE_FANGS;
			nagaPlayer.tongue.type = Tongue.SNAKE;
			nagaPlayer.lowerBody.type = LowerBody.NAGA; // Not included in nagaScore, but just in case ...

			assertThat(nagaPlayer.nagaScore(), greaterThan(0));
		}

		[Test]
		public function testBunnyScore():void
		{
			var bunnyPlayer:Player = new Player();
			bunnyPlayer.face.type = Face.BUNNY;
			bunnyPlayer.tail.type = Tail.RABBIT;
			bunnyPlayer.ears.type = Ears.BUNNY;
			bunnyPlayer.lowerBody.type = LowerBody.BUNNY;

			assertThat(bunnyPlayer.bunnyScore(), greaterThan(0));
		}

		[Test]
		public function testHarpyScore():void
		{
			var harpyPlayer:Player = new Player();
			harpyPlayer.arms.type = Arms.HARPY;
			harpyPlayer.hair.type = Hair.FEATHER;
			harpyPlayer.wings.type = Wings.FEATHERED_LARGE;
			harpyPlayer.tail.type = Tail.HARPY;
			harpyPlayer.lowerBody.type = LowerBody.HARPY;

			assertThat(harpyPlayer.harpyScore(), greaterThan(0));
		}

		[Test]
		public function testKangaScore():void
		{
			var kangaPlayer:Player = new Player();
			createCock(CockTypesEnum.KANGAROO, kangaPlayer);
			kangaPlayer.ears.type = Ears.KANGAROO;
			kangaPlayer.tail.type = Tail.KANGAROO;
			kangaPlayer.face.type = Face.KANGAROO;
			kangaPlayer.lowerBody.type = LowerBody.KANGAROO;
			kangaPlayer.skin.type = Skin.FUR;

			assertThat(kangaPlayer.kangaScore(), greaterThan(0));
		}

		[Test]
		public function testSheepScore():void
		{
			var sheepPlayer:Player = new Player();
			sheepPlayer.ears.type = Ears.SHEEP;
			sheepPlayer.horns.type = Horns.SHEEP;
			sheepPlayer.tail.type = Tail.SHEEP;
			sheepPlayer.lowerBody.setProps({type: LowerBody.CLOVEN_HOOFED, legCount: 2});
			sheepPlayer.hair.type = Hair.WOOL;
			sheepPlayer.skin.type = Skin.WOOL;

			assertThat(sheepPlayer.sheepScore(), greaterThan(0));
		}

		[Test]
		public function testSharkScore():void
		{
			var sharkPlayer:Player = new Player();
			sharkPlayer.face.type = Face.SHARK_TEETH;
			sharkPlayer.gills.type = Gills.FISH;
			sharkPlayer.rearBody.type = RearBody.SHARK_FIN;
			sharkPlayer.tail.type = Tail.SHARK;

			assertThat(sharkPlayer.sharkScore(), greaterThan(0));
		}

		[Test]
		public function testMutantScore():void
		{
			mutantPlayer.face.type = Face.WOLF;
			mutantPlayer.tail.type = Tail.DRACONIC;
			mutantPlayer.skin.type = Skin.PLAIN;

			assertThat(mutantPlayer.mutantScore(), greaterThan(0));
		}

		[Test]
		public function testHorseMutantScore():void
		{
			mutantPlayer.face.type = Face.HORSE;
			mutantPlayer.tail.type = Tail.HORSE;
			mutantPlayer.skin.type = Skin.FUR;

			assertThat(mutantPlayer.mutantScore(), greaterThan(0));
		}

		[Test]
		public function testDogMutantScore():void
		{
			mutantPlayer.face.type = Face.DOG;
			mutantPlayer.tail.type = Tail.DOG;
			mutantPlayer.skin.type = Skin.FUR;

			assertThat(mutantPlayer.mutantScore(), greaterThan(0));
		}

		[Test]
		public function testSalamanderScore():void
		{
			var salamanderPlayer:Player = new Player();
			createPerk(PerkLib.Lustzerker, salamanderPlayer);
			createCock(CockTypesEnum.LIZARD, salamanderPlayer);
			salamanderPlayer.arms.type = Arms.SALAMANDER;
			salamanderPlayer.lowerBody.type = LowerBody.SALAMANDER;
			salamanderPlayer.tail.type = Tail.SALAMANDER;

			assertThat(salamanderPlayer.salamanderScore(), greaterThan(0));
		}

		[Test]
		public function testSirenScore():void
		{
			var sirenPlayer:Player = new Player();
			sirenPlayer.createVagina();
			sirenPlayer.face.type = Face.SHARK_TEETH;
			sirenPlayer.tail.type = Tail.SHARK;
			sirenPlayer.wings.type = Wings.FEATHERED_LARGE;
			sirenPlayer.arms.type = Arms.HARPY;

			assertThat(sirenPlayer.sirenScore(), greaterThan(0));
		}

		[Test]
		public function testPigScore():void
		{
			var pigPlayer:Player = new Player();
			createCock(CockTypesEnum.PIG, pigPlayer);
			pigPlayer.ears.type = Ears.PIG;
			pigPlayer.tail.type = Tail.PIG;
			pigPlayer.face.type = Face.PIG;
			pigPlayer.lowerBody.type = LowerBody.CLOVEN_HOOFED;

			assertThat(pigPlayer.pigScore(), greaterThan(0));
		}

		[Test]
		public function testSatyrScore():void
		{
			var satyrPlayer:Player = new Player();
			satyrPlayer.lowerBody.type = LowerBody.CLOVEN_HOOFED;
			satyrPlayer.tail.type = Tail.GOAT;
			satyrPlayer.ears.type = Ears.ELFIN;
			satyrPlayer.face.type = Face.HUMAN;
			satyrPlayer.createCock();
			satyrPlayer.balls = 2;
			satyrPlayer.ballSize = 3;

			assertThat(satyrPlayer.satyrScore(), greaterThanOrEqualTo(4)); // There was an issue with the satyrScore producing a too low score
		}

		[Test]
		public function testRhinoScore():void
		{
			var rhinoPlayer:Player = new Player();
			createCock(CockTypesEnum.RHINO, rhinoPlayer);
			rhinoPlayer.ears.type = Ears.RHINO;
			rhinoPlayer.tail.type = Tail.RHINO;
			rhinoPlayer.face.type = Face.RHINO;
			rhinoPlayer.horns.type = Horns.RHINO;
			rhinoPlayer.skin.tone = "gray";

			assertThat(rhinoPlayer.rhinoScore(), greaterThan(0));
		}

		[Test]
		public function testEchidnaScore():void
		{
			var echidnaPlayer:Player = new Player();
			createCock(CockTypesEnum.ECHIDNA, echidnaPlayer);
			echidnaPlayer.ears.type = Ears.ECHIDNA;
			echidnaPlayer.tail.type = Tail.ECHIDNA;
			echidnaPlayer.face.type = Face.ECHIDNA;
			echidnaPlayer.tongue.type = Tongue.ECHIDNA;
			echidnaPlayer.lowerBody.type = LowerBody.ECHIDNA;
			echidnaPlayer.skin.type = Skin.FUR;

			assertThat(echidnaPlayer.echidnaScore(), greaterThan(0));
		}

		[Test]
		public function testDeerScore():void
		{
			var deerPlayer:Player = new Player();
			createCock(CockTypesEnum.HORSE, deerPlayer);
			deerPlayer.ears.type = Ears.DEER;
			deerPlayer.tail.type = Tail.DEER;
			deerPlayer.face.type = Face.DEER;
			deerPlayer.lowerBody.type = LowerBody.CLOVEN_HOOFED;
			deerPlayer.horns.setProps({type: Horns.ANTLERS, value: 4});
			deerPlayer.skin.type = Skin.FUR;

			assertThat(deerPlayer.deerScore(), greaterThan(0));
		}

		[Test]
		public function testDragonneScore():void
		{
			var dragonnePlayer:Player = new Player();
			dragonnePlayer.face.type = Face.CAT;
			dragonnePlayer.ears.type = Ears.CAT;
			dragonnePlayer.tail.type = Tail.CAT;
			dragonnePlayer.tongue.type = Tongue.DRACONIC;
			dragonnePlayer.wings.type = Wings.DRACONIC_LARGE;
			dragonnePlayer.lowerBody.type = LowerBody.CAT;
			dragonnePlayer.skin.type = Skin.DRAGON_SCALES;

			assertThat(dragonnePlayer.dragonneScore(), greaterThan(0));
		}

		[Test]
		public function testManticoreScore():void
		{
			var manticorePlayer:Player = new Player();
			manticorePlayer.face.type = Face.CAT;
			manticorePlayer.ears.type = Ears.CAT;
			manticorePlayer.tail.type = Tail.SCORPION;
			manticorePlayer.lowerBody.type = LowerBody.CAT;
			manticorePlayer.horns.type = Horns.DEMON;
			manticorePlayer.wings.type = Wings.BAT_LIKE_LARGE;
			manticorePlayer.skin.type = Skin.FUR;

			assertThat(manticorePlayer.manticoreScore(), greaterThan(0));
		}

		[Test]
		public function testBimboScore():void
		{
			var bimboPlayer:Player = new Player();
			createPerk(PerkLib.BimboBrains, bimboPlayer);
			createPerk(PerkLib.BimboBody, bimboPlayer);
			bimboPlayer.createVagina(true, Vagina.WETNESS_SLICK);
			bimboPlayer.createBreastRow(10);
			bimboPlayer.setArmor(kGAMECLASS.armors.BIMBOSK);
			kGAMECLASS.flags[kFLAGS.BIMBOSKIRT_MINIMUM_LUST] = 30;
			bimboPlayer.femininity = 100;
			bimboPlayer.hips.rating = 10;
			bimboPlayer.butt.rating = 10;
			bimboPlayer.tone = 10;
			bimboPlayer.hair.setProps({color: "platinum blonde", length: 12});
			bimboPlayer.inte = 10;

			assertThat(bimboPlayer.bimboScore(), greaterThan(0));
		}

		[Test]
		public function hpChangeNotifyNoChange(): void {
			cut.HPChangeNotify(0);

			assertThat(cut.collectedOutput, emptyArray());
		}

		[Test]
		public function hpChangeNotifyNoChangeOverMaxHp(): void {
			cut.HP = HP_OVER_HEAL;

			cut.HPChangeNotify(0);

			assertThat(cut.collectedOutput, hasItem(startsWith("You're as healthy as you can be.")));
		}

		[Test]
		public function hpChangeNotifyHeal(): void {
			cut.HPChangeNotify(1);

			assertThat(cut.collectedOutput, hasItem(startsWith("You gain")));
		}

		[Test]
		public function hpChangeNotifyHealOverMaxHp(): void {
			cut.HP = HP_OVER_HEAL;

			cut.HPChangeNotify(1);

			assertThat(cut.collectedOutput, hasItem(startsWith("Your HP maxes out at")));
		}

		[Test]
		public function hpChangeNotifyDamage(): void {
			cut.HPChangeNotify(-1);

			assertThat(cut.collectedOutput, hasItem(containsString("damage.")));
		}

		[Test]
		public function hpChangeNotifyDamageHpBelowZero(): void {
			cut.HP = -1;

			cut.HPChangeNotify(-1);

			assertThat(cut.collectedOutput, hasItem(containsString("damage, dropping your HP to 0.")));
		}

		[Test]
		public function hpChangeZeroNoDelta(): void {
			assertThat(cut.HPChange(0, false), equalTo(0));
		}

		[Test]
		public function hpChangeHealerBoost(): void {
			cut.createPerk(PerkLib.HistoryHealer, 0, 0, 0, 0);

			assertThat(cut.HPChange(100, false), equalTo(120));
		}

		[Test]
		public function hpChangeNurseOutfitBoost(): void {
			cut.setArmor(new ArmorLib().NURSECL);

			assertThat(cut.HPChange(100, false), equalTo(110));
		}

		[Test]
		public function hpChangeOverHeal(): void {
			assertThat(cut.HPChange(HP_OVER_HEAL, false), equalTo(249));
		}

		[Test]
		public function hpChangeOverHealPlayerHp(): void {
			cut.HPChange(HP_OVER_HEAL, false);

			assertThat(cut.HP, equalTo(PLAYER_MAX_HP));
		}

		[Test]
		public function hpChangeOverHealDisplayHpChange(): void {
			cut.HPChange(HP_OVER_HEAL, true);

			assertThat(cut.calls, arrayWithSize(1));
			assertThat(cut.calls, hasItem(equalTo(HP_OVER_HEAL)));
		}

		[Test]
		public function hpChangePlayerHpOverMaxDelta(): void {
			cut.HP = HP_OVER_HEAL;

			assertThat(cut.HPChange(HP_OVER_HEAL, false), equalTo(0));
		}

		[Test]
		public function hpChangePlayerHpOverMaxPlayerHp(): void {
			cut.HP = HP_OVER_HEAL;

			cut.HPChange(HP_OVER_HEAL, false);

			assertThat(cut.HP, equalTo(1000));
		}

		[Test]
		public function hpChangePlayerHpOverMaxDisplayHpChange(): void {
			cut.HP = HP_OVER_HEAL;

			cut.HPChange(HP_OVER_HEAL, true);

			assertThat(cut.calls, arrayWithSize(1));
			assertThat(cut.calls, hasItem(equalTo(HP_OVER_HEAL)));
		}

		[Test]
		public function hpChangeHealDisplayHpChange(): void {
			cut.HPChange(1, true);

			assertThat(cut.calls, arrayWithSize(1));
			assertThat(cut.calls, hasItem(equalTo(1)));
		}

		[Test]
		public function hpChangeHealPlayerHP(): void {
			cut.HPChange(1, true);

			assertThat(cut.HP, equalTo(2));
		}

		[Test]
		public function hpChangeDamageDisplayHpChange(): void {
			cut.HP = 50;

			cut.HPChange(-1, true);

			assertThat(cut.calls, arrayWithSize(1));
			assertThat(cut.calls, hasItem(equalTo(-1)));
		}

		[Test]
		public function hpChangeDamagePlayerHp(): void {
			cut.HP = 50;

			cut.HPChange(-1, false);

			assertThat(cut.HP, equalTo(49));
		}

		[Test]
		public function hpChangeDamageBelowZeroDisplayHpChange(): void {
			cut.HPChange(-HP_OVER_HEAL, true);

			assertThat(cut.calls, arrayWithSize(1));
			assertThat(cut.calls, hasItem(equalTo(-HP_OVER_HEAL)));
		}

		[Test]
		public function hpChangeDamageBelowZeroPlayerHp(): void {
			cut.HPChange(-HP_OVER_HEAL, false);

			assertThat(cut.HP, equalTo(0));
		}
	}
}

import classes.Player;

/**
 * Yes, i'm a lazy git.
 */
class DummyPlayer extends Player {
	public var calls:Vector.<Number> = new Vector.<Number>();
	public var collectedOutput:Vector.<String> = new Vector.<String>();

	/**
	 * Intercept calls to HPChangeNotify so we can sense them in tests.
	 *
	 * @param	changeNum the value of the HP change?
	 */
	override public function HPChangeNotify(changeNum:Number):void {
		calls.push(changeNum);
		super.HPChangeNotify(changeNum);
	}

	/**
	 * Redirect output to a vector instead of displaying it on the GUI.
	 * @param	text to store
	 */
	override protected function outputText(text:String):void {
		collectedOutput.push(text);
	}
}


code:
package classes{
	import org.flexunit.asserts.*;
	import org.hamcrest.assertThat;
	import org.hamcrest.core.*;
	import org.hamcrest.number.*;
	import org.hamcrest.object.*;
	import org.hamcrest.text.*;

	import flash.display.Stage;

	import classes.CoC;
	import classes.Scenes.Inventory;
	import classes.Saves;
	import classes.helper.StageLocator;
	import classes.GlobalFlags.kGAMECLASS;

	public class SavesTest {
		private static const TEST_VERSION:String = "test";
		private static const TEST_SAVE_GAME:String = "test";

		private static const CLIT_LENGTH:Number = 5;
		private static const VAGINA_RECOVERY_PROGRESS:int = 6;

		private static const NUMBER_OF_COCKS:int = 3;
		private static const TEST_SOCK:String = "testSock";
		private static const VIRIDIAN_SOCK:String = "viridian";

		private var player:Player;
		private var cut:Saves;

		[BeforeClass]
		public static function setUpClass():void {
			kGAMECLASS = new CoC(StageLocator.stage);
		}

		[Before]
		public function setUp():void {
			player = new Player();

			createPlayerCocks();

			kGAMECLASS.player = player;
			kGAMECLASS.ver = TEST_VERSION;
			kGAMECLASS.version = TEST_VERSION;

			cut = new Saves(kGAMECLASS.gameStateDirectGet, kGAMECLASS.gameStateDirectSet);
			kGAMECLASS.inventory = new Inventory(cut);

			saveGame();
		}

		private function saveGame():void {
			cut.saveGame(TEST_SAVE_GAME, false);
		}

		private function loadGame():void {
			kGAMECLASS.player = new Player();

			cut.loadGame(TEST_SAVE_GAME);

			this.player = kGAMECLASS.player;
		}

		private function createPlayerCocks():void {
			player.removeCock(0, int.MAX_VALUE);

			player.createCock(1, 1, CockTypesEnum.CAT);
			player.createCock(2, 2, CockTypesEnum.DOG);
			player.createCock(3, 3, CockTypesEnum.HORSE);
		}

		[Test]
		public function testClitLengthSaved():void {
			player.createVagina();
			player.setClitLength(CLIT_LENGTH);
			cut.saveGame(TEST_SAVE_GAME, false);
			player.setClitLength(0);

			cut.loadGame(TEST_SAVE_GAME);

			assertThat(kGAMECLASS.player.getClitLength(), equalTo(CLIT_LENGTH));
		}

		[Test]
		public function testRecoveryProgressSaved():void {
			player.createVagina();
			player.vaginas[0].recoveryProgress = VAGINA_RECOVERY_PROGRESS;
			cut.saveGame(TEST_SAVE_GAME, false);
			player.vaginas[0].resetRecoveryProgress();

			cut.loadGame(TEST_SAVE_GAME);

			assertThat(kGAMECLASS.player.vaginas[0].recoveryProgress, equalTo(VAGINA_RECOVERY_PROGRESS));
		}

		[Test]
		public function playerHasThreeCocks():void {
			assertThat(player.cocks.length, equalTo(NUMBER_OF_COCKS));
		}

		[Test]
		public function cocksAreStored():void {
			player.removeCock(0, 3);
			assertThat(player.cocks.length, equalTo(0));

			cut.loadGame(TEST_SAVE_GAME);

			assertThat(kGAMECLASS.player.cocks.length, equalTo(NUMBER_OF_COCKS));
		}

		[Test]
		public function cocksLoadOrder():void {
			player.removeCock(0, 3);
			assertThat(player.cocks.length, equalTo(0));

			cut.loadGame(TEST_SAVE_GAME);

			assertThat(kGAMECLASS.player.cocks[0].cockType, equalTo(CockTypesEnum.CAT));
			assertThat(kGAMECLASS.player.cocks[2].cockType, equalTo(CockTypesEnum.HORSE));
		}

		[Test]
		public function cockLoadViridianSockGrantsLustyRegenerationPerk():void {
			player.cocks[0].sock = VIRIDIAN_SOCK;

			saveGame();
			loadGame();

			assertThat(player.hasPerk(PerkLib.LustyRegeneration), equalTo(true));
		}

		[Test]
		public function cockLoadNoLustyRegenerationPerkWithoutViridianSock():void {
			player.cocks[0].sock = TEST_SOCK;

			saveGame();
			loadGame();

			assertThat(player.hasPerk(PerkLib.LustyRegeneration), equalTo(false));
		}
	}
}


code:
package classes.Scenes.Areas.Bog
{
	import org.flexunit.asserts.*;
	import org.hamcrest.assertThat;
	import org.hamcrest.core.*;
	import org.hamcrest.number.*;
	import org.hamcrest.object.*;
	import org.hamcrest.text.*;
	import org.hamcrest.collection.*;

	import classes.CoC;
	import classes.GlobalFlags.kGAMECLASS;
	import classes.Player;
	import classes.helper.StageLocator;

	public class PhoukaSceneTest
	{
		private static const SCENE_TEXT:String = "You scream as the ";

		private var cut:SceneForTest;
		private var player:Player;

		[BeforeClass]
		public static function setUpClass():void
		{
			kGAMECLASS = new CoC(StageLocator.stage);
		}

		[Before]
		public function setUp():void
		{
			player = new Player();
			player.createVagina();
			kGAMECLASS.player = player;

			cut = new SceneForTest(kGAMECLASS.pregnancyProgress);
		}

		[Test(description="Exposes bug #1116, sex scene skipped")]
		public function doNotClearSexScene():void {
			cut.horseScene();

			assertThat(cut.collectedOutput, hasItem(startsWith(SCENE_TEXT)));
		}
	}
}

import classes.Scenes.Areas.Bog.PhoukaScene;
import classes.Scenes.PregnancyProgression;

class SceneForTest extends PhoukaScene {
	public var collectedOutput:Vector.<String> = new Vector.<String>();

	public function SceneForTest(pregnancyProgression:PregnancyProgression) {
		super(pregnancyProgression);
	}

	public function horseScene():void {
		this.phoukaSexHorseChoice();
	}

	override protected function outputText(output:String):void {
		collectedOutput.push(output);
	}

	override protected function clearOutput():void {
		collectedOutput = new Vector.<String>();
	}
}


code:
package classes.Scenes.Areas
{
	import classes.Scenes.Areas.Bog.PhoukaSceneTest;

	[Suite]
	[RunWith("org.flexunit.runners.Suite")]
	public class BogSuit
	{
		public var phoukaSceneTest:PhoukaSceneTest
	}
}


code:
package classes.Scenes.Areas
{
	import classes.Scenes.PregnancyProgression;
	import classes.helper.DummyOutput;
	import org.flexunit.asserts.*;
	import org.hamcrest.assertThat;
	import org.hamcrest.core.*;
	import org.hamcrest.number.*;
	import org.hamcrest.object.*;
	import org.hamcrest.text.*;
	import org.hamcrest.collection.*;

	import classes.CoC;
	import classes.GlobalFlags.kGAMECLASS;
	import classes.helper.StageLocator;

	public class DeepWoodsTest
	{
		private var cut:DeepWoods;
		private var forest:Forest;

		[Before]
		public function setUp():void
		{
			this.forest = new Forest(new PregnancyProgression(), new DummyOutput());
		}

		[Test(expected='ArgumentError')]
		public function throwExceptionOnNullForest():void
		{
			new DeepWoods(null);
		}

		[Test(expected='ArgumentError')]
		public function throwExceptionOnUndefinedForest():void
		{
			new DeepWoods(undefined);
		}

		[Test]
		public function createDeepwoodsWithValidForest():void
		{
			new DeepWoods(forest);
		}
	}
}


code:
package classes.Scenes.Areas.Forest
{
	import org.flexunit.asserts.*;
	import org.hamcrest.assertThat;
	import org.hamcrest.core.*;
	import org.hamcrest.number.*;
	import org.hamcrest.object.*;
	import org.hamcrest.text.*;
	import org.hamcrest.collection.*;

	import classes.CoC;
	import classes.GlobalFlags.kGAMECLASS;
	import classes.Player;
	import classes.helper.StageLocator;

	public class FaerieTest
	{
		private var cut:FaerieForTest;
		private var player:Player;

		public function FaerieTest()
		{
		}

		[BeforeClass]
		public static function setUpClass():void
		{
			kGAMECLASS = new CoC(StageLocator.stage);
		}

		[Before]
		public function setUp():void
		{
			player = new Player();
			kGAMECLASS.player = player;

			cut = new FaerieForTest();
		}

		[Test(description = "Wrong order of checks causes an exception to be thrown")]
		public function doNothingWithNoVagina():void
		{
			cut.testFaerieDoNothing();
		}
	}
}

import classes.Scenes.Areas.Forest.Faerie;

class FaerieForTest extends Faerie {
	public function testFaerieDoNothing():void {
		super.faerieDoNothing();
	}
}


code:
package classes.Scenes.Areas
{
	import classes.Scenes.Areas.Forest.FaerieTest;

	[Suite]
	[RunWith("org.flexunit.runners.Suite")]
	public class ForestSuit
	{
		public var faerieTest:FaerieTest;
	}
}


code:
package classes.Scenes.Areas.Mountain
{
    import org.flexunit.asserts.*;
	import org.hamcrest.assertThat;
	import org.hamcrest.core.*;
	import org.hamcrest.number.*;
	import org.hamcrest.object.*;
	import org.hamcrest.text.*;
	import org.hamcrest.collection.*;

	import classes.CoC;
	import classes.GlobalFlags.kGAMECLASS;
	import classes.Player;
	import classes.PregnancyStore;
	import classes.helper.StageLocator;
	public class InfestedHellhoundSceneTest
	{
		private var cut:InfestedHellhoundScene;
		private var player:Player;

		public function InfestedHellhoundSceneTest()
		{

		}

		[BeforeClass]
		public static function setUpClass():void {
			kGAMECLASS = new CoC(StageLocator.stage);
		}

		[Before]
        public function setUp():void {
			player = new Player();
			player.createVagina();

			kGAMECLASS.player = player;

			cut = new InfestedHellhoundScene();
        }

		/**
		 * Test to expose issue 'Worm pregnancy override bug' #458
		 */
		[Test]
		public function checkThatWormsDoNotClearPregnancy():void {
			player.knockUpForce(PregnancyStore.PREGNANCY_IMP, PregnancyStore.INCUBATION_IMP);

			cut.infestedHellhoundLossRape();

			assertThat(player.pregnancyType, equalTo(PregnancyStore.PREGNANCY_IMP));
		}

		[Test]
		public function wormPregnancyIfNotPregnant():void {
			assertThat(player.isPregnant(), equalTo(false)); // guard assert

			cut.infestedHellhoundLossRape();

			assertThat(player.pregnancyType, equalTo(PregnancyStore.PREGNANCY_WORM_STUFFED));
		}
	}
}


code:
package classes.Scenes.Areas
{
	import classes.Scenes.Areas.Mountain.InfestedHellhoundSceneTest;

	[Suite]
	[RunWith("org.flexunit.runners.Suite")]
	public class MountainSuit
	{
		public var infestedHellhoundSceneTest:InfestedHellhoundSceneTest;
	}
}


code:
package classes.Scenes
{
	import classes.Scenes.Areas.BogSuit;
	import classes.Scenes.Areas.DeepWoodsTest;
	import classes.Scenes.Areas.ForestSuit;
	import classes.Scenes.Areas.MountainSuit;

	[Suite]
	[RunWith("org.flexunit.runners.Suite")]
	public class AreasSuit
	{
		public var mountainSuit:MountainSuit;
		public var forestSuit:ForestSuit;
		public var bogSuit:BogSuit;

		public var deepWoodsTest:DeepWoodsTest;
	}
}


code:
package classes.Scenes.NPCs
{
	import classes.DefaultDict;
    import org.flexunit.asserts.*;
	import org.hamcrest.assertThat;
	import org.hamcrest.core.*;
	import org.hamcrest.number.*;
	import org.hamcrest.object.*;
	import org.hamcrest.text.*;
	import org.hamcrest.collection.*;

	import classes.helper.StageLocator;

	import classes.GlobalFlags.kGAMECLASS;
	import classes.Player;
	import classes.CoC;
	import classes.Cock;
	import classes.PregnancyStore;
	import classes.Scenes.NPCs.IsabellaFollowerScene;
	import classes.PerkLib;
	import classes.CockTypesEnum;
	import classes.helper.FireButtonEvent;
	import classes.CoC;
	import classes.Output;

	public class IsabellaFollowerSceneTest
	{
		private var isabellaScene : IsabellaScene;
		private var cut:IsabellaFollowerSceneForTest;
		private var player:Player;
		private var fireButon:FireButtonEvent;

		private static const INCUBATION_DELTA : int = 10;
		/**
		 * This is used to skip time to the last pregnancy stage
		 */
		private static const ADVANCE_PREGNANCY : int = PregnancyStore.INCUBATION_ISABELLA - (IsabellaScene.ISABELLA_PREGNANCY_LAST_STAGE - INCUBATION_DELTA);

		public function IsabellaFollowerSceneTest()
		{
		}

		[BeforeClass]
		public static function setUpClass():void {
			kGAMECLASS = new CoC(StageLocator.stage);
		}

		private function setUpIsabella() : void {
			isabellaScene = new IsabellaScene();
			cut = new IsabellaFollowerSceneForTest();
		}

		[Before]
        public function setUp():void {
			setUpIsabella();

			isabellaScene.pregnancy.knockUpForce();

			// preggers time!
			isabellaScene.pregnancy.knockUpForce(PregnancyStore.PREGNANCY_PLAYER, PregnancyStore.INCUBATION_ISABELLA)

			player = new Player();
			kGAMECLASS.player = player;

			fireButon = new FireButtonEvent(kGAMECLASS.mainView, Output.MAX_BUTTON_INDEX);
        }

		[Test]
		public function isabellaAppearance_withUnsupportedPregnancyType() : void
		{
			isabellaScene.pregnancy.knockUpForce()
			isabellaScene.pregnancy.knockUpForce(PregnancyStore.PREGNANCY_IMP, PregnancyStore.INCUBATION_ISABELLA)

			cut.isaAppearance();

			assertThat(cut.collectedOutput, hasItem(equalTo(IsabellaFollowerScene.DESC_APPEAR_NO_EVENTS_FOR_PREG_TYPE)));
		}

		[Test]
		public function isabellaAppearance_playerLowCumQuantity() : void
		{
			isabellaScene.pregnancy.knockUpForce()
			isabellaScene.pregnancy.knockUpForce(PregnancyStore.PREGNANCY_IMP, PregnancyStore.INCUBATION_ISABELLA)

			player.cocks = new Vector.<Cock>();
			assertThat(player.cumQ(), equalTo(0)); // guard assert

			cut.isaAppearance();

			assertThat(cut.collectedOutput, not(hasItem(equalTo(IsabellaFollowerScene.DESC_APPEAR_PLAYER_HIGH_CUMQ))));
		}

		[Test]
		public function isabellaAppearance_playerHighCumQuantity() : void
		{
			isabellaScene.pregnancy.knockUpForce()
			isabellaScene.pregnancy.knockUpForce(PregnancyStore.PREGNANCY_IMP, PregnancyStore.INCUBATION_ISABELLA)
			//TODO Use mocking library so we can avoid stuff like this
			player.createPerk(PerkLib.FerasBoonSeeder, 0, 0, 0, 0);
			player.createCock(6, 1, CockTypesEnum.HUMAN);
			assertThat(player.cumQ(), greaterThan(500)); // guard assert

			cut.isaAppearance();

			assertThat(cut.collectedOutput, hasItem(equalTo(IsabellaFollowerScene.DESC_APPEAR_PLAYER_HIGH_CUMQ)));
		}

		[Test]
		public function isabellaAppearance_whenNotPregnant() : void
		{
			isabellaScene.pregnancy.knockUpForce();

			cut.isaAppearance();

			assertThat(cut.collectedOutput, hasItem(equalTo(IsabellaFollowerScene.DESC_APPEAR_EVENT_NOT_PREGNANT)));
		}

		[Test]
		public function isabellaAppearance_firstStageOfPregnancy() : void
		{
			cut.isaAppearance();

			assertThat(cut.collectedOutput, hasItem(equalTo(IsabellaFollowerScene.DESC_APPEAR_EVENT_FIRST_STAGE_PREGNANT)));
		}

		[Test]
		public function isabellaAppearance_playerLowLibido() : void
		{
			player.lib = 0;

			cut.isaAppearance();

			assertThat(cut.collectedOutput, not(hasItem(equalTo(IsabellaFollowerScene.DESC_APPEAR_PLAYER_HIGH_LIBIDO))));
		}

		[Test]
		public function isabellaAppearance_playerHighLibido() : void
		{
			player.lib = 100;

			cut.isaAppearance();

			assertThat(cut.collectedOutput, hasItem(equalTo(IsabellaFollowerScene.DESC_APPEAR_PLAYER_HIGH_LIBIDO)));
		}

		[Test]
		public function isabellaAppearance_lastStageOfPregnancy() : void
		{
			for (var i : int = 0; i < ADVANCE_PREGNANCY; i++ ) {
				isabellaScene.pregnancy.pregnancyAdvance();
			}

			cut.isaAppearance();

			assertThat(cut.collectedOutput, hasItem(containsString(IsabellaFollowerScene.DESC_APPEAR_EVENT_LAST_STAGE_PREGNANT)));
		}

		private function createTentaCocks(count:int, length:Number) :void {
			for (var i:int = 0; i < count; i++){
				player.createCock(length, 1, CockTypesEnum.TENTACLE);
			}
		}

		[Test]
		public function isabellaTentacleSexNotAvailableWithShortCocks() : void {
			player.lust = 70;
			createTentaCocks(3, 23);

			cut.campSexMenu();

			assertThat(cut.collectedOutput, not(hasItem(containsString("numerous tentacles"))));
		}

		[Test]
		public function isabellaTentacleSex() : void {
			player.lust = 70;

			createTentaCocks(3, 24);

			cut.campSexMenu();
			fireButon.fireButtonClick(4);

			assertThat(cut.collectedOutput, hasItem(containsString("numerous tentacles")));
			assertThat(cut.collectedOutput, hasItem(containsString("exposing your monstrous tentacle-cocks")));
		}

		[Test]
		public function isabellaTentacleSexNotAvailableWithTooFewTentacles() : void {
			player.lust = 70;
			createTentaCocks(2, 24);

			cut.campSexMenu();

			assertThat(cut.collectedOutput, not(hasItem(containsString("numerous tentacles"))));
		}
	}
}

import classes.Scenes.NPCs.IsabellaFollowerScene;

/**
 * Class to collect scene text output so the test can compare it to expected values.
 */
class IsabellaFollowerSceneForTest extends IsabellaFollowerScene {
	public var collectedOutput:Vector.<String> = new Vector.<String>();

	override protected function outputText(output:String):void {
		collectedOutput.push(output);
	}

	/**
	 * This is to avoid making the appearance function public
	 */
	public function isaAppearance() : void {
		this.isabellasAppearance();
	}

	public function campSexMenu() : void {
		this.campIzzySexMenu();
	}

	override protected function isabellasAppearance():void {
		super.isabellasAppearance();
	}

	override protected function campIzzySexMenu() : void {
		super.campIzzySexMenu();
	}
 }


code:
package classes.Scenes.NPCs
{
	import org.flexunit.asserts.*;
	import org.hamcrest.assertThat;
	import org.hamcrest.core.*;
	import org.hamcrest.number.*;
	import org.hamcrest.object.*;
	import org.hamcrest.text.*;
	import org.hamcrest.collection.*;

	import classes.helper.StageLocator;

	import classes.GlobalFlags.kGAMECLASS;
	import classes.Player;
	import classes.CoC;
	import classes.PregnancyStore;
	import classes.Scenes.NPCs.IsabellaFollowerScene;

	public class IsabellaSceneTest
	{
		private var cut : IsabellaScene;
		private var player:Player;

		private static const INCUBATION_DELTA : int = 10;
		/**
		 * This is used to skip time to the last pregnancy stage
		 */
		private static const ADVANCE_PREGNANCY : int = PregnancyStore.INCUBATION_ISABELLA - (IsabellaScene.ISABELLA_PREGNANCY_LAST_STAGE - INCUBATION_DELTA);

		public function IsabellaSceneTest()
		{
		}

		[BeforeClass]
		public static function setUpClass():void {
			kGAMECLASS = new CoC(StageLocator.stage);
		}

		private function setUpIsabella() : void {
			cut = new IsabellaScene();
		}

		[Before]
        public function setUp():void {
			setUpIsabella();

			cut.pregnancy.knockUpForce();

			// preggers time!
			cut.pregnancy.knockUpForce(PregnancyStore.PREGNANCY_PLAYER, PregnancyStore.INCUBATION_ISABELLA)

			player = new Player();
			kGAMECLASS.player = player;
        }

		[Test]
		public function isabellaNotPregnant_afterPregnancyClear() : void
		{
			cut.pregnancy.knockUpForce();

			// law of demeter violation ahoi!
			assertThat(cut.pregnancy.isPregnant, equalTo(false));
		}

		[Test]
		public function isabellaPregnant_afterKnockUp() : void
		{
			assertThat(cut.pregnancy.isPregnant, equalTo(true));
		}

		[Test]
		public function isabellaIncubationProgress_afterKnockUp() : void
		{
			assertThat(cut.pregnancy.incubation, equalTo(PregnancyStore.INCUBATION_ISABELLA));
		}

		[Test]
		public function isabellaIncubationProgress_lastStageOfPregnancy() : void
		{
			for (var i : int = 0; i < ADVANCE_PREGNANCY; i++ ) {
				cut.pregnancy.pregnancyAdvance();
			}

			assertThat(cut.pregnancy.incubation, between(0, IsabellaScene.ISABELLA_PREGNANCY_LAST_STAGE));
		}

		[Test]
		public function isabellaPregnancyEventStAGE_withUnsupportedPregnancyType() : void
		{
			cut.pregnancy.knockUpForce()

			cut.pregnancy.knockUpForce(PregnancyStore.PREGNANCY_IMP, PregnancyStore.INCUBATION_ISABELLA)

			assertThat(cut.pregnancy.event, 1);
		}

		[Test]
		public function isabellaPregnancyEventStAGE_afterKnockUp() : void
		{
			cut.pregnancy.knockUpForce()

			cut.pregnancy.knockUpForce(PregnancyStore.PREGNANCY_PLAYER, PregnancyStore.INCUBATION_ISABELLA)

			assertThat(cut.pregnancy.event, 2);
		}

		[Test]
		public function isabellaPregnancyEventStAGE_lastStageOfPregnancy() : void
		{
			for (var i : int = 0; i < ADVANCE_PREGNANCY; i++ ) {
				cut.pregnancy.pregnancyAdvance();
			}

			assertThat(cut.pregnancy.event, equalTo(10));
		}
	}
}


code:
package classes.Scenes.NPCs{
	import classes.Scenes.PregnancyProgression;
	import classes.helper.DummyOutput;
    import org.flexunit.asserts.*;
	import org.hamcrest.assertThat;
	import org.hamcrest.core.*;
	import org.hamcrest.number.*;
	import org.hamcrest.object.*;
	import org.hamcrest.text.*;
	import org.hamcrest.collection.*;

	import classes.helper.StageLocator;

	import classes.GlobalFlags.kGAMECLASS;
	import classes.Player;
	import classes.CoC;

    public class JojoSceneTest {
		private const ALWAYS_EXPECTED_TEXT:String = "You crawl further up his body and grin down at him as you press";
		private const WET_ONLY_EXPECTED_TEXT:String = "You moan as he works, your juices flowing liberally across his muzzle and into his";

        private var cut:JojoSceneForTest;
		private var player:Player;

		[BeforeClass]
		public static function setUpClass():void {
			kGAMECLASS = new CoC(StageLocator.stage);
		}

        [Before]
        public function setUp():void {
			cut = new JojoSceneForTest(new PregnancyProgression(), new DummyOutput());
			player = new Player();
			kGAMECLASS.player = player;
        }

		[Test]
        public function testCorruptJojoVaginalSmotherNotWetEnough():void {
			player.createVagina();

			cut.testCorruptJojoVaginalSmother();

			assertThat(cut.collectedOutput, hasItem(startsWith(ALWAYS_EXPECTED_TEXT)));
			assertThat(cut.collectedOutput, not(hasItem(startsWith(WET_ONLY_EXPECTED_TEXT))));
		}

		[Test]
        public function testCorruptJojoVaginalSmotherEnough():void {
			player.createVagina(false,5,1);

			cut.testCorruptJojoVaginalSmother();

			assertThat(cut.collectedOutput, hasItem(startsWith(ALWAYS_EXPECTED_TEXT)));
			assertThat(cut.collectedOutput, hasItem(startsWith(WET_ONLY_EXPECTED_TEXT)));
		}
    }
}

import classes.Scenes.NPCs.JojoScene;
import classes.Scenes.PregnancyProgression;
import classes.internals.GuiOutput;

class JojoSceneForTest extends JojoScene {
	public var collectedOutput:Vector.<String> = new Vector.<String>();

	public function JojoSceneForTest(pregnancyProgression:PregnancyProgression, output:GuiOutput)
	{
		super(pregnancyProgression, output);
	}

	public function testCorruptJojoVaginalSmother():void {
		corruptJojoVaginalSmother();
	}

	override protected function outputText(output:String):void {
		collectedOutput.push(output);
	}
}


code:
package classes.Scenes {

import classes.Scenes.NPCs.IsabellaSceneTest;
import classes.Scenes.NPCs.JojoSceneTest;
import classes.Scenes.NPCs.IsabellaFollowerSceneTest;

[Suite]
[RunWith("org.flexunit.runners.Suite")]
	public class NPCsSuit
	{
		 public var jojoSceneTest:JojoSceneTest;
		 public var isabellaSceneTest : IsabellaSceneTest;
		 public var isabellaFollowerSceneTest:IsabellaFollowerSceneTest;
	}
}


code:
package classes.Scenes.Places.Bazaar{
    import org.flexunit.asserts.*;
	import org.hamcrest.assertThat;
	import org.hamcrest.core.*;
	import org.hamcrest.number.*;
	import org.hamcrest.object.*;
	import org.hamcrest.text.*;
	import org.hamcrest.collection.*;

	import classes.helper.StageLocator;

	import classes.GlobalFlags.kGAMECLASS;
	import classes.Player;
	import classes.CoC;

    public class BlackCockTest {
		private const ALWAYS_EXPECTED_TEXT:String = "\n\nThe moment you think this, Harry reaches his free hand";
		private const WET_ONLY_EXPECTED_TEXT:String = "Every time you gush fluid onto his fingers he vibrates his palm, sending";

        private var cut:BlackCockForTest;
		private var player:Player;

		[BeforeClass]
		public static function setUpClass():void {
			kGAMECLASS = new CoC(StageLocator.stage);
		}

        [Before]
        public function setUp():void {
			cut = new BlackCockForTest();
			player = new Player();
			kGAMECLASS.player = player;
        }

		[Test]
        public function testHarryFuckNotWetEnough():void {
			player.createVagina();

			cut.testHaveHarryFuckYou();

			assertThat(cut.collectedOutput, hasItem(startsWith(ALWAYS_EXPECTED_TEXT)));
			assertThat(cut.collectedOutput, not(hasItem(startsWith(WET_ONLY_EXPECTED_TEXT))));
		}

		[Test]
        public function testHarryFuckWetEnough():void {
			player.createVagina(false,5,1);

			cut.testHaveHarryFuckYou();

			assertThat(cut.collectedOutput, hasItem(startsWith(ALWAYS_EXPECTED_TEXT)));
			assertThat(cut.collectedOutput, hasItem(startsWith(WET_ONLY_EXPECTED_TEXT)));
		}
    }
}

import classes.Scenes.Places.Bazaar.BlackCock;

class BlackCockForTest extends BlackCock {
	public var collectedOutput:Vector.<String> = new Vector.<String>();

	public function testHaveHarryFuckYou():void {
		haveHarryFuckYou();
	}

	override protected function outputText(output:String):void {
		collectedOutput.push(output);
	}
}


code:
package classes.Scenes.Places.Bazaar{
	import classes.Appearance;
	import classes.BodyParts.Butt;
	import classes.helper.FireButtonEvent;
	import classes.internals.RandomNumberGenerator;
    import org.flexunit.asserts.*;
	import org.hamcrest.assertThat;
	import org.hamcrest.core.*;
	import org.hamcrest.number.*;
	import org.hamcrest.object.*;
	import org.hamcrest.text.*;
	import org.hamcrest.collection.*;

	import classes.helper.StageLocator;

	import classes.GlobalFlags.kGAMECLASS;
	import classes.Player;
	import classes.CoC;
	import classes.GlobalFlags.kFLAGS;
	import classes.Output;

    public class RoxanneTest {
		private static const EVENT_ITERATIONS:int = 5;

        private var cut:RoxanneForTest;
		private var player:Player;
		private var fireButtons:FireButtonEvent;

		[BeforeClass]
		public static function setUpClass():void {
			kGAMECLASS = new CoC(StageLocator.stage);
		}

        [Before]
        public function setUp():void {
			var rng:RandomNumberGenerator = new RngMock();

			cut = new RoxanneForTest(rng);

			player = new Player();
			player.rng = rng;
			kGAMECLASS.player = player;

			fireButtons = new FireButtonEvent(kGAMECLASS.mainView, Output.MAX_BUTTON_INDEX);

			player.flags[kFLAGS.ROXANNE_TIME_WITHOUT_SEX] = 10;
			player.flags[kFLAGS.ROXANNE_DRINKING_CONTEST_LOSE_ON_PURPOSE] = 1;

			assertThat(player.ass.analLooseness, equalTo(0));
        }

		/**
		 * Many loops needed due to non-deterministic nature of buttChangeNoDisplay().
		 * @param	testFunction function to call multiple times
		 */
		private function repeatEvent(testFunction:Function):void {
			for (var i:int = 0; i < EVENT_ITERATIONS; i++) {
				testFunction();
			}
		}

		[Test]
        public function roxanneStretchLowTime():void {

			var testFunction:Function = function():void {
				cut.roxanneDrinkingContestTest();
				fireButtons.fireNextButtonEvent();
			};

			repeatEvent(testFunction);

			assertThat(kGAMECLASS.player.ass.analLooseness, equalTo(3));
			assertThat(cut.collectedOutput, hasItem(startsWith("A foot interposes itself")));
		}

		[Test]
        public function roxanneResetCounterLowTime():void {
			cut.roxanneDrinkingContestTest();
			fireButtons.fireNextButtonEvent();

			assertThat(player.flags[kFLAGS.ROXANNE_TIME_WITHOUT_SEX],equalTo(1));
			assertThat(cut.collectedOutput, hasItem(startsWith("A foot interposes itself")));
		}

		private function setRoxanneLargeSize():void {
			player.flags[kFLAGS.ROXANNE_TIME_WITHOUT_SEX] = 290;
		}

		[Test]
        public function roxanneRepeatedStretchingWithHighTime():void {
			setRoxanneLargeSize();

			var testFunction:Function = function():void {
				cut.roxanneDrinkingContestTest();
				fireButtons.fireNextButtonEvent();
				setRoxanneLargeSize();
			};

			repeatEvent(testFunction);

			assertThat(kGAMECLASS.player.ass.analLooseness, equalTo(5));
			assertThat(cut.collectedOutput, hasItem(startsWith("Gosh, Roxanne is so strong...")));
		}

		[Test]
        public function roxanneCounterResetWithHighTime():void {
			setRoxanneLargeSize();
			cut.roxanneDrinkingContestTest();
			fireButtons.fireNextButtonEvent();

			assertThat(player.flags[kFLAGS.ROXANNE_TIME_WITHOUT_SEX],equalTo(1));
			assertThat(cut.collectedOutput, hasItem(startsWith("Gosh, Roxanne is so strong...")));
		}

		[Test]
        public function roxanneRepeatedStretchingWithBigBooty():void {
			setRoxanneLargeSize();
			player.butt.rating = Butt.RATING_EXPANSIVE;

			var testFunction:Function = function():void {
				cut.roxanneDrinkingContestTest();
				fireButtons.fireNextButtonEvent();
				setRoxanneLargeSize();
			};

			repeatEvent(testFunction);

			assertThat(kGAMECLASS.player.ass.analLooseness, equalTo(5));
			assertThat(cut.collectedOutput, hasItem(startsWith("Gods, your head is swimming!")));
		}

		[Test]
        public function roxanneCounterResetWithBigBooty():void {
			setRoxanneLargeSize();
			player.butt.rating = Butt.RATING_EXPANSIVE;

			var testFunction:Function = function():void {
				cut.roxanneDrinkingContestTest();
				fireButtons.fireNextButtonEvent();
			};

			repeatEvent(testFunction);

			assertThat(player.flags[kFLAGS.ROXANNE_TIME_WITHOUT_SEX], equalTo(1));
			assertThat(cut.collectedOutput, hasItem(startsWith("Gods, your head is swimming!")));
		}
    }
}

import classes.Scenes.Places.Bazaar.Roxanne;
import classes.internals.RandomNumberGenerator;

class RoxanneForTest extends Roxanne {
	public var collectedOutput:Vector.<String> = new Vector.<String>();

	public function RoxanneForTest(rng:RandomNumberGenerator)
	{
		super(rng);
	}

	public function roxanneDrinkingContestTest():void {
		super.roxanneDrinkingContest();
	}

	override protected function outputText(output:String):void {
		collectedOutput.push(output);
	}
}

class RngMock implements RandomNumberGenerator {
	public var randomValue:int = 0;

	public function random(max:int):int
	{
		return randomValue;
	}

	public function randomCorrected(max:int):int
	{
		return randomValue;
	}
}


code:
package classes.Scenes.Places {
	import classes.Scenes.Places.Bazaar.BlackCockTest;
	import classes.Scenes.Places.Bazaar.RoxanneTest;

[Suite]
[RunWith("org.flexunit.runners.Suite")]
	public class BazaarSuit
	{
		 public var blackCockTest:BlackCockTest;
		 public var roxanneTest:RoxanneTest;
	}
}


code:
package classes.Scenes {

import classes.Scenes.Places.BazaarSuit;

[Suite]
[RunWith("org.flexunit.runners.Suite")]
	public class PlacesSuit
	{
		 public var bazaarSuit:BazaarSuit;
	}
}


code:
package classes.Scenes
{
	import classes.Scenes.Monsters.ImpScene;
	import classes.Scenes.NPCs.EmberScene;
	import classes.Scenes.NPCs.UrtaPregs;
	import classes.Scenes.Places.TelAdre;
	import classes.helper.DummyOutput;
	import classes.internals.GuiOutput;
	import org.flexunit.asserts.*;
	import org.hamcrest.assertThat;
	import org.hamcrest.core.*;
	import org.hamcrest.number.*;
	import org.hamcrest.object.*;
	import org.hamcrest.text.*;
	import org.hamcrest.collection.*;

	import classes.helper.StageLocator;

	import classes.DefaultDict;
	import classes.CoC;
	import classes.Player;
	import classes.GlobalFlags.kGAMECLASS;
	import classes.GlobalFlags.kFLAGS;
	import classes.PregnancyStore;
	import classes.StatusEffects;
	import classes.Vagina;
	import classes.StatusEffects;
	import classes.Scenes.Areas.Bog;

	import org.flexunit.runners.Parameterized;

	[RunWith("org.flexunit.runners.Parameterized")]
	public class PregnancyProgressionAnalBirthTest
	{
		private static var cut:PregProgForTest; // static so I can be lazy and don't need to pass it as a parameter
		private var player:Player;
		private var output:GuiOutput;

		private var pregnancyType:int;

		[BeforeClass]
		public static function setUpClass():void
		{
			kGAMECLASS = new CoC(StageLocator.stage);
		}

		[Parameters]
		public static var testData:Array =
		[
			[PregnancyStore.PREGNANCY_FROG_GIRL],
			[PregnancyStore.PREGNANCY_SATYR],
			[PregnancyStore.PREGNANCY_DRIDER_EGGS],
			[PregnancyStore.PREGNANCY_BEE_EGGS],
			[PregnancyStore.PREGNANCY_SANDTRAP_FERTILE],
		];

		public function PregnancyProgressionAnalBirthTest(pregnancyType:int):void
		{
			this.pregnancyType = pregnancyType;
		}

		[Before]
		public function setUp():void
		{
			player = new Player();
			kGAMECLASS.player = player;

			kGAMECLASS.flags = new DefaultDict();

			output = new DummyOutput();

			cut = new PregProgForTest();
			kGAMECLASS.createScenes(cut);

			player.buttKnockUpForce(pregnancyType, 1);
		}

		[Test]
		public function giveBirth():void
		{
			cut.updatePregnancy();

			assertThat(cut.senseAnalBirth, hasItem(pregnancyType));
		}

		[Test]
		public function displayText():void
		{
			assertThat(cut.updatePregnancy(), equalTo(true));
		}

		[Test]
		public function pregnancyCleared():void
		{
			cut.updatePregnancy();

			assertThat(player.isButtPregnant(), equalTo(false));
		}

		[Test]
		public function chainDisplayUpdate():void
		{
			player.goIntoHeat(false);
			player.buttKnockUpForce(pregnancyType, 1);

			assertThat(cut.updatePregnancy(), equalTo(true));
		}
	}
}

import classes.Scenes.PregnancyProgression;

class PregProgForTest extends PregnancyProgression
{
	public var collectedOutput:Vector.<String> = new Vector.<String>();

	override protected function outputText(output:String):void
	{
		collectedOutput.push(output);
	}

	public function pregUpdate():Boolean
	{
		return updatePregnancy();
	}
}