/** * Copyright (C) 2002-2012 The FreeCol Team * * This file is part of FreeCol. * * FreeCol is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * FreeCol is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with FreeCol. If not, see <http://www.gnu.org/licenses/>. */ package net.sf.freecol.common.model; import java.util.ArrayList; import java.util.HashSet; import java.util.List; import java.util.Set; import net.sf.freecol.util.test.FreeColTestCase; public class ModifierTest extends FreeColTestCase { public void testAdditiveModifier() { Modifier modifier = new Modifier("test", 3, Modifier.Type.ADDITIVE); spec().addModifier(modifier); assertEquals(4f, modifier.applyTo(1)); } public void testMultiplicativeModifier() { Modifier modifier = new Modifier("test", 1.5f, Modifier.Type.MULTIPLICATIVE); spec().addModifier(modifier); assertEquals(1 * 1.5f, modifier.applyTo(1)); assertEquals(3 * 1.5f, modifier.applyTo(3)); } public void testPercentageModifier() { Modifier modifier = new Modifier("test", 50, Modifier.Type.PERCENTAGE); spec().addModifier(modifier); assertEquals(150f, modifier.applyTo(100)); assertEquals(4.5f, modifier.applyTo(3)); } public void testCombineAdditiveModifiers() { Modifier modifier1 = new Modifier("test", 3, Modifier.Type.ADDITIVE); Modifier modifier2 = new Modifier("test", 4, Modifier.Type.ADDITIVE); Set<Modifier> modifierSet = new HashSet<Modifier>(); modifierSet.add(modifier1); modifierSet.add(modifier2); assertEquals(1 + 3 + 4f, FeatureContainer.applyModifierSet(1, null, modifierSet)); } public void testCombineMultiplicativeModifiers() { Modifier modifier1 = new Modifier("test", 3, Modifier.Type.MULTIPLICATIVE); Modifier modifier2 = new Modifier("test", 4, Modifier.Type.MULTIPLICATIVE); Set<Modifier> modifierSet = new HashSet<Modifier>(); modifierSet.add(modifier1); modifierSet.add(modifier2); assertEquals(2 * 3 * 4f, FeatureContainer.applyModifierSet(2, null, modifierSet)); } public void testCombinePercentageModifiers() { Modifier modifier1 = new Modifier("test", 3, Modifier.Type.PERCENTAGE); Modifier modifier2 = new Modifier("test", 4, Modifier.Type.PERCENTAGE); Set<Modifier> modifierSet = new HashSet<Modifier>(); modifierSet.add(modifier1); modifierSet.add(modifier2); assertEquals(107f, FeatureContainer.applyModifierSet(100, null, modifierSet)); } public void testCombinedModifier() { Modifier modifier1 = new Modifier("test", 3, Modifier.Type.ADDITIVE); Modifier modifier2 = new Modifier("test", 1.5f, Modifier.Type.MULTIPLICATIVE); Modifier modifier3 = new Modifier("test", 50, Modifier.Type.PERCENTAGE); Set<Modifier> modifierSet = new HashSet<Modifier>(); modifierSet.add(modifier1); modifierSet.add(modifier2); assertEquals((1 + 3) * 1.5f, FeatureContainer.applyModifierSet(1, null, modifierSet)); modifierSet.add(modifier3); assertEquals(((1 + 3) * 1.5f) * 1.5f, FeatureContainer.applyModifierSet(1, null, modifierSet)); modifierSet.remove(modifier1); assertEquals(10 * 1.5f * 1.5f, FeatureContainer.applyModifierSet(10, null, modifierSet)); } public void testScope() { UnitType carpenter = spec().getUnitType("model.unit.masterCarpenter"); UnitType frigate = spec().getUnitType("model.unit.frigate"); Modifier modifier1 = new Modifier("test", 3, Modifier.Type.ADDITIVE); Modifier modifier2 = new Modifier("test", 1.5f, Modifier.Type.MULTIPLICATIVE); Modifier modifier3 = new Modifier("test", 30, Modifier.Type.PERCENTAGE); FeatureContainer featureContainer = new FeatureContainer(); FeatureContainer.addModifier(featureContainer, modifier1); FeatureContainer.addModifier(featureContainer, modifier2); FeatureContainer.addModifier(featureContainer, modifier3); // applies to frigate Scope scope1 = new Scope(); scope1.setType("model.unit.frigate"); // applies to carpenter Scope scope2 = new Scope(); scope2.setAbilityID(Ability.NAVAL_UNIT); scope2.setAbilityValue(false); // applies to frigate Scope scope3 = new Scope(); scope3.setMethodName("getLineOfSight"); scope3.setMethodValue("2"); List<Scope> scopes = new ArrayList<Scope>(); scopes.add(scope1); modifier1.setScopes(scopes); assertTrue(modifier1.appliesTo(frigate)); assertFalse(modifier1.appliesTo(carpenter)); Set<Modifier> result = featureContainer.getModifierSet("test", frigate, null); assertEquals(3, result.size()); assertEquals(((1 + 3) * 1.5f) + ((1 + 3) * 1.5f) * 30 / 100, FeatureContainer.applyModifierSet(1, null, result)); result = featureContainer.getModifierSet("test", carpenter, null); assertEquals(2, result.size()); assertEquals(1.5f + (1.5f * 30) / 100, FeatureContainer.applyModifierSet(1, null, result)); List<Scope> scopes2 = new ArrayList<Scope>(); scopes2.add(scope2); scopes2.add(scope3); modifier2.setScopes(scopes2); assertTrue(modifier2.appliesTo(frigate)); assertTrue(modifier2.appliesTo(carpenter)); result = featureContainer.getModifierSet("test", frigate, null); assertEquals(3, result.size()); assertEquals(((1 + 3) * 1.5f) + ((1 + 3) * 1.5f) * 30 / 100, FeatureContainer.applyModifierSet(1, null, result)); result = featureContainer.getModifierSet("test", carpenter, null); assertEquals(2, result.size()); assertEquals(1.5f + (1.5f * 30) / 100, FeatureContainer.applyModifierSet(1, null, result)); } public void testTimeLimits() { UnitType frigate = spec().getUnitType("model.unit.frigate"); Modifier modifier1 = new Modifier("test", 1, Modifier.Type.ADDITIVE); Modifier modifier2 = new Modifier("test", 2, Modifier.Type.ADDITIVE); modifier1.setFirstTurn(new Turn(10)); modifier1.setLastTurn(new Turn(30)); modifier2.setFirstTurn(new Turn(20)); modifier2.setLastTurn(new Turn(40)); assertTrue(modifier1.hasTimeLimit()); assertTrue(modifier2.hasTimeLimit()); assertFalse(modifier1.appliesTo(frigate, new Turn(5))); assertFalse(modifier1.appliesTo(frigate, new Turn(35))); assertFalse(modifier1.isOutOfDate(new Turn(25))); assertTrue(modifier1.appliesTo(frigate, new Turn(25))); assertFalse(modifier2.appliesTo(frigate, new Turn(5))); assertFalse(modifier2.appliesTo(frigate, new Turn(5))); assertFalse(modifier2.isOutOfDate(new Turn(25))); assertTrue(modifier2.appliesTo(frigate, new Turn(25))); FeatureContainer featureContainer = new FeatureContainer(); FeatureContainer.addModifier(featureContainer, modifier1); FeatureContainer.addModifier(featureContainer, modifier2); Set<Modifier> modifierSet = featureContainer.getModifierSet("test", frigate, new Turn(15)); assertEquals(1, modifierSet.size()); assertEquals(modifier1, modifierSet.iterator().next()); modifierSet = featureContainer.getModifierSet("test", frigate, new Turn(35)); assertEquals(1, modifierSet.size()); assertEquals(modifier2, modifierSet.iterator().next()); } public void testIncrements() { UnitType frigate = spec().getUnitType("model.unit.frigate"); Modifier modifier1 = new Modifier("test", 1, Modifier.Type.ADDITIVE); Modifier modifier2 = new Modifier("test", 2, Modifier.Type.ADDITIVE); modifier1.setIncrement(1, Modifier.Type.ADDITIVE, new Turn(10), new Turn(15)); assertFalse(modifier1.appliesTo(frigate, new Turn(9))); assertTrue(modifier1.appliesTo(frigate, new Turn(10))); assertTrue(modifier1.hasIncrement()); FeatureContainer featureContainer = new FeatureContainer(); FeatureContainer.addModifier(featureContainer, modifier1); FeatureContainer.addModifier(featureContainer, modifier2); // only modifier2 assertEquals(3f, featureContainer.applyModifier(1, "test", frigate, new Turn(9))); // both modifiers assertEquals(4f, featureContainer.applyModifier(1, "test", frigate, new Turn(10))); assertEquals(5f, featureContainer.applyModifier(1, "test", frigate, new Turn(11))); assertEquals(9f, featureContainer.applyModifier(1, "test", frigate, new Turn(15))); // only modifier2 assertEquals(3f, featureContainer.applyModifier(1, "test", frigate, new Turn(16))); } public void testHashEquals() { Scope scope1 = new Scope(); scope1.setType("model.unit.frigate"); scope1.setAbilityID("whatever"); Scope scope2 = new Scope(); scope2.setType("model.unit.frigate"); scope2.setAbilityID("whatever"); Scope scope3 = new Scope(); scope3.setType("model.unit.frigate"); scope3.setAbilityID("whatever"); scope3.setAbilityValue(false); assertEquals(scope1, scope1); assertEquals(scope1.hashCode(), scope1.hashCode()); assertEquals(scope1, scope2); assertEquals(scope1.hashCode(), scope2.hashCode()); assertFalse(scope1.equals(scope3)); assertFalse(scope1.hashCode() == scope3.hashCode()); Modifier modifier1 = new Modifier("test", 3, Modifier.Type.ADDITIVE); Modifier modifier2 = new Modifier("test", 3, Modifier.Type.ADDITIVE); Modifier modifier3 = new Modifier("test", 2, Modifier.Type.ADDITIVE); assertEquals(modifier1, modifier1); assertEquals(modifier1.hashCode(), modifier1.hashCode()); assertEquals(modifier1, modifier2); assertEquals(modifier1.hashCode(), modifier2.hashCode()); assertFalse(modifier1.equals(modifier3)); assertFalse(modifier1.hashCode() == modifier3.hashCode()); List<Scope> scopeList1 = new ArrayList<Scope>(); scopeList1.add(scope1); scopeList1.add(scope3); List<Scope> scopeList2 = new ArrayList<Scope>(); scopeList2.add(scope3); scopeList2.add(scope1); List<Scope> scopeList3 = new ArrayList<Scope>(); scopeList3.add(scope1); scopeList3.add(scope2); modifier1.setScopes(scopeList1); modifier2.setScopes(scopeList1); assertEquals(modifier1, modifier1); assertEquals(modifier1.hashCode(), modifier1.hashCode()); assertEquals(modifier1, modifier2); assertEquals(modifier1.hashCode(), modifier2.hashCode()); assertFalse(modifier1.equals(modifier3)); assertFalse(modifier1.hashCode() == modifier3.hashCode()); modifier2.setScopes(scopeList2); assertEquals(modifier2, modifier2); assertEquals(modifier2.hashCode(), modifier2.hashCode()); assertEquals(modifier1, modifier2); assertEquals(modifier1.hashCode(), modifier2.hashCode()); assertFalse(modifier2.equals(modifier3)); assertFalse(modifier2.hashCode() == modifier3.hashCode()); modifier2.setScopes(scopeList3); assertEquals(modifier2, modifier2); assertEquals(modifier2.hashCode(), modifier2.hashCode()); assertFalse(modifier1.equals(modifier2)); assertFalse(modifier1.hashCode() == modifier2.hashCode()); assertFalse(modifier2.equals(modifier3)); assertFalse(modifier2.hashCode() == modifier3.hashCode()); } /** * The presence of a single Modifier with an unknown value * produces an unknown result. */ public void testModifierUnknown() { Modifier modifier1 = new Modifier("test", 3, Modifier.Type.ADDITIVE); Modifier modifier2 = new Modifier("test", Modifier.UNKNOWN, Modifier.Type.MULTIPLICATIVE); Modifier modifier3 = new Modifier("test", 30, Modifier.Type.PERCENTAGE); FeatureContainer featureContainer = new FeatureContainer(); FeatureContainer.addModifier(featureContainer, modifier1); FeatureContainer.addModifier(featureContainer, modifier2); FeatureContainer.addModifier(featureContainer, modifier3); assertEquals(Modifier.UNKNOWN, featureContainer.applyModifier(1, "test", null, new Turn(15))); } }