PDA

View Full Version : Pair Programming b0l vs ufo13[TASK2.1]


thebol
22-12-2005, 21:01
Ciao!

Qua iniziamo il task per inserire 2 gemme in grid.
Di questo se ne occupera gridController, che contterra anche i riferimenti alla coppia di gemme(come voluto da fek).

Per ora lasciamo cmq a grid la propietà di gemUnderControl(per compatibilta), poi vedremo se è il caso di toglierla)

thebol
22-12-2005, 21:03
primo test
testare inserimento della coppia di gemme


public void testInsertGemsPair(){
controller.insertNewGemsPair();

assertTrue(grid.isGemAt(0, 4));
assertTrue(grid.isGemAt(1, 4));

}


il test sarà nella nuova classe di test TestGemsPair

Ufo13
22-12-2005, 21:39
Ovviamente non compila perchè manca la definizione del metodo insertNewGemsPair()

Inizio usando il quickfix di eclipse e lancio i test:

fallisce testInsertGemsPair

Inserisco il codice che mi fa passare i test:


public void insertNewGemsPair()
{
Gem pivotGem = gemQueue().extract();
Gem slaveGem = gemQueue().extract();

grid.insertGem(0, 4, slaveGem);
grid.insertGem(1, 4, pivotGem);
}


Build Successfull!

Preparo il nuovo test :)

Ufo13
22-12-2005, 21:56
Per continuare abbiamo bisogno di spostare il concetto di gemUnderControl dentro GridController... Procediamo col refactoring...

thebol
22-12-2005, 22:48
prima di questo refactoring, ne farei un altro :)

la insertGem di grid fa 2 cose:
inserisce la gemma
la setta come gemUnderControll

visto che dobbiamo portare fuori gemUnderControll conviene separare le 2 logiche

public void insertGem(int row, int column, Gem gem)
{
if(isGemAt(row, column))
{
throw new IllegalArgumentException();
}

if(gem.isAttachedToGrid())
{
throw new IllegalArgumentException();
}

empty = false;

gem.setCellPosition(row, column);

addGemToGrid(gem);
alignGemToCellUpperBound(gem);
setGemUnderControl(gem);
}



diventerebbe


public void insertGemUnderControll(int row, int column, Gem gem)
{
insertGem(row, column, gem);
setGemUnderControl(gem);
}


public void insertGem(int row, int column, Gem gem)
{
if(isGemAt(row, column))
{
throw new IllegalArgumentException();
}

if(gem.isAttachedToGrid())
{
throw new IllegalArgumentException();
}

empty = false;

gem.setCellPosition(row, column);

addGemToGrid(gem);
alignGemToCellUpperBound(gem);
}



si introduce una nuova funzione che non è testata esplicitamente, ma lo è da insertGemUnderControll.

bisognerebbe cambiare un po di test per far si che testino direttamente insertGem e non insertGemUnderControll..

thebol
22-12-2005, 23:11
l'ultimo refactoring proposto lo facciamo dopo se ne abbiamo bisogno

per ora portiamo tutta la logica di gemundercontrol in gridController

thebol
22-12-2005, 23:53
riretifica lo faccio subito, commito e per stasera ci fermiamo qua.

per l'altro refactoring(portare gemUnderControl in gridController) preferirei avere un coach o cmq uno che tiene d'occhio il design, che è un refactoring che porta molti cambiamenti(alcuni metodi in grid dovranno diventare pubblici, vorrei sapere se questo e un problema, o se qualcuno ha altre soluzioni) e cambiamenti nei test.

ciau

thebol
23-12-2005, 00:25
fatto lo sdoppiamento e committato.

i 2 nuovi metodi sono gia testati, per fare questo ho diviso la funzione e fatto girare i test. Quelli legati alla insertGem che non giravano li ho modificati sostituendo insertGem con insertGemUnderControll e hanno ricominciato a funzionare :) testando la funzione.

in piu ho aggiunto il test

public void testInsertGemUnderControll()
{
grid.insertGem(4, 2, gem1);
assertSame("Wrong gem under control", gem1, grid.getGemUnderControl());
}

mo faccio il commit

Ufo13
23-12-2005, 09:16
A me e` venuta un'idea che semplificherebbe il task e richiederebbe un numero minimo di modifiche... Quando (se :p) torno a casa spiego tutto :D

Ufo13
25-12-2005, 11:56
Aggiungo il test:


public void testGemsPairUnderGravity()
{
MockTimer timer = new MockTimer();

gridController.insertNewGemsPair();
grid.setGravity(1.0f);

timer.advance(config.getInteger("UpdateRate")+1);
gridController.update(timer);

assertTrue("slaveGem didn't move correctly after gravity applied", grid.isGemAt(1, 4));
assertTrue("pivotGem didn't move correctly after gravity applied", grid.isGemAt(2, 4));
}

Ufo13
25-12-2005, 12:03
Il test compila ma non va:

NullPointerException in update di gridController...

insertNewGemsPair non setta gemUnderControl

cambio di conseguenza in


public void insertNewGemsPair()
{
Gem slaveGem = gemGenerator.extract();
grid.insertGem(0, 4, slaveGem);

Gem pivotGem = gemGenerator.extract();
grid.insertGem(1, 4, pivotGem);

setGemUnderControl(pivotGem);
}


ora lancio i test...

Failure... La slaveGem non si è spostata... La update va solo su gemUnderControl... Lo cambio di conseguenza



grid.update(timer, getGemUnderControl());
grid.update(timer, slaveGem);


aggiungo il campo privato slaveGem...

Funziona!

Ufo13
25-12-2005, 12:07
ormai mi rendo conto che non stiamo andando in pair ma non riusciamo proprio ad avere gli stessi orari pare con queste feste in mezzo... Poi con i refactoring mio e di cionci il task si è semplificato assai...

Ufo13
25-12-2005, 12:20
thebol ti propongo questi:


public void testGemsPairMoveLeft()
{
gridController.insertNewGemsPair();

gridController.moveLeft();

assertTrue("slaveGem didn't move correctly after moveLeft", grid.isGemAt(0, 3));
assertTrue("pivotGem didn't move correctly after moveLeft", grid.isGemAt(1, 3));
}

public void testGemsPairMoveRight()
{
gridController.insertNewGemsPair();

gridController.moveRight();

assertTrue("slaveGem didn't move correctly after moveRight", grid.isGemAt(0, 5));
assertTrue("pivotGem didn't move correctly after moveRight", grid.isGemAt(1, 5));
}

Ufo13
25-12-2005, 16:17
faccio io :)


public void moveLeft()
{
grid.moveGemLeft(gemUnderControl);
grid.moveGemLeft(slaveGem);
}


public void moveRight()
{
grid.moveGemRight(gemUnderControl);
grid.moveGemRight(slaveGem);
}


Verde, preparo nuovi test

Ufo13
25-12-2005, 17:05
Due nuovi test


public void testGemsPairReactingToMoveLeftEvent()
{
input.generateKey(Input.KeyCode.vk_Left);

gridController.reactToInput(new MockTimer());

assertTrue("slaveGem didn't move correctly after MoveRight Event", grid.isGemAt(0, 3));
assertTrue("pivotGem didn't move correctly after MoveRight Event", grid.isGemAt(1, 3));
}

public void testGemsPairReactingToMoveRightEvent()
{
input.generateKey(Input.KeyCode.vk_Right);

gridController.reactToInput(new MockTimer());

assertTrue("slaveGem didn't move correctly after MoveRight Event", grid.isGemAt(0, 5));
assertTrue("pivotGem didn't move correctly after MoveRight Event", grid.isGemAt(1, 5));
}

Ufo13
25-12-2005, 17:15
Entrambi i test falliscono su slaveGem...

Per fare funzionare i test cambio MoveLeftCommandHandler e MoveRightCommandHandler dove in handleEvent chiamaeranno moveLeft e moveRight di GridController

Lancio i test...

NullPointerException in testReactToInput... Perchè? Beh ovviamente moveLeft e moveRight danno per scontato che slaveGem non sia null... Basta modificare il codice in questo modo:


public void moveLeft()
{
grid.moveGemLeft(gemUnderControl);

if(slaveGem != null)
{
grid.moveGemLeft(slaveGem);
}
}


public void moveRight()
{
grid.moveGemRight(gemUnderControl);

if(slaveGem != null)
{
grid.moveGemRight(slaveGem);
}
}


Lancio i test...
Funziona!

Ufo13
25-12-2005, 18:01
A questo punto direi che ci vuole il test per vedere che la coppia non si separi mai anche in condizioni limite (la gemma di sotto non può muoversi a sinistra ma quella di sopra sì).

Il test è il seguente:


public void testGemsPairDoesntSplit()
{
Gem gem = Gem.createForTesting();
grid.insertGem(1, 3, gem);

gridController.moveLeft();

assertTrue("slaveGem must not move left", gridController.getSlaveGem().getCellColumn() == 4);
}


Per compilare devo testare ed implementare anche la getSlaveGem() (test talmente banale che non posto neanche :p)

Eseguo i test...
Rosso... La gemma si muove...

Ho bisogno di sapere dentro gridController se le gemme possono muoversi a sinistra o a destra...

Preparo due test da aggiungere in testGrid:

public void testGemCanMoveLeft()
{
grid.insertGem(3, 3, gem1);

assertTrue("gem1 can move left", grid.gemCanMoveLeft(gem1));

grid.insertGem(3, 2, gem2);

assertFalse("gem1 cannot move left", grid.gemCanMoveLeft(gem1));
}

public void testGemCanMoveRight()
{
grid.insertGem(3, 2, gem1);

assertTrue("gem1 can move right", grid.gemCanMoveRight(gem1));

grid.insertGem(3, 3, gem2);

assertFalse("gem1 cannot move right", grid.gemCanMoveRight(gem1));
}


uso quick fix per implementare gli stub e lancio i test... azz si ferma al testGemsPair... Allora commento un secondo quel test e rilancio i test... Rosso...

Implemento questo codice:

public boolean gemCanMoveLeft(Gem gem)
{
return canMove(gem, -1);
}


public boolean gemCanMoveRight(Gem gem)
{
return canMove(gem, +1);
}


Rilancio i test... Verde! Decommento il test in TestGemsPair e rilancio i test... Ancora rosso (certamente :p)...

Cambio moveLeft()

public void moveLeft()
{
if(slaveGem == null)
{
grid.moveGemLeft(gemUnderControl);
}
else
if(grid.gemCanMoveLeft(gemUnderControl) && grid.gemCanMoveLeft(slaveGem))
{
grid.moveGemLeft(gemUnderControl);
grid.moveGemLeft(slaveGem);
}
}


Lancio i test... Verde! Oggi son fortunato :p

Ora rifaccio il test e l'implementazione per il movimento a destra... Verde :)

Ufo13
25-12-2005, 18:10
Le gemme in posizione verticale non sono previste in questo task quindi non preparerò i test per lo split delle gemme in posizione orizzontale quando una delle due per effetto della gravità incontra un'ostacolo...

Ora non mi rimane che fare il refactoring per la creazione di oggetti GemsPair invece che singole gemme...

Ufo13
25-12-2005, 19:03
Ok, il task è completo :)