On continue par une armée (qui pue à tous les sens du terme) à Mamar: La Death Guard.
Et on commence par l'aura Contagion de Nurgle.
Car avec les démon, j'ai ajouté les auras.
Pour commencer, on vérifie que la Death Guard a l'aura en BDD:
Évidement, la règle s'implémente facilement:
Chez moi, les règles sont fabriquées par le Design Pattern Factory:
Et contrairement à des Ploucs qui codent l'application critique de l'entreprise, il y a des TU, sur la Factory ici:
Et on commence par l'aura Contagion de Nurgle.
Car avec les démon, j'ai ajouté les auras.
Pour commencer, on vérifie que la Death Guard a l'aura en BDD:
Code:
curl -XPOST -v -d '{"langage":"fr","idCamp":"2","idFaction":"4","idSousFaction":"1","idSousSousFaction":"1"}' -H "Content-type: application/json" http://localhost:8080/aura/parRecherch
Code:
[
{
"aireEffet":1,
"isAuraUnite":true,
"profils":[
],
"factory":"com.calculateur.warhammer.data.regles.factory.factory.death.guard.AuraContagionNurgleFactory",
"ressource":{
"id":24000,
"ressource":"com.calculateur.warhammer.dto.aura.death_guard.death_guard"
},
"donnees":[
],
"description":"-1 à l\u0027endurance de la cible. La portée est de 1ps au tour 1, 3ps au tour 2, 6ps au tour 3 et 9ps au tour 4+.",
"id":24000,
"nom":"id.aura.contagion.nurgle",
"cleTraduction":"aura.death.guard.contagion.nurgle",
"libelle":"Contagion de Nurgle"
}
]
Évidement, la règle s'implémente facilement:
Code:
package com.calculateur.warhammer.data.regles.regle.death.guard;
import com.calculateur.warhammer.data.regles.IRegleAttaque;
/**
* Aura Contagion de Nurgle.
* @author phili
*
*/
public class AuraContagionNurgle implements IRegleAttaque{
public static final String ID_AURA_CONTAGION_NURGLE = "id.aura.contagion.nurgle";
@Override
public Integer getMalusEndurance() {
return -1;
}
}
Chez moi, les règles sont fabriquées par le Design Pattern Factory:
Code:
package com.calculateur.warhammer.data.regles.factory.factory.death.guard;
import com.calculateur.warhammer.base.exception.FunctionnalExeption;
import com.calculateur.warhammer.data.identifiable.IAura;
import com.calculateur.warhammer.data.regles.IRegleAttaque;
import com.calculateur.warhammer.data.regles.IRegleDefense;
import com.calculateur.warhammer.data.regles.IUpdateAura;
import com.calculateur.warhammer.data.regles.factory.donnees.IDonneeFactory;
import com.calculateur.warhammer.data.regles.factory.regle.AbstractAuraRegleFactory;
import com.calculateur.warhammer.data.regles.regle.death.guard.AuraContagionNurgle;
/**
* Factory pour l'aura Contagion de Nurgle
*
* @author phili
*
*/
public class AuraContagionNurgleFactory extends AbstractAuraRegleFactory implements IUpdateAura {
@Override
public IRegleAttaque getRegleAttaque(IDonneeFactory donnees) throws FunctionnalExeption {
updateAura(donnees);
return super.getRegleAttaque(donnees);
}
@Override
protected IRegleAttaque getRegleAttaqueAura() {
return new AuraContagionNurgle();
}
@Override
protected IRegleDefense getRegleDefenseAura() {
return null;
}
@Override
protected String getKeyAura() {
return AuraContagionNurgle.ID_AURA_CONTAGION_NURGLE;
}
@Override
public void updateAura(IDonneeFactory donnees) {
IAura aura = donnees.getContexteAction().getAurasAttaquant().get(getKeyAura());
if(aura != null) {
updateAuraSelonNumeroTour(donnees.getContexteAction().getNumeroTour(), aura);
}
}
private void updateAuraSelonNumeroTour(Integer numeroTour, IAura aura) {
switch (numeroTour) {
case 1:
aura.setBonusAireEffet(0);
break;
case 2:
aura.setBonusAireEffet(2);
break;
case 3:
aura.setBonusAireEffet(5);
break;
default:
aura.setBonusAireEffet(8);
}
}
}
Et contrairement à des Ploucs qui codent l'application critique de l'entreprise, il y a des TU, sur la Factory ici:
Code:
package com.calculateur.warhammer.data.regles.factory.factory.death.guard;
import static org.junit.jupiter.api.Assertions.fail;
import static org.mockito.ArgumentMatchers.any;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import org.assertj.core.api.Assertions;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.junit.jupiter.api.parallel.Execution;
import org.junit.jupiter.api.parallel.ExecutionMode;
import org.mockito.Mock;
import org.mockito.Mockito;
import org.mockito.junit.jupiter.MockitoExtension;
import com.calculateur.warhammer.base.exception.FunctionnalExeption;
import com.calculateur.warhammer.data.identifiable.IAura;
import com.calculateur.warhammer.data.regles.IRegleAttaque;
import com.calculateur.warhammer.data.regles.factory.regle.AbstractFactoryRegleTest;
import com.calculateur.warhammer.data.regles.regle.death.guard.AuraContagionNurgle;
@Execution(ExecutionMode.SAME_THREAD)
@ExtendWith(MockitoExtension.class)
public class AuraContagionNurgleFactoryTest extends AbstractFactoryRegleTest{
private static final Integer PORTEE_TOUR_1 = 1;
private static final Integer PORTEE_TOUR_2 = 3;
private static final Integer PORTEE_TOUR_3 = 6;
private static final Integer PORTEE_TOUR_4 = 9;
private static final Integer TOUR_MAXIMUM = 5;
private static final Integer DISTANCE_MAXIMUM_TEST = 15;
@Mock
private IAura aura;
public AuraContagionNurgleFactoryTest() {
super(new AuraContagionNurgleFactory());
}
@Override
protected boolean isRegleAttaqueAttendu() {
return true;
}
@Override
protected boolean isRegleDefenseAttendu() {
return false;
}
@Test
public void testAuraAbsente() {
try {
Mockito.when(donnees.getContexteAction()).thenReturn(contexteAction);
Mockito.when(contexteAction.getAurasAttaquant()).thenReturn(Collections.emptyMap());
factoryRegle.getRegleAttaque(donnees);
fail();
}catch(FunctionnalExeption ex) {
validateFunctionnalException(ex);
}
}
@Test
public void testAura() throws FunctionnalExeption{
for(Integer numeroTour = 1; numeroTour <= TOUR_MAXIMUM;numeroTour++) {
for(Integer distanceBelligerant = 1; distanceBelligerant < DISTANCE_MAXIMUM_TEST; distanceBelligerant++) {
initMocks(numeroTour, distanceBelligerant);
IRegleAttaque regle = factoryRegle.getRegleAttaque(donnees);
validateRegle(regle, numeroTour, distanceBelligerant);
}
}
}
private void initMocks(Integer numeroTour,Integer distanceEntreBeligerants) {
Mockito.when(donnees.getContexteAction()).thenReturn(contexteAction);
Mockito.when(contexteAction.getNumeroTour()).thenReturn(numeroTour);
Map<String, IAura> mapAura = new HashMap<>();
mapAura.put(AuraContagionNurgle.ID_AURA_CONTAGION_NURGLE, aura);
Mockito.when(contexteAction.getAurasAttaquant()).thenReturn(mapAura);
Mockito.when(contexteAction.getDistanceEntreBelligerant()).thenReturn(distanceEntreBeligerants.doubleValue());
Mockito.when(aura.isAuraUnite()).thenReturn(true);
Mockito.doAnswer(invocation -> {
Integer bon = (Integer)invocation.getArgument(0);
Integer portee = 1;
Mockito.when(aura.getApplicationAura()).thenReturn(portee + bon);
return null;
}).when(aura).setBonusAireEffet(any());
}
private void validateRegle(IRegleAttaque regle,Integer numeroTour,Integer distanceEntreBeligerants) {
Integer porteeAura = getPorteeAura(numeroTour);
boolean isRegle = distanceEntreBeligerants <= porteeAura;
if(isRegle) {
Assertions.assertThat(regle.getMalusEndurance()).isEqualTo(-1);
}else {
Assertions.assertThat(regle).isNull();
}
}
private Integer getPorteeAura(Integer numeroTour) {
Integer portee;
switch (numeroTour) {
case 1:
portee = PORTEE_TOUR_1;
break;
case 2:
portee = PORTEE_TOUR_2;
break;
case 3:
portee = PORTEE_TOUR_3;
break;
default:
portee = PORTEE_TOUR_4;
}
return portee;
}
}