Add a new tarification for real babies (< 2 yo)

Pour faire suite à nos discussions, voici une nouvelle PR dans laquelle j'étends la classe `YagniTicketTarification` car **les tranches d'age qu'elle utilise ne me conviennent pas/plus** : pour moi, **un bébé n'en est plus un à partir de deux ans**. Il sait (normalement) marcher, parler, ... c'est donc devenu un enfant :)

Bref, j'étends donc cette classe en redéfinissant la méthode protected qui va bien, à savoir la méthode `isConsideredABaby`.

Le "problème" c'est qu'en réalité, **je n'ai pas cassé le contrat de la classe** `YagniTicketTarification` qui, par sa seule méthode publique, va toujours me retourner un flottant représentant le prix d'un ticket pour une personne donnée.

Je n'ai pas cassé son contrat, par contre, **j'ai largement modifié son comportement**. Et bien que le contrat soit toujours respecté, la méthode ne se comporte plus du tout de la manière (bon j'exagère un peu là :wink:).

Je dois donc figer le nouveau comportement au niveau des tests unitaires associés à cette nouvelle classe. 

Comme je travail en TDD et qu'à priori, je ne sais pas trop ce qui est à ma disposition dans le code pour créer le nouveau comportement, je vais commencer par mettre un test au niveau de la méthode publique de la classe que je vais écrire : j'ai une interface à respecter, je sais donc avec certitude par où commencer.

En travaillant de cette manière, qu'est ce qui se passe : 

* Une grande partie (la totalité en réalité) du **test unitaire de la classe mère est dupliqué**
* Dans le nouveau test unitaire, **je modifie uniquement les données fournies par le *provider* pour coller à ce que je souhaite implémenter**
* **je test toujours totalement** mes *protected* à travers la méthode publique
* je fige/spécifie/définis/test le comportement que je veux implémenter
* **j'assure que le reste fonctionne toujours de la même manière**
* **je reste le plus loin possible des détails d'implémentation** internes de la classe (à savoir les *protected*s)

La seule chose ici qui, pour moi, pourrait poser problème est la duplication de code au niveau du test, mais est-ce réellement un problème dans les tests si je peux garantir que **mon code est toujours bien couvert**, que lui **ne contient pas de duplication**, qu'il est propre et surtout, qu'**il fait le travail demandé** ?

D'autre part, **si demain je souhaite déléguer la logique de vérification de l'age à un autre composant, mon test ne bougera pas**. Oui je sais, il ne faut pas penser à demain, désolé, je ne peux pas m'en empêcher :laughing:.

Voilà le genre de cas qui me fait dire que tester les *protected* n'est pas forcément nécessaire. Elles sont là pour supporter les méthodes publiques, j'ai donc toujours un point d'entrée pour atteindre leur code, le stresser, et vérifier les retours.

Imaginons maintenant que j'aie pu tester les *protected* : peut-être que j'aurais eu tendance à vérifier uniquement le retour booléen de la méthode `isConsideredABaby` car c'est la seule chose que ma nouvelle classe contiendra. 

Là, je vois une première erreur : en théorie, je ne sais pas ce que ma classe contiendra. Je sais juste que je veux qu'elle considère des tranches d'age différentes et que celles-ci influenceront le prix unitaire d'un ticket.

Passons sur cette erreur : si j'avais travaillé de cette manière (en commençant par couvrir `isConsideredABaby` à l'aide d'un T.U), j'aurais peut-être loupé le fait que ma modification n'était pas suffisante.

En effet, pour que tout fonctionne, **j'ai également du légèrement modifier la méthode `isConsideredAChild` de la classe mère** pour que celle-ci s'adapte à la nouvelle borne de ma tranche.

On vois tout de suite qu'en s'approchant trop d'un détail d'implémentation, on peut commettre une erreur : si la vérification des tranches était implémentée dans une méthode unique, je n'aurais pas eu à faire cette seconde modification car un `return` aurait certainement été fait dès que la personne validait une tranche (`#1` et `#3`dans les exemples). Avec un `if`/`elseif`/`else` tout aurait pu être différent (`#2`):

```php
// #1
switch (true)
{
    case $age < 4:
        return 2.0;

    case $age < 12:
        return 10.0;

    default:
        return 30.0;
}

// #2
if ($age < 4) {
    $price = 2.0;
} elseif ($age < 12 && $age >= 4) {
    $price = 10.0;
} else {
    $price = 30.0;
}

return $price;

// #3
if ($age < 4) {
    return 2.0;
} elseif ($age < 12) {
    return 10.0;
} else {
    return 30.0;
}

// #4
// @see https://github.com/geraldcroes/yagni/blob/master/yagni/sources/YagniTicketTarification.php#L4
```

*Les 4 implémentation précédentes sont équivalentes mais ne nécessitent pas les mêmes interventions en cas de modification.*

Je préfère donc dupliquer du code dans les tests et **TOUJOURS** couvrir l'interface publique, même si je ne modifie que l'implémentation interne. Je garantis ainsi que le service attendu est toujours bien rendu, au niveau des nouvelles règles mais également au niveau des règles que je n'ai pas touchées.