/*
* Copyright (c) 2013 Tom Parker <thpr@users.sourceforge.net>
*
* This program is free software; you can redistribute it and/or modify it under
* the terms of the GNU Lesser General Public License as published by the Free
* Software Foundation; either version 2.1 of the License, or (at your option)
* any later version.
*
* This program 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 Lesser General Public License for more
* details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this library; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
*/
package pcgen.io.testsupport;
import org.junit.Test;
import pcgen.cdom.base.CDOMObject;
import pcgen.cdom.enumeration.ListKey;
import pcgen.cdom.enumeration.ObjectKey;
import pcgen.cdom.enumeration.SkillCost;
import pcgen.cdom.enumeration.Type;
import pcgen.cdom.reference.CDOMDirectSingleRef;
import pcgen.core.Ability;
import pcgen.core.AbilityCategory;
import pcgen.core.ArmorProf;
import pcgen.core.Equipment;
import pcgen.core.Language;
import pcgen.core.PCClass;
import pcgen.core.PCTemplate;
import pcgen.core.ShieldProf;
import pcgen.core.Skill;
import pcgen.core.WeaponProf;
import pcgen.core.analysis.SkillRankControl;
import plugin.lsttokens.CcskillLst;
import plugin.lsttokens.CskillLst;
import plugin.lsttokens.TypeLst;
import plugin.lsttokens.auto.WeaponProfToken;
import plugin.lsttokens.choose.SkillToken;
import plugin.lsttokens.pcclass.HdToken;
import plugin.lsttokens.skill.ExclusiveToken;
import plugin.lsttokens.testsupport.TokenRegistration;
public abstract class AbstractGlobalTargetedSaveRestoreTest<T extends CDOMObject>
extends AbstractSaveRestoreTest
{
public abstract Class<T> getObjectClass();
protected abstract Object prepare(T obj);
protected abstract void remove(Object o);
protected abstract void applyObject(T obj);
protected void additionalChooseSet(T obj)
{
//Default to no action necessary
}
protected boolean isSymmetric()
{
//Default to true
return true;
}
@Test
public void testGlobalCSkill()
{
PCClass monclass = create(PCClass.class, "MonClass");
new HdToken().parseToken(context, monclass, "8");
new TypeLst().parseToken(context, monclass, "Monster");
Skill granted = create(Skill.class, "Granted");
new ExclusiveToken().parseToken(context, granted, "Yes");
T target = create(getObjectClass(), "Target");
Skill skill = create(Skill.class, "MySkill");
new ExclusiveToken().parseToken(context, skill, "Yes");
new CskillLst().parseToken(context, target, "Granted");
Object o = prepare(target);
finishLoad();
pc.incrementClassLevel(1, monclass);
pc.setHP(pc.getActiveClassLevel(monclass, 0), 3);
assertEquals(SkillCost.EXCLUSIVE,
pc.getSkillCostForClass(granted, monclass));
applyObject(target);
assertEquals(SkillCost.CLASS,
pc.getSkillCostForClass(granted, monclass));
final Runnable cleanup = getPreEqualityCleanup();
Runnable fullcleanup = new Runnable()
{
public void run()
{
if (cleanup != null)
{
cleanup.run();
}
//TODO need this to create the spell support :/
PCClass cl =
context.getReferenceContext().silentlyGetConstructedCDOMObject(PCClass.class,
"MonClass");
reloadedPC.getSpellSupport(cl);
}
};
runRoundRobin(fullcleanup);
assertEquals(SkillCost.CLASS,
pc.getSkillCostForClass(granted, monclass));
assertEquals(SkillCost.CLASS,
reloadedPC.getSkillCostForClass(granted, monclass));
remove(o);
reloadedPC.setDirty(true);
assertEquals(SkillCost.EXCLUSIVE,
reloadedPC.getSkillCostForClass(granted, monclass));
}
@Test
public void testGlobalCSkillList()
{
PCClass monclass = create(PCClass.class, "MonClass");
new HdToken().parseToken(context, monclass, "8");
new TypeLst().parseToken(context, monclass, "Monster");
Skill granted = create(Skill.class, "Granted");
new ExclusiveToken().parseToken(context, granted, "Yes");
T target = create(getObjectClass(), "Target");
Skill skill = create(Skill.class, "MySkill");
new ExclusiveToken().parseToken(context, skill, "Yes");
new CskillLst().parseToken(context, target, "LIST");
new SkillToken().parseToken(context, target, "Granted|MySkill");
additionalChooseSet(target);
Object o = prepare(target);
finishLoad();
pc.incrementClassLevel(1, monclass);
pc.setHP(pc.getActiveClassLevel(monclass, 0), 3);
assertEquals(SkillCost.EXCLUSIVE,
pc.getSkillCostForClass(granted, monclass));
applyObject(target);
assertEquals(SkillCost.CLASS,
pc.getSkillCostForClass(granted, monclass));
final Runnable cleanup = getPreEqualityCleanup();
Runnable fullcleanup = new Runnable()
{
public void run()
{
if (cleanup != null)
{
cleanup.run();
}
//TODO need this to create the spell support :/
PCClass cl =
context.getReferenceContext().silentlyGetConstructedCDOMObject(PCClass.class,
"MonClass");
reloadedPC.getSpellSupport(cl);
}
};
runRoundRobin(fullcleanup);
assertEquals(SkillCost.CLASS,
pc.getSkillCostForClass(granted, monclass));
assertEquals(SkillCost.CLASS,
reloadedPC.getSkillCostForClass(granted, monclass));
remove(o);
reloadedPC.setDirty(true);
if (isSymmetric())
{
assertEquals(SkillCost.EXCLUSIVE,
reloadedPC.getSkillCostForClass(granted, monclass));
}
}
@Test
public void testGlobalCCSkill()
{
PCClass myclass = create(PCClass.class, "SomeClass");
new HdToken().parseToken(context, myclass, "8");
Skill granted = create(Skill.class, "Granted");
new ExclusiveToken().parseToken(context, granted, "Yes");
T target = create(getObjectClass(), "Target");
create(Skill.class, "MySkill");
new CcskillLst().parseToken(context, target, "Granted");
Object o = prepare(target);
finishLoad();
pc.incrementClassLevel(1, myclass);
pc.setHP(pc.getActiveClassLevel(myclass, 0), 3);
assertEquals(SkillCost.EXCLUSIVE,
pc.getSkillCostForClass(granted, myclass));
applyObject(target);
assertEquals(SkillCost.CROSS_CLASS,
pc.getSkillCostForClass(granted, myclass));
final Runnable cleanup = getPreEqualityCleanup();
Runnable fullcleanup = new Runnable()
{
public void run()
{
if (cleanup != null)
{
cleanup.run();
}
//TODO need this to create the spell support :/
PCClass cl =
context.getReferenceContext().silentlyGetConstructedCDOMObject(PCClass.class,
"SomeClass");
reloadedPC.getSpellSupport(cl);
}
};
runRoundRobin(fullcleanup);
assertEquals(SkillCost.CROSS_CLASS,
pc.getSkillCostForClass(granted, myclass));
assertEquals(SkillCost.CROSS_CLASS,
reloadedPC.getSkillCostForClass(granted, myclass));
remove(o);
reloadedPC.setDirty(true);
assertEquals(SkillCost.EXCLUSIVE,
reloadedPC.getSkillCostForClass(granted, myclass));
}
public void testGlobalCCSkillList()
{
PCClass myclass = create(PCClass.class, "SomeClass");
new HdToken().parseToken(context, myclass, "8");
Skill granted = create(Skill.class, "Granted");
new ExclusiveToken().parseToken(context, granted, "Yes");
T target = create(getObjectClass(), "Target");
create(Skill.class, "MySkill");
new CcskillLst().parseToken(context, target, "LIST");
new SkillToken().parseToken(context, target, "Granted|MySkill");
additionalChooseSet(target);
Object o = prepare(target);
finishLoad();
pc.incrementClassLevel(1, myclass);
pc.setHP(pc.getActiveClassLevel(myclass, 0), 3);
assertEquals(SkillCost.EXCLUSIVE,
pc.getSkillCostForClass(granted, myclass));
applyObject(target);
assertEquals(SkillCost.CROSS_CLASS,
pc.getSkillCostForClass(granted, myclass));
final Runnable cleanup = getPreEqualityCleanup();
Runnable fullcleanup = new Runnable()
{
public void run()
{
if (cleanup != null)
{
cleanup.run();
}
//TODO need this to create the spell support :/
PCClass cl =
context.getReferenceContext().silentlyGetConstructedCDOMObject(PCClass.class,
"SomeClass");
reloadedPC.getSpellSupport(cl);
}
};
runRoundRobin(fullcleanup);
assertEquals(SkillCost.CROSS_CLASS,
pc.getSkillCostForClass(granted, myclass));
assertEquals(SkillCost.CROSS_CLASS,
reloadedPC.getSkillCostForClass(granted, myclass));
remove(o);
reloadedPC.setDirty(true);
if (isSymmetric())
{
assertEquals(SkillCost.EXCLUSIVE,
reloadedPC.getSkillCostForClass(granted, myclass));
}
}
@Test
public void testAutoWeaponProf()
{
WeaponProf granted = create(WeaponProf.class, "Granted");
create(WeaponProf.class, "Ignored");
T target = create(getObjectClass(), "Target");
new WeaponProfToken().parseToken(context, target, "Granted");
Object o = prepare(target);
finishLoad();
assertFalse(pc.hasWeaponProf(granted));
applyObject(target);
assertTrue(pc.hasWeaponProf(granted));
runRoundRobin(getPreEqualityCleanup());
assertTrue(pc.hasWeaponProf(granted));
assertTrue(reloadedPC.hasWeaponProf(granted));
remove(o);
reloadedPC.setDirty(true);
assertFalse(reloadedPC.hasWeaponProf(granted));
}
@Test
public void testAutoWeaponProfList()
{
WeaponProf granted = create(WeaponProf.class, "Granted");
create(WeaponProf.class, "Ignored");
T target = create(getObjectClass(), "Target");
new WeaponProfToken().parseToken(context, target, "%LIST");
new plugin.lsttokens.choose.WeaponProficiencyToken().parseToken(
context, target, "Granted|Ignored");
additionalChooseSet(target);
Object o = prepare(target);
finishLoad();
assertFalse(pc.hasWeaponProf(granted));
applyObject(target);
assertTrue(pc.hasWeaponProf(granted));
runRoundRobin(getPreEqualityCleanup());
assertTrue(pc.hasWeaponProf(granted));
assertTrue(reloadedPC.hasWeaponProf(granted));
remove(o);
reloadedPC.setDirty(true);
if (isSymmetric())
{
assertFalse(reloadedPC.hasWeaponProf(granted));
}
}
@Test
public void testAutoShieldProf()
{
ShieldProf granted = create(ShieldProf.class, "Granted");
create(ShieldProf.class, "Ignored");
T target = create(getObjectClass(), "Target");
new plugin.lsttokens.auto.ShieldProfToken().parseToken(context, target,
"Granted");
Object o = prepare(target);
finishLoad();
Equipment e = new Equipment();
e.addToListFor(ListKey.TYPE, Type.SHIELD);
e.put(ObjectKey.SHIELD_PROF, CDOMDirectSingleRef.getRef(granted));
assertFalse(pc.isProficientWith(e));
applyObject(target);
assertTrue(pc.isProficientWith(e));
runRoundRobin(getPreEqualityCleanup());
assertTrue(pc.isProficientWith(e));
assertTrue(reloadedPC.isProficientWith(e));
remove(o);
reloadedPC.setDirty(true);
assertFalse(reloadedPC.isProficientWith(e));
}
@Test
public void testAutoShieldProfList()
{
ShieldProf granted = create(ShieldProf.class, "Granted");
create(ShieldProf.class, "Ignored");
T target = create(getObjectClass(), "Target");
new plugin.lsttokens.auto.ShieldProfToken().parseToken(context, target,
"%LIST");
new plugin.lsttokens.choose.ShieldProficiencyToken().parseToken(
context, target, "Granted|Ignored");
additionalChooseSet(target);
Object o = prepare(target);
finishLoad();
Equipment e = new Equipment();
e.addToListFor(ListKey.TYPE, Type.SHIELD);
e.put(ObjectKey.SHIELD_PROF, CDOMDirectSingleRef.getRef(granted));
assertFalse(pc.isProficientWith(e));
applyObject(target);
assertTrue(pc.isProficientWith(e));
runRoundRobin(getPreEqualityCleanup());
assertTrue(pc.isProficientWith(e));
assertTrue(reloadedPC.isProficientWith(e));
remove(o);
reloadedPC.setDirty(true);
if (isSymmetric())
{
assertFalse(reloadedPC.isProficientWith(e));
}
}
@Test
public void testAutoArmorProf()
{
T target = create(getObjectClass(), "Target");
ArmorProf granted = create(ArmorProf.class, "Granted");
create(ArmorProf.class, "Ignored");
new plugin.lsttokens.auto.ArmorProfToken().parseToken(context, target,
"Granted");
Object o = prepare(target);
finishLoad();
Equipment e = new Equipment();
e.addToListFor(ListKey.TYPE, Type.ARMOR);
e.put(ObjectKey.ARMOR_PROF, CDOMDirectSingleRef.getRef(granted));
assertFalse(pc.isProficientWith(e));
applyObject(target);
assertTrue(pc.isProficientWith(e));
runRoundRobin(getPreEqualityCleanup());
assertTrue(pc.isProficientWith(e));
assertTrue(reloadedPC.isProficientWith(e));
remove(o);
reloadedPC.setDirty(true);
assertFalse(reloadedPC.isProficientWith(e));
}
@Test
public void testAutoArmorProfList()
{
T target = create(getObjectClass(), "Target");
ArmorProf granted = create(ArmorProf.class, "Granted");
create(ArmorProf.class, "Ignored");
new plugin.lsttokens.auto.ArmorProfToken().parseToken(context, target,
"%LIST");
new plugin.lsttokens.choose.ArmorProficiencyToken().parseToken(context,
target, "Granted|Ignored");
additionalChooseSet(target);
Object o = prepare(target);
finishLoad();
Equipment e = new Equipment();
e.addToListFor(ListKey.TYPE, Type.ARMOR);
e.put(ObjectKey.ARMOR_PROF, CDOMDirectSingleRef.getRef(granted));
assertFalse(pc.isProficientWith(e));
applyObject(target);
assertTrue(pc.isProficientWith(e));
runRoundRobin(getPreEqualityCleanup());
assertTrue(pc.isProficientWith(e));
assertTrue(reloadedPC.isProficientWith(e));
remove(o);
reloadedPC.setDirty(true);
if (isSymmetric())
{
assertFalse(reloadedPC.isProficientWith(e));
}
}
@Test
public void testAutoLanguage()
{
T target = create(getObjectClass(), "Target");
Language granted = create(Language.class, "Granted");
create(Language.class, "Ignored");
new plugin.lsttokens.auto.LangToken().parseToken(context, target,
"Granted");
Object o = prepare(target);
finishLoad();
assertFalse(pc.hasLanguage(granted));
applyObject(target);
assertTrue(pc.hasLanguage(granted));
runRoundRobin(getPreEqualityCleanup());
assertTrue(pc.hasLanguage(granted));
assertTrue(reloadedPC.hasLanguage(granted));
remove(o);
reloadedPC.setDirty(true);
assertFalse(reloadedPC.hasLanguage(granted));
}
@Test
public void testAutoLanguageList()
{
T target = create(getObjectClass(), "Target");
Language granted = create(Language.class, "Granted");
create(Language.class, "Ignored");
new plugin.lsttokens.auto.LangToken().parseToken(context, target,
"%LIST");
new plugin.lsttokens.choose.LangToken().parseToken(context,
target, "Granted|Ignored");
additionalChooseSet(target);
Object o = prepare(target);
finishLoad();
assertFalse(pc.hasLanguage(granted));
applyObject(target);
assertTrue(pc.hasLanguage(granted));
runRoundRobin(getPreEqualityCleanup());
assertTrue(pc.hasLanguage(granted));
assertTrue(reloadedPC.hasLanguage(granted));
remove(o);
reloadedPC.setDirty(true);
if (isSymmetric())
{
assertFalse(reloadedPC.hasLanguage(granted));
}
}
//TODO We accept this is not symmetric now due to equipment cloning
// @Test
// public void testAutoEquipment()
// {
// T target = create(getObjectClass(), "Target");
// Equipment granted = create(Equipment.class, "Granted");
// create(Equipment.class, "Ignored");
// new plugin.lsttokens.auto.EquipToken().parseToken(context, target,
// "%LIST");
// new plugin.lsttokens.choose.EquipmentToken().parseToken(context,
// target, "Granted|Ignored");
// Object o = prepare(target);
// finishLoad();
// assertFalse(pc.getEquipmentMasterList().contains(granted));
// applyObject(target);
// assertTrue(pc.getEquipmentMasterList().contains(granted));
// dumpPC(pc);
// runRoundRobin();
// assertTrue(pc.getEquipmentMasterList().contains(granted));
// assertTrue(reloadedPC.getEquipmentMasterList().contains(granted));
// remove(o);
// reloadedPC.setDirty(true);
// assertFalse(reloadedPC.getEquipmentMasterList().contains(granted));
// }
@Test
public void testAddLanguage()
{
Language granted = create(Language.class, "MyLanguage");
create(Language.class, "Ignored");
T target = create(getObjectClass(), "Target");
new plugin.lsttokens.add.LanguageToken().parseToken(context, target,
"MyLanguage");
Object o = prepare(target);
finishLoad();
assertFalse(pc.hasLanguage(granted));
applyObject(target);
assertTrue(pc.hasLanguage(granted));
runRoundRobin(getPreEqualityCleanup());
assertTrue(pc.hasLanguage(granted));
assertTrue(reloadedPC.hasLanguage(granted));
remove(o);
reloadedPC.setDirty(true);
assertFalse(reloadedPC.hasLanguage(granted));
}
@Test
public void testAddTemplate()
{
PCTemplate granted = create(PCTemplate.class, "MyTemplate");
create(PCTemplate.class, "Ignored");
T target = create(getObjectClass(), "Target");
new plugin.lsttokens.add.TemplateToken().parseToken(context, target,
"MyTemplate");
Object o = prepare(target);
finishLoad();
assertFalse(pc.hasTemplate(granted));
applyObject(target);
assertTrue(pc.hasTemplate(granted));
runRoundRobin(getPreEqualityCleanup());
assertTrue(pc.hasTemplate(granted));
assertTrue(reloadedPC.hasTemplate(granted));
remove(o);
reloadedPC.setDirty(true);
if (isSymmetric())
{
assertFalse(reloadedPC.hasTemplate(granted));
}
}
@Test
public void testAddAbilityNormalTarget()
{
TokenRegistration.register(plugin.bonustokens.SkillRank.class);
T target = create(getObjectClass(), "Target");
Ability abil = context.getReferenceContext().constructCDOMObject(Ability.class, "GrantedAbility");
context.getReferenceContext().reassociateCategory(AbilityCategory.FEAT, abil);
new plugin.lsttokens.add.AbilityToken().parseToken(context, target,
"FEAT|NORMAL|GrantedAbility");
Skill granted = create(Skill.class, "GrantedSkill");
create(Skill.class, "IgnoredSkill");
new plugin.lsttokens.choose.SkillToken().parseToken(context,
abil, "GrantedSkill|IgnoredSkill");
new plugin.lsttokens.BonusLst().parseToken(context, abil, "SKILLRANK|%LIST|1");
abil.put(ObjectKey.MULTIPLE_ALLOWED, true);
Object o = prepare(target);
finishLoad();
assertEquals(0.0f, SkillRankControl.getTotalRank(pc, granted));
applyObject(target);
pc.setDirty(true);
assertEquals(1.0f, SkillRankControl.getTotalRank(pc, granted));
runRoundRobin(getPreEqualityCleanup());
assertEquals(1.0f, SkillRankControl.getTotalRank(pc, granted));
assertEquals(1.0f, SkillRankControl.getTotalRank(reloadedPC, granted));
remove(o);
reloadedPC.setDirty(true);
//This fails (see CODE-2387)
//assertEquals(0.0f, SkillRankControl.getTotalRank(reloadedPC, granted));
}
@Test
public void testAddAbilityVirtualTarget()
{
TokenRegistration.register(plugin.bonustokens.SkillRank.class);
T target = create(getObjectClass(), "Target");
Ability abil = context.getReferenceContext().constructCDOMObject(Ability.class, "GrantedAbility");
context.getReferenceContext().reassociateCategory(AbilityCategory.FEAT, abil);
new plugin.lsttokens.add.AbilityToken().parseToken(context, target,
"FEAT|VIRTUAL|GrantedAbility");
Skill granted = create(Skill.class, "GrantedSkill");
create(Skill.class, "IgnoredSkill");
new plugin.lsttokens.choose.SkillToken().parseToken(context,
abil, "GrantedSkill|IgnoredSkill");
new plugin.lsttokens.BonusLst().parseToken(context, abil, "SKILLRANK|%LIST|1");
abil.put(ObjectKey.MULTIPLE_ALLOWED, true);
Object o = prepare(target);
finishLoad();
assertEquals(0.0f, SkillRankControl.getTotalRank(pc, granted));
applyObject(target);
pc.setDirty(true);
pc.calcActiveBonuses();
assertEquals(1.0f, SkillRankControl.getTotalRank(pc, granted));
runRoundRobin(getPreEqualityCleanup());
assertEquals(1.0f, SkillRankControl.getTotalRank(pc, granted));
assertEquals(1.0f, SkillRankControl.getTotalRank(reloadedPC, granted));
remove(o);
reloadedPC.setDirty(true);
//This fails (see CODE-2387)
//assertEquals(0.0f, SkillRankControl.getTotalRank(reloadedPC, granted));
}
//Fails due to issues highlighted in CODE-2283
// @Test
// public void testAddSkill()
// {
// PCClass myclass = create(PCClass.class, "SomeClass");
// Skill granted = create(Skill.class, "GrantedSkill");
// create(Skill.class, "Ignored");
// T target = create(getObjectClass(), "Target");
// new plugin.lsttokens.add.SkillToken().parseToken(context, target,
// "GrantedSkill");
// Object o = prepare(target);
// finishLoad();
// pc.incrementClassLevel(1, myclass);
// assertNull(pc.getSkillRankForClass(granted, null));
// applyObject(target);
// assertEquals(1.0, pc.getSkillRankForClass(granted, null));
// runRoundRobin();
// assertEquals(1.0, pc.getSkillRankForClass(granted, null));
// assertEquals(1.0, reloadedPC.getSkillRankForClass(granted, null));
// remove(o);
// reloadedPC.setDirty(true);
// assertNull(pc.getSkillRankForClass(granted, null));
// }
protected Runnable getPreEqualityCleanup()
{
return null;
}
}