Florent Biville et Agathe Vaisse
Durée :
Vues : 394
5 likes
Publié : novembre 4, 2020

Transcription

[00:00:15] Euh, bonjour à tous. Merci d'être là. Ce soir, nous allons vous présenter l'hygiène de développement en temps de pandémie, c'est-à-dire que nous allons parler de méthodes de travail et les deux pandas. Alors moi, je suis Agathe Bess, je suis développeuse principalement back-end euh exclusivement chez Wise et CFF. Euh, développeuse c'est pas mon premier métier, j'ai fait une reconversion professionnelle il y a quelques années. Et euh, je co-organise avec Florent le Meetup Hacker Garden Paris qui a lieu tous les mois et euh, à Commente Push qui a lieu une fois par an et qui euh, en fait, ce sont des événements qui permettent de contribuer à des projets open source. Euh, à côté de ça, je suis aussi passionnée de littérature fantastique et ce soir, c'est mon premier talk, c'est mon premier live coding. Je suis sur un Mac avec un clavier Qwerty, donc autant vous dire que ma zone de confort, elle est très très loin. Donc merci pour votre bienveillance et je vais laisser Florent se présenter.
[00:01:09] Euh, yes. Alors effectivement, ce sera un live coding avec tous les risques que ça peut comporter. Euh donc pour ma part, je suis développeur à New Forge depuis un petit mois. J'étais à Pivotal qui a été acquis par VMware ensuite, donc je suis resté avec moi un petit peu. Euh donc comme Agathe, donc je co-organise ce Meetup Paris tous les mois, même si cette année la période est un peu compliquée. Le Hacker Garton Paris pour réunir contributeur maintenant de projets open source et euh et et contributeurs potentiels qui veulent être un peu guidés euh sur sur leur première contribution. Donc ça, on le fait vraiment tous les mois pour le coup, notamment en virtuel en ce moment. Et Hack Commit Push qui est que Agathe a aussi mentionné, qui est le même format qu'Hackerton, mais avec plus de gens et plus longtemps sur toute la journée, qui est gratuit et qui est pour l'instant une fois par an à Paris et si le contexte s'améliore, on le fera peut-être aussi à d'autres endroits. Et ma passion, à part euh à part montrer des blogs en live, bah c'est d'apprendre le Turc, qui est la langue de ma belle famille, donc voilà. S'il y a des Turcophones au passage, euh vous pouvez poser les questions.
[00:02:08] Posez des questions.
[00:02:09] Voilà, posez les questions, ça sera ça sera ça sera une bonne dose de stress supplémentaire.
[00:02:15] Et donc du coup aujourd'hui, ce qu'on va vous montrer euh et peut-être vous convaincre, c'est de un exemple, c'est notre façon à nous en tout cas, quand Agathe et mon travaillent ensemble, de faire du Test Driven Development et du Pair Programming. Euh Et pour ça, on a pris le le biais d'une petite application assez simple, un petit jeu web et qu'on vous montrera un petit peu plus tard. Encore une fois, faut pas prendre tout ce qu'on fait à la lettre, c'est notre interprétation, on s'est peut-être un peu éloigné parfois de pratiques plus. Donc faites-vous votre idée, nous c'est juste pour vous illustrer que bon, c'est pas quelque chose qui est réservé à une élite ou quoi que ce soit, c'est des méthodes qui sont ouverts à tous, quelle que soit la code base sur laquelle vous travaillez. Notamment aux débutants. Yes, complètement.
[00:03:01] Alors Test Driven Development c'est quoi? Test Driven Development, c'est avant tout un cycle en fait, un cycle qui est centré sur du feedback, on veut du feedback immédiat. Et ce qu'on va faire très souvent, c'est qu'on va exprimer notre intention. Alors le plus souvent sous la forme d'un test exécutable, on va on va écrire un test avant donc on va essayer d'exprimer notre intention sous la forme d'un test. Évidemment le test, vu qu'on l'écrit avant d'écrire quelle implémentation que ce soit, il va d'abord ne pas passer, il va d'abord être en échec. Donc il y a cette notion de red. qui va arriver tout de suite. Donc ce qu'on veut d'abord voir, c'est exprimer notre intention, vérifier que il n'y a rien dans le code qui est prêt pour que cette intention soit déjà réalisée. Donc ça c'est l'étape red. Ensuite s'evertuer à faire en sorte que le le test, donc notre intention qui a été traduite en code passe et donc ça c'est l'étape green parce que du coup le test va passer, va être en succès et donc vraiment faire le minimum possible pour que le test passe hein. Donc on va pas essayer de coder une application entière dans cette étape là. On va vraiment penser à un aspect particulier de la feature qu'on est en train de développer. bah là, on peut prendre un petit peu de recul, on se dit, OK, donc là, OK, je viens de faire le minimum, c'est très bien. Est-ce que je peux améliorer un petit peu ce que je viens de faire, tiens, il y a la duplication, par exemple, il y a on fait la même chose à deux ou trois endroits différents, peut-être que je peux centraliser ça et cetera et cetera. Donc voilà, c'est pas juste on pas juste les les les œillères là. On essaie, on prend un moment, mais pas pas tout le temps, à un moment bien précis, quand tous les tests passent, on peut se permettre euh de réfléchir à améliorer les choses qu'on a écrites. Mais en tout cas, voilà, c'est vraiment centré sur le fait que on a un test en échec. Un test ensuite qu'on fait passer via des steps minimales. Donc vous entendrez parfois parler de baby steps parce qu'on essaie vraiment de faire le l'étape minimale. Et enfin, refactorer, donc refactorer, c'est un sens bien spécifique. hein, c'est euh modifier du code pour qu'il soit plus maintenable. sans pour autant modifier son comportement observable. Sinon c'est plus du refactoring, c'est une modification qui a entraîne potentiellement des régressions. Donc ça c'est pas quelque chose qu'on veut. Et donc ce qu'il faut voir aussi et ça, on s'en rend compte pas forcément au début, on s'en rend compte au fur et à mesure avec l'expérience, c'est que le Test Driven Development, c'est aussi une acceptation que euh on ne sait pas tout. Et même quand on croit tout savoir et qu'on croit savoir tout implémenter d'un coup, finalement, on fait toujours des erreurs. Donc c'est aussi savoir rester humble et par rapport à l'inconnu qui qui qui se déroule devant nous. Et donc c'est vraiment l'idée de se forcer, alors au début, il faut se forcer. C'est pas c'est pas forcément naturel de d'avancer pas à pas de ces fameuses baby step justement. Donc vraiment il y a cette notion d'humilité au dire, je vais me forcer. Même si je pense avoir une idée précise ou pas de ce que je veux faire, je me forçais à y aller étape par étape et euh et avancer petit à petit. Et mine de rien, il y a beaucoup de d'effets de bord positifs du Test Driven Development. Il y en a un, il se trouve que vu qu'on se force à déclarer notre intention avant d'implémenter quoi que ce soit, donc on va implémenter notre intention sous forme de test. Bah ça permet aussi d'avoir un support objectif de communication. Parce que par exemple si vous travaillez avec quelqu'un d'autre ou dans une équipe, euh si quelqu'un arrive pour savoir ce que vous faites, on dit, bah voilà, je suis en train de travailler sur ce test là. Et ça c'est complètement objectif hein parce que c'est un test qui va passer ou qui va ne pas passer, donc quelqu'un d'autre peut le dire et comprendre ce qu'on est en train d'essayer de faire. Donc ça aide aussi beaucoup à la communication. Et enfin, alors ça c'est la partie un peu Captain Obvious hein, mais quand vous faites du TDD, vous avez du code forcément testable puisque il est testé. Ça c'est un peu logique, mais c'est pas forcément l'aspect. le plus important, c'est un c'est un bénéfice évidemment euh très sympa, très pratique qui permet d'avoir tout un tas de de tests de non régression ensuite. Mais vraiment moi je vois ça le TDD avant tout comme un comme un support de communication et pour soi-même, pour savoir dans quelle direction dans quelle direction on va, mais aussi pour les autres pour les embarquer ensuite bah notamment donc quand on fait du pair programming ou du mob programming.
[00:06:55] Alors le pair programming du coup, c'est quoi?
[00:06:58] Alors le pair programming, c'est une pratique de développement qu'on pratique donc en binôme avec un pair. Ça peut être colocalisé, donc on va être tous les deux au même endroit sur le même poste comme on l'est là ce soir. Mais ça peut être également à distance ce qui ce qu'on pratique beaucoup actuellement avec un partage d'écran. Donc dans le pair, il y aura un conducteur, un pilote qui va coder et un navigateur ou un copilote qui euh qui lui va faire des recherches, qui va vérifier des choses, qui va peut-être contredire ce qui a été codé par le pilote ou qui va donner son avis tout simplement, qui va essayer d'avoir une vision globale en fait du code qui est en train d'être écrit et qui va maintenir aussi la vision globale de l'application. Donc ça c'est son rôle. Euh, il y a plusieurs façons de pratiquer le pair programming. Euh classique comme j'ai un peu de vous décrire en fait, ça va être une discussion assez naturelle et euh on va changer de rôle à un intervalle régulier. Ping-pong, donc ça c'est du pair programming avec du TDD. Donc l'un écrit un test, l'autre écrit l'implémentation. Le premier reprend le clavier pour faire le refactoring. Et euh, et ainsi de suite en fait. Donc, euh, vraiment euh tout est décomposé entre euh entre euh entre le binôme. Et couplage fort, donc c'est quelque chose que j'ai testé quelques fois que j'apprécie moyennement. mais il faut savoir que ça existe. Donc le pilote ne va coder que ce que le copilote lui dit d'écrire. Donc voilà, il y a vraiment Voilà, il y a vraiment une autre relation, mais bon, ça peut fonctionner dans certains cas. donc pourquoi pas notamment peut-être avec quelqu'un de de moins expérimenté. Voilà. Voilà, donc les avantages du du pair programming euh on est spécialiste dans les blagues euh très drôles.
[00:08:41] Euh voilà. Donc voilà, les avantages du pair programming. Euh, on est spécialiste dans les blagues euh très drôles. Donc si tu perds, tu gagnes. Euh, ça va surtout nous donner un feedback très rapide sur notre notre code vu que il y a quelqu'un qui va le regarder constamment et donner son avis dessus. Euh, on va pouvoir monter en compétence chacun euh chacun l'un l'autre en fait, on va se tirer vers le haut, on va apprendre de l'autre. Ça c'est vraiment quelque chose de de très important dans le pair programming. On va essayer aussi de renforcer l'esprit d'équipe, la collaboration. Donc c'est bien dans une équipe de faire tourner les binômes pour que ce soit pas toujours les mêmes personnes qui qui fonctionnent ensemble. Euh, si jamais on est face à un mur et qu'on sait absolument pas quoi faire, bah là on n'est pas tout seul. Donc généralement même quand les choses sont compliquées ou paraissent compliquées, on va parvenir à avancer. Et surtout, il faut pas oublier qu'en pair programming, il faut prendre des pauses, il faut prendre le temps, c'est pas du 9h 18h en pair programming parce que là c'est vraiment très très dur, faut vraiment accepter que c'est bien de prendre une pause de temps en temps. Et euh, ça va permettre de une meilleure qualité de travail.
[00:09:56] Et c'est l'heure du live coding. C'est parti.
[00:09:59] Yes. Et donc le mystère du panda enfin révélé. Euh parce qu'on a eu voilà, on a fait une étude de marché énorme, il y a un très très grand besoin d'un nouveau jeu de pendu. Sauf que le pendu en tant que tel, le concept est un petit peu un petit peu gore, c'est dommage. Donc plutôt qu'exposer les les enfants à un pendu réel, on s'est dit qu'avec un panda, c'était plus mignon. Donc le panda, quand on se trompe, il perd il perd ses bonbons un par un jusqu'à ce qu'il soit inconsolable. Et donc l'idée du pendu, si jamais vous ne connaissez pas, on ne sait jamais, ça peut arriver, vous avez un mot à deviner, un mot mystère à deviner. Et vous avez un nombre d'essais un nombre d'essais limité, pardon, pour deviner les lettres du mot. Donc vous soumettez caractère par caractère. Donc du coup ce qu'on a fait euh et ce qu'on va faire là, c'est on va compléter, enfin on va essayer de compléter, hein, si tout se passe bien, si les dieux de la démo sont contre nous, bah ça se passera moins bien. On va essayer de compléter le jeu justement pour ben implémenter les règles du jeu du Penda. qui est donc un panda qui remplace le pendu. Donc je sais pas comment on le prononce, mais ça je vous laisserai décider entre vous.
[00:11:00] Et donc en fait, ce qu'on va effectivement faire en mode ping-pong, comme l'a expliqué Agathe, ping-pong, hein, donc rappelez-vous du red green refactor. Le test, le premier écrit un test en échec, le deuxième répare le test. introduit un nouveau test en échec, alors éventuellement avec du refactor entre deux et ainsi de suite. et et comme ça ça tourne tout le temps. Donc faisons un peu l'état des lieux de l'application. Alors, à quoi elle ressemble aujourd'hui? Donc là, je vais euh, alors je pourrais lancer le vrai backend, bah je vais lancer un faux backend. En gros, on on utilise en vrai une API de dictionnaire pour avoir un mot aléatoire dans différentes langues. Là, je vais je là, je vais faire la version rapide comme ça, ça ira un petit peu plus vite. Donc je démarre mes API derrière qu'on a implémenté et qu'on va pas faire en live hein parce qu'il nous faudrait il nous faudrait une quarteur si on voulait faire l'API entière en live coding et puis ce serait pas forcément beaucoup plus intéressant pour illustrer un peu nos nos mécaniques à nous de de TDD et de et de pair programming. Donc j'attends un peu que l'applie démarre, j'ouvre un bon navigateur. OK, l'applie est démarrée donc on est content. Et donc derrière, à quoi ça ressemble, juste pour vous donner une idée, même si là le jeu en l'occurrence, il n'est pas complété, hein, il est pas fini, donc justement, il va falloir qu'on complète. Donc on va choisir une langue, bon il se trouve qu'en vrai on en a beaucoup plus. Prenons le français par exemple. Et on a un magnifique écran où il faut qu'on devine un mot mystère. Donc là on se rend compte que euh il y a cinq lettres à deviner. Et donc on va aller deviner petit à petit. Donc là vous verrez que il va pas se passer grand-chose, là j'essaie de deviner des lettres, il se passe strictement rien. Pourquoi? Parce que autant on a terminé le travail de UI. mais on n'a pas euh on n'a pas encore implémenté les logiques du jeu. Donc on a une question sur le TCR. Alors pour le coup, effectivement, il y a Kenbeck qui qui est qui qui a introduit cette méthode. il y a quelques mois ou peut-être un an, je sais plus exactement. J'avoue je n'ai personnellement pas testé. Donc j'ai pas d'avis particulier sur TCR. C'est quelque chose qui est sur ma to-do list mais malheureusement pas encore au top de ma to-do list. Mais non, pour le coup pas pas d'opinion là-dessus de mon côté. J'ai pas d'avis particulier sur TCR. C'est quelque chose qui est sur ma to-do list mais malheureusement pas encore au top de ma to-do list. Mais non, pour le coup pas pas d'opinion là-dessus de mon côté. de mon côté. Et donc en fait, ce qui est intéressant aussi quand on fait du TDD euh ou slash du pairing, bah c'est de quand on sait plus trop où on en est, et bah c'est de laisser un test en échec. Alors nous dans notre cas, en fait, on va démarrer par quoi, on va démarrer par un test end-to-end en échec. Donc on va regarder ce qui se passe, si je lance mon test end-to-end. Et je devrais donc avoir un test en échec qui va me rappeler un petit peu là où j'en suis euh dans le code. Et ça, ça peut être très pratique notamment le soir, par exemple, quand vous finissez votre journée, vous dis bon, je vais laisser je vais rester sur un test en échec, comme ça demain euh je sais où j'en suis exactement. je sais où j'en suis exactement.
[00:13:36] Je sais où j'en suis.
[00:13:38] Et donc là, oh patatra, il y a un test qui ne passe pas. Qu'est-ce que c'est que ce test? Euh si on regarde un peu plus haut, shoot display fail de terms in 30 order. Donc si on regarde un petit peu, c'est une appli Angular, au fait. Donc c'est c'est basé sur du protractor pour les tests end-to-end. Et donc si on regarde et même si vous êtes pas développeur full time, même si vous faites pas de TypeScript ou et cetera, ça devrait être relativement compréhensible ce qui se passe ici. Parce qu'on est sur du pattern Page Object, on va l'écrire notre page comme on écrirait une classe classique en programmation orienté objet. Et donc là typiquement il y a ce qui se passe. J'ai ma page de sélection de langue, qu'on a vu tout à l'heure, je choisis une langue, donc je choisis le français. Euh, j'essaie de deviner deux lettres et il se trouve que les deux lettres ne correspondent pas au mot aléatoire qui a été choisi. Alors comment je sais ça, vous allez me dire mais où est le mot aléatoire qu'on doit deviner? Bah en fait, en fait ça utilise le fake back-end que j'ai que j'ai expliqué tout à l'heure et vous en fait vous voyez que dans la langue française, le mot à deviner est Panda. Et donc dans Panda, il y a ni la lettre E ni la lettre B. Donc quand je récupère les tentatives en échec, je devrais avoir dans l'ordre alphabétique, le B et le E. Donc voilà où on en est et ça ne passe pas. Donc du coup ça nous donne déjà une direction dans laquelle on veut aller. On sait déjà que les feuilles de themes pour l'instant, ça ne passe pas du tout. Et donc ce qu'il faut regarder maintenant, bah alors la page il se trouve donc là on va aller, on est sur une version un peu idéalisée hein du TDD du pairing ici parce qu'on s'est en fait, on a déjà codé la pluie avant. Donc on sait déjà plus ou moins dans le direction où on en veut aller. En vrai, ça met plus de temps, mais il faut accepter que notamment au début, c'est des choses qui prennent du temps. Mais là, on va aller un petit peu vite vu qu'on a un temps limité. Il se trouve qu'en fait, euh si je regarde les fail de temps, sur mon template HTML, donc le HTML de la page qui nous intéresse, euh, on va les afficher. Exactement. Et il se trouve qu'en fait, si on regarde les fail de temps aujourd'hui. ça vient d'un game state. Donc on prend les fail de tems et on les trie par par ordre alphabétique hein. par ordre selon le code de la langue. Et si je garde ce fameux game state, il vient d'où? Si je reviens sur le template, bon là c'est un peu de la technicité Angular, mais peu importe, j'ai un observable qui me produit, donc j'ai une sorte de canal qui me produit des game state à chaque fois. et je regarde un game state en particulier. Et si je je regarde d'où vient ce conduit entre guillemets, cet observable de game state, il vient d'ici. OK, super, mais qui l'initialise? Là, on va voir ce qui se passe, mais pour l'instant, il est hardcodé sur un observable avec un game state vide. Donc il est en fait, j'ai un conduit qui n'aura que toute sa vie qu'une seule valeur. Donc ça, ça va clairement pas, donc il va falloir qu'on corrige ça. en fait j'ai un conduit qui n'aura que toute sa vie qu'une seule valeur. Donc ça ça va clairement pas donc il va falloir qu'on corrige ça.
[00:16:10] Et le game state en fait, ça va représenter l'état du jeu avec le mot à deviner, le nombre de tentatives maximum accordées, le nombre de tentatives restantes et euh aussi euh savoir quelle lettre du mot ont déjà été devinées ou pas.
[00:16:25] Et donc là, je vais parler beaucoup moins parce que je vais commencer justement à à ajouter euh, entrer dans ce Red Green Refactor et donc c'est Agathe qui va commenter ce que je fais.
[00:16:34] On va utiliser la notion de service en fait pour faire un pont entre cette recherche de lettres et euh et ce game state qui pour l'instant est hardcodé et qui va représenter l'état d'avancement du jeu. Donc on va écrire un premier test qui va initialiser en fait un game state de départ qui va se lancer quand on va commencer le jeu.
[00:16:56] Yes. Yes.
[00:17:00] On va s'appeler service, pardon. Alors on va s'appeler service, pardon.
[00:17:04] Oui, service.
[00:17:07] Donc on va souscrire, on va utiliser une méthode d'initialisation qu'on va appeler init tout simplement.
[00:17:15] Le mot à deviner sera donc Panda. Donc les deux arguments de notre méthode init, ça va être le mot à deviner et euh on anticipe légèrement, mais on sait déjà qu'on aura qu'on va suivre un patterne de de caractère en fait. Donc on anticipe un petit peu.
[00:17:34] Voilà et donc là vous voyez qu'on n'est pas sur du TDD à la lettre parce que je triche un peu, je sais que je vais en avoir besoin après. En vrai, j'aurais pu me contenter juste du premier du premier paramètre là comme le disait Agathe.
[00:17:44] Ce qui va se passer après, c'est qu'on va Ah oui, juste une seconde, game state avec un dollar. Donc le dollar en fait, c'est une convention Angular qui est largement adoptée qui indique que la constante game state là, c'est un observable. Donc nous on l'utilise ça généralement. Donc nous on l'utilise ça généralement et on va se souscrire à cet observable. Euh et en commençant à jouer, on va pouvoir recevoir un nouveau game state tout neuf de départ. Voilà, et on s'attend à ce que là dans les assertions, on va s'attendre à ce que le game state et un nombre restant un nombre de tentatives restant. égal au nombre de tentatives maximum auquel a droit le joueur et euh on s'attend aussi à ce que le le nombre de tentatives échoué soit égal à zéro parce que pour l'instant, il n'y a pas eu d'essai de la part du joueur pour deviner le. Alors le donne à la fin, c'est juste pour signaler que on va s'arrêter là en fait parce que notre test est pas synchrone et euh on a on a besoin de signaler que le test est terminé quand on a reçu l'observable.
[00:18:44] Alors alors certains adeptes du TDD s'arrêtent aux erreurs de compilation. Ils disent bon, ça compile pas, ça ça revient à un Red state qui se discute. Moi pour le coup c'est je j'aime bien quand même que ça compile. Donc là on est en TypeScript, on n'est pas en JavaScript, donc il y a effectivement une sorte de phase de de transpilation ou de compilation vous l'appelez comme vous voulez. Euh, moi j'aime bien quand même que ça compile un minimum. Donc euh que je mets quand même la signature et puis ça aide aussi à renforcer un peu l'intention du test, quoi. Là, on voit bien, on voit bien ce qu'il faut faire. Donc je fais je fais mon truc minimum pour que ça passe. Alors ça se discute hein. Ça se discute, il y a vraiment plein de façons de faire, encore une fois, c'est notre mécanique à nous, c'est pas forcément celle à adopter universellement. Et donc à ce stade, je devrais avoir un test en échec. en plus du test end-to-end. Le test end-to-end vraiment pour une tâche de fond parce que le test end-to-end souvent c'est un peu plus large que une simple baby step. Donc là déjà, je veux avoir cette notion de de de game service et je si le test s'échoue bien comme il faut. à savoir que pour l'instant, init renvoie un conduit vide. Donne du coup ne va jamais observer de game state. parce que pour l'instant mon conduit reste vide entre guillemets, mon observabble reste vide. Donc donne n'est jamais appelé. Donc le test n'est jamais fini et alors plutôt que d'attendre à vitam etnam, on va attendre un timer.
[00:19:27] euh que je mets quand même la signature et puis ça aide aussi à renforcer un peu l'intention du test quoi. Là on voit bien on voit bien ce qu'il faut faire. Donc je fais je fais vraiment mon truc minimum pour que ça passe. Alors ça se discute hein. Ça se discute, il y a vraiment plein de façons de faire, encore une fois, c'est notre mécanique à nous, on c'est pas forcément celle à adopter universellement. Et donc à ce stade, je devrais avoir un test en échec, en plus du test one, un test un point vraiment au servir pour une tâche de fond. parce que le test souvent c'est un peu plus large que une simple baby step. Donc là déjà, je veux avoir cette notion de de de game service et je si le test échoue bien comme il faut. à savoir que pour l'instant, init renvoie un conduit vide.
[00:20:12] donne du coup ne va jamais observer de game state parce que pour l'instant mon conduit reste vide entre guillemets, mon observateur reste vide. Donc donne n'est jamais appelé. Donc le test n'est jamais fini et alors plutôt que d'attendre à vitam, on va attendre un timeout. Donc là du coup le test est en échec et la mission de la mission d'Agathe cette fois si elle l'accepte. en même temps si elle l'accepte pas, je sais pas comment on ferait, ça va être de faire le job minimum. pour ben pour simplement déjà émettre euh hop, je mets des je vais implémenter la méthode init en fait.
[00:20:43] Je vais me mettre un peu derrière.
[00:20:45] Exactement, vas-y.
[00:20:47] Je vais passer.
[00:20:48] Donc là ça va là le but ça va être quoi? Ça va être simplement à ce stade, on est juste focalisé sur le fait que on veut émettre un game set initial. On va rien faire d'autre, on va pas commencer à faire d'autres choses. Et une fois et en fait l'idée l'idée de ce game service juste pour revenir un peu pourquoi on est parti la tête dans le guidon sur les game service, ce game service va faire un peu le pont entre ce qui se passe dans notre page HTML, à savoir j'ai un formulaire, rappelez-vous, j'essaie de cliquer sur les tentatives et soumettre des tentatives. Et donc ça ça doit être transmis à notre game service qui lui-même va ensuite décider du prochain game state en fonction de la tentative qui a été faite. Donc typiquement si Panda je commence par soumettre la lettre P, et ben alors tu vas avoir un nouveau game set, tu vas oui, bien joué, tu as trouvé la lettre P, du coup on va afficher la lettre P et les autres lettres sont encore à révéler et ainsi de suite. Vous voyez qu'il y a les états, les états qui sont calculés en fonction de l'état précédent et de la tentative en cours et ce ce calcul est encapsulé par par l'ami euh game service.
[00:21:47] OK. Je suis désolé pour mon temps de frappe. C'est assez dur de passer sur un clavier.
[00:21:54] Et donc là ce qui est intéressant c'est que ce qu'a fait Agathe en fait, elle a utilisé un behavior subject qui permet en fait rappelez-vous que c'est un conduit observable. Donc si vous subscribe, si vous subscribe, désolé pour l'anglicisme, si vous subscribe un observable mais que la valeur a déjà été mise, vous allez pas les voir, ce sera trop tard. Alors justement le behavior subject permet d'avoir une sorte de buffer de cache de la dernière valeur et du coup les nouveaux subscriber qui arrivent après vont voir cette valeur. Donc ça c'est assez utile comme ça ça permet de se dédouaner un peu de cette notion de timing qui est un peu pénible. Donc là le test passe. Donc ça c'est une bonne nouvelle mais en l'état, euh c'est pas très très satisfaisant. Il faut quand même faire la corrélation entre les key strokes, donc les les essais, les lettres qu'on tape pour deviner le mot et le calcul du game state. parce que là aujourd'hui on on là à ce stade, l'implémentation qu'est-ce qu'elle fait ? Simplement elle va calculer un game state indépendamment de ce qu'on tape. Donc là le prochain test, qu'est-ce qu'il va essayer de faire ? Et ben il va essayer justement de de simuler non pas en terme HTML parce qu'on n'est pas au niveau d'un component d'angular, un component qui fait vraiment les l'abstraction de la page du HTML donc du DOM. pour appeler des services, on est au niveau service, donc on va simuler le fait qu'on essaie d'envoyer un caractère en particulier et que du coup ça a une influence sur le game state qui est calculé. Et donc là l'idée ça va être quoi ? Bah déjà on va essayer de simuler le fait qu'on envoie euh qu'on envoie un caractère et donc c'est là où le deuxième paramètre de que j'avais introduit un peu tôt dans le premier test a tout son sens. Là pour l'instant une 30 si vous regardez, on a off string qui fait strictement rien. Et ça en fait on va la remplacer par
[00:23:31] par un conduit.
[00:23:32] un conduit dans lequel on va publier une valeur. Donc pour ça observable c'est une partie dans laquelle on peut seulement lire, il va falloir qu'on crée un subject juste avant le service init et ce subject, c'est quelque c'est un conduit dans lequel on peut aussi écrire. Et nous dans le test c'est exactement ce qu'on veut, parce qu'on veut produire des caractères, on veut produire des caractères qui vont dire la lettre qu'on est en train d'essayer de deviner pour le mot pour le mot mystère. Donc on a un subject et ce subject qu'est-ce qu'on va faire ? Du coup, plutôt que d'avoir un off string ligne 31, on va on va publier la partie lisible de ce subject. Alors attention, c'est shift.
[00:24:07] sur un coire.
[00:24:08] C'est les joies les joies du clavier quand on est pas habitué. Donc on pourrait imaginer un type caractère en TypeScript ou bon ça mettrait plus de temps que ce qui est vraiment intéressant, donc on l'a pas fait, on fait strings ce qui est un petit peu limite. Et donc ce subject il y a plusieurs usages. Déjà on va vouloir ligne 31 donc on a un off string, on va le remplacer par un keystroke as observable. Ça ça veut dire quoi ? Ça veut dire qu'on va qu'on va permettre qu'on va exposer au service la partie lisible. Donc lui il pourra subscribe dessus mais il pourra pas écrire dedans. On veut vraiment qu'il y en ait qu'un seul qui écrive. Et ensuite qu'est-ce qu'on veut, qu'est-ce qu'on veut ? Ben on veut écrire un caractère dedans. Donc c'est ce qu'on va faire du coup, c'est dans ce subject on va écrire une lettre et et voir que le game state qui est mis ensuite euh est euh dépend de la lettre qu'on vient d'écrire. Donc typiquement c'est quelque chose qu'on va faire en fin de test, on va faire juste après subscribe. Vous voyez l'avantage du TDD là c'est que Agathe elle est en plein stress.
[00:25:01] C'est ça.
[00:25:02] Elle est en train de perdre ses moyens en live. Mais moi je suis moins stressé du coup je peux aussi l'aider vous voyez. C'est quand même l'avantage du même dans des situations comme celle-là. Et donc là l'idée c'est qu'on a ce subject qui s'appelle keystroke. On va pouvoir faire un next. Next en gros c'est pour soumettre une valeur dans le conduit et tous ceux qui subscribe pourront l'observer. Et donc là on peut prendre n'importe quelle lettre.
[00:25:25] Par exemple.
[00:25:27] Par exemple la lettre C. Alors du coup la dernière partie la dernière partie qui reste c'est adapter ce subscribe. parce que rappelez-vous dans le premier test on a vu qu'on j'arrive plus à parler, on aimait systématiquement un état initial. Donc ça on le sait mais du coup cette fois ce ce à quoi on s'attend, c'est que maintenant que j'ai envoyé une lettre, je m'attends à ce qu'il y a un game state qui a été calculé que mon état du jeu change, je veux donc voir une nouvelle valeur. Donc pour ça, alors le if va pas forcément se passer tout de suite ici, ça va plutôt se passer dans le subscribe, mais il va falloir qu'on compte. Une façon de faire, c'est de se dire qu'on on a l'état initial, ça c'est le test d'avant. On envoie un deuxième état, donc pour ça il faut compter.
[00:26:02] On va avoir un deuxième gap state qui est observé par le subscribe. Et si on arrive à un deuxième état, alors on va bien observer que ses caractéristiques prennent en compte prennent en compte la tentative qu'on vient de faire.
[00:26:17] Ça va être bien.
[00:26:19] Et donc on va arriver au deuxième game state, donc on part à zéro, donc du coup on va arriver à un. Si on arrive à un, là on va pouvoir faire nos expect et notre donne pour signaler que la le test est fini.
[00:26:32] il manque une acolade ouvrante.
[00:26:34] Je l'avais mis pour.
[00:26:35] Ouais, mais tu l'as tu as dû la supprimer bizarrement. Voilà et donc ce qui va manquer ensuite c'est d'incrémenter ce compteur sinon. Commande Alt L si tu veux.
[00:26:47] Je vais le faire si tu veux.
[00:26:47] Non non, c'est bon t'inquiète.
[00:26:48] Je vais. Commande Alt L et ça devrait reformatter le tout.
[00:26:52] Option L.
[00:26:54] Wai. OK. Et il faut donc incrémenter le compteur sinon sinon on arrivera jamais à
[00:26:59] Yes. Alors.
[00:27:04] Et donc là si on regarde ce qui se passe côté test, Donc là notre intention, je pense qu'elle est déclarée suffisamment clairement, on va tenter une lettre et on s'attend à ce que alors presque en fait, pas tout à fait, le test n'est pas tout à fait je parlais un peu vite. Ils sont que les left tems ce sera pas max tems, on aura pas le nombre max, on aura max tems -1. parce qu'on vient de griller une cartouche entre guillemets, on vient de griller une tentative parce qu'on vient de se planter grosso modo. Et fail the tems cette fois ce sera pas point size, ce sera fail the tems tout court, ça va être le set des tentatives ratées qui devra notamment contenir la lettre C qu'on vient d'essayer.
[00:27:37] Et là du coup, on a ça y est, on a enfin une corrélation entre les game states qui sont calculé et ce qu'on est en train d'envoyer via cette observable. Et une fois qu'on aura ce pont, le existe pas encore mais on peut se contenter du type caractère pour l'instant. Et donc là à ce stade, ça y est. Là on a notre intention est clairement déclarée. Du coup on va voir si le test si le test passe ce serait très étonnant. Mais le test a priori ne va pas passer parce qu'on on n'émet qu'un seul state initial et du coup on va jamais rentrer dans le if et on va jamais appeler donne et on aura de nouveaux timeout parce que du coup le test ne va jamais compléter. Donc voilà OK. Et donc là, j'arrête de parler et je prends la main pour essayer de corriger les choses.
[00:28:15] On va essayer de faire la corrélation entre les lettres que serviront à montrer et ce qu'on a en sortie. qu'est-ce qui va se passer. Tu veux le mettre en plein écran ?
[00:28:23] Ouais, je vais le mettre en plein écran effectivement, histoire que ça soit plus clair pour tout le monde. D'accord.
[00:28:29] Euh, on va souscrire aux événements d'entrée, donc les keystroke.
[00:28:35] Et le but du jeu, ça va être de publier un nouveau game state en fonction des événements qui arrivent. Donc,
[00:28:50] c'est bon.
[00:28:52] OK. Donc en fait ce ce comportement, il va être encapsulé dans dans la classe des game state avec enfin ça va être la méthode compute next state qui va produire un nouveau game state après chaque chaque essai de du joueur. Donc on va l'encapsuler dans cette classe.
[00:29:16] et elle va prendre la tentative en cours en paramètre et retourner un nouveau game state.
[00:29:24] Donc en sachant que là euh l'objectif c'est d'avoir un une tentative en moins vu qu'on a essayé une lettre qui ne fonctionnait pas, qui n'appartenait pas au mot à deviner. et euh d'ajouter cette lettre à nos tentatives infructueuses. Voilà.
[00:29:43] Ça c'est fait. Et là, vous voyez qu'on est sur vraiment une implémentation littérale, c'est pas c'est pas du tout complet mais dans l'état de notre test actuel, ça suffit. Cool.
[00:29:52] Ouais.
[00:29:54] Alors du coup, elle reste la question, euh bon bah là on a on a un game service qui fait le pont correctement, qui euh qui prend qui observe bien les qui demande à calculer le le game state en fonction. Est-ce que ça suffit pour notre test du coup ? Est-ce que est-ce que on a fini ? Alors du coup, on peut relancer le test pour être sûr, rappelez-vous, on avait un test qui était en échec. sur je sélectionne une langue et je veux voir que les tentatives de que d'échec sont bien affichées.
[00:30:21] Et alors ça met un peu de temps mais je sais pas, je sens, je je pressens que le test ne va toujours pas passer. Et incroyable, il ne passe toujours pas. Pourquoi ? Parce qu'en fait Game State.
[00:30:31] exactement.
[00:30:33] ce qu'on a montré au début.
[00:30:35] ça peut pas fonctionner pour.
[00:30:37] Donc là on va un petit peu vite, on va euh on pourrait le test drive aussi, on pourrait le piloter par des tests unitaires. Là on va aller un peu vite, on va pas le faire par des tests unitaires. Euh et du coup ce qu'on va faire bah c'est que plutôt que d'arder ce fameux observable de game state qui en gros va me va me mettre qu'une seule valeur dans toute sa vie, on va plutôt passer plus intelligemment par le game service qu'on vient de compléter. Et lui dire bah tiens voici le mot initial.
[00:31:02] qui doit d'ailleurs s'appeler je repasse en plein écran pardon, qui va s'appeler quelque chose qui va s'appeler Word par exemple. et euh les fameux inputs donc l'observable, il va venir d'où, il va venir d'input et en fait si on regarde ce qui se passe plus précisément, si on regarde d'où ça vient, vous verrez qu'en fait à chaque fois qu'on submit le formulaire.
[00:31:24] avec un caractère, on va publier dans ce subject.
[00:31:30] Donc c'est comme ça qu'en fait à chaque fois qu'on initialise le composant, il va initialiser un conduit un canal, je sais pas comment on peut vulgariser ça autrement, on va dire un canal dans lequel on va écrire à chaque fois qu'on soumet le formulaire. Donc à chaque fois qu'on tape une lettre, qu'on appuie sur entrée dans la page, il va envoyer via cette méthode next un nouveau un nouveau caractère et du coup cette fois ça y est, le game service va prendre la main et va calculer les game state en fonction de ce qui a été passé. Donc ça c'est cool, la question c'est est-ce que maintenant ça suffit à ce que les test passe, la suspense insoutenable.
[00:32:09] et là attention, tout le monde retient sa respiration, on en peut plus tellement il y a de suspense. Et là ça passe, merveilleux, super. En revanche, bon OK, là on prend un petit on fait on est au bureau, c'est la pause café, on se dit ouais mais attends, je crois qu'on a pas tout à fait fini en fait quand on discute.
[00:32:23] Et si on regarde bah notamment alors le game service, il a plutôt une bonne tronche hein. Il euh il a un game state initial et ce game state ensuite on va lui demander à chaque fois on va lui demander à chaque fois éventuellement d'ailleurs on va le changer un petit peu au passage. Donc ça c'est pas très grave. Vu qu'on fait vu qu'on fait quelque chose de mutable en fait ça va marcher. Il se trouve qu'en vrai si on l'avait fait de façon immutable là, il y aurait un bug mais encore une fois, si vous voulez voir une implémentation un peu plus soignée, on vous enverra la repository si ça vous intéresse.
[00:32:54] Donc là vu que c'est mutable, ça va marcher de ce prendre comme ça, c'est un petit peu moche mais en vrai en vrai il faudrait faire un petit peu autrement. Mais peu importe. En tout cas, il fonctionne à peu près, donc il va bien observer les caractères qu'on lui envoie et calculer un next state derrière.
[00:33:08] Mais alors du coup, qu'est-ce qui
[00:33:09] que là ça fonctionne en cas d'échec.
[00:33:11] Exactement. Rappelez-vous l'implémentation du compute next state c'est systématiquement il dit qu'on perd un essai et que tout ce qu'on essaie est faux. Ce qui est pas exactement l'implémentation vers laquelle on voudrait aller donc hop bah du coup on va commencer alors on l'a pas forcément on pourrait ajouter un test end to end, on n'a pas trop le temps, on va pas le faire. Euh mais on va on va compléter les tests. On va compléter les tests du game state et l'avantage du coup là c'est qu'on est complètement isolé d'observable, de pas observable, c'est beaucoup plus simple, on a juste du game state et des attributs à lui passer et on est sur des tests un petit peu moins techniques que tout à l'heure.
[00:33:41] la partie technique est terminée.
[00:33:43] Vous pouvez y aller.
[00:33:45] Et moi aussi. Et du coup cette fois, on va commencer, si je ne m'abuse, parce que je me rappelais même plus qu'est-ce qu'on veut faire.
[00:33:51] par un essai réussi.
[00:33:52] Par un essai réussi effectivement parce que vous voyez que là on échoue systématiquement alors que qui réussi il y a pas de raison que il y a pas de raison que ça marche. Donc.
[00:34:04] Hop, quelque chose comme ça. On veut on veut prendre en compte les alors désolé pour l'anglais, c'est peut-être pas complètement correct mais les anglophones bilingue dans la salle, on est désolé. Donc qu'est-ce qu'on a ? Donc on veut un game state. Là d'ailleurs, j'arrête de parler puisque faut que je code, faut que je me concentre, pardon.
[00:34:23] Euh donc on a un game state et ce coup là on va voir on va essayer de faire des assertions sur ce qui pourrait se passer si le joueur réussit à trouver une lettre. Donc là, rappelez-vous le mot à trouver c'était Panda.
[00:34:36] Donc on va chercher avec la lettre N, on va relancer la même méthode qui doit produire un nouveau game state à chaque essai de l'utilisateur. Et on va vérifier que le nombre de tentatives échouées va rester à zéro. Donc ce sera zéro. Et on va également vérifier que le nombre de tentatives restantes euh va va pas diminuer en fait, parce que quand tu mettes est trouvé, on conserve notre nombre de tentatives. Sinon ce sera un petit peu compliqué.
[00:35:11] Euh on va aussi vérifier que euh on va bien afficher en fait les les tentatives échouées parce que le but du jeu c'est de montrer aussi au joueur que les lettres qui ne correspondent pas au mot. Enfin, on va lui montrer les lettres qui ne correspondent pas au mot à trouver puisque sinon ça va être un petit peu compliqué pour lui de se souvenir de tous les essais qu'il a fait auparavant.
[00:35:36] Et là vous vous vous entendez la question, pourquoi c'est un mot de cinq lettres ? Qu'est-ce qu'il fait que N est dans le mot ou pas ? C'est une excellente question parce qu'aujourd'hui, euh game state ne prend absolument pas en compte le mot qu'on cherche à deviner. Ça c'est quelque chose qu'il va falloir qu'on qu'on corrige de suite. Sinon on va on va avoir un petit souci. Sinon le test on l'état n'a pas de sens. L'intention n'est pas claire du tout.
[00:35:57] Donc on va rajouter le mot à à deviner au game state. Donc là ici Panda.
[00:36:05] là il est pas content parce que il y a pas de constructeur qui prend pas de constructeur par défaut.
[00:36:10] On va compléter la classe Game state.
[00:36:13] Voilà, c'est beaucoup plus joli. ou pas.
[00:36:21] Et petit mot magique, si on met private devant, ça devient automatiquement un champ. Alors là c'est c'est bien mignon ce que je viens de faire mais c'est complètement destructif, on n'est pas du tout sur du refactoring, là j'ai tout pété potentiellement. Donc on va on va rejouer les tests pour lancer ça, mais du coup ouais si quand on là malheureusement on n'avait pas le choix. Sinon n'aurait pas pu aller beaucoup plus loin, donc les tests vont y aura des problèmes de compilation.
[00:36:40] Un argument pour le mot a été fourni. Vous voyez qu'il y a plusieurs endroits où je fais un new game state sans lui passer de mots. Donc forcément il est pas content. La bonne nouvelle c'est que ça va se corriger assez vite parce que le mot je l'ai déjà sous la main. on va prendre ça au passage. On aura déjà ça. On va se laisser guider par la pour le coup le fait d'avoir une compilation, c'est quand même assez pratique, ça permet de tester tous les les problèmes d'un coup.
[00:37:07] C'est chaud.
[00:37:09] Ouais, alors là on va on va vous la faire courte. Le problème c'est quoi ? C'est que le init, il est censé émettre un jeu un game set initial. mais dans le game dans le test unitaire du composant, on s'isole de l'extérieur, dont le service aussi. Et le service aussi, vous voyez que pour l'instant, il est pas fidèle à l'implémentation qu'on a faite. En fait ce qu'il faudrait qu'on fasse c'est qu'on n'émette si je ne m'abuse un new game state initial. Sinon sinon ce n'a plus cohérent avec ce qu'on a fait, c'est pour ça qu'il y a un échec. En vrai il aurait fallu qu'on passe beaucoup plus de temps à comprendre, là on va pas le faire parce qu'on sait où est le problème. Dans la vraie vie, ça prend du temps. Mais c'est pas grave, il faut accepter de prendre du temps.
[00:37:47] la première fois la première fois qu'on a codé l'application, on a pris beaucoup de temps.
[00:37:51] Exactement sur des problèmes comme ça. Et donc là cette fois on a un test en échec et si tout se passe bien, on c'est le bon et là miracle des miracles, c'est bien le bon. Alors je vais remonter un petit peu parce que là ça fait un peu penser magique mais.
[00:38:05] État du jeu pour tentative réussie. Et donc là le test est en échec et du coup, j'arrête de coder, je passe la main. à.
[00:38:12] la caméra ici.
[00:38:14] Agathe, il faut que j'arrête il faut que j'arrête de regarder mon laptop, je me trompe de caméra, c'est ma faute.
[00:38:18] OK, donc là le but du jeu, c'est que je répare le test. Euh
[00:38:23] Je suis passé un peu parce que j'étais tout fermé, je crois.
[00:38:24] Ouais, c'est ça.
[00:38:25] Il faut que tu ouvre, il faut repartir en plein écran aussi.
[00:38:28] Ouais, je vais faire ça. OK. Euh donc je vais aller dans Game state directement et en fait, je vais retoucher la méthode compute next state qui ne fonctionnait que pour des des essais ratés.
[00:38:41] Hop. Donc ce qu'on va faire là c'est que on va vérifier que ce explique.
[00:38:46] Oui non mais en fait je ce que je suis en train de me dire je vais te laisser te concentrer puis je vais expliquer ce que tu essayer de faire. Et donc là dans l'idée en fait le compute next state là pour l'instant il était assez aveugle, il nous dit bah de toute façon vous avez forcément raté. C'est ça ce qu'il dit en fait. mais en fait c'est pas vrai, il faut quand même vérifier que le mot donc ça y est le mot on y a enfin accès puisqu'on a introduit un constructeur. Le mot à deviner, on va regarder ses lettres tout simplement. On va regarder chacune de ces lettres et dire bah tiens, est-ce que la tentative que je suis en train de t'envoyer là, est-ce qu'elle fait partie de ces lettres ou pas ?
[00:39:14] Et donc le split sur un sur un string vide, ça permet de récupérer c'est un petit raccourci qui permet de récupérer toutes les toutes les lettres dans un tableau. Et en fait on pourra demander index of, quel est l'index du premier premier élément qui match dans le tableau de. Et donc du coup si on trouve effectivement un index, ça commencera à zéro ou plus, on sera supérieur ou égal à zéro, donc ça veut dire que le caractère qu'on cherche. est effectivement dans le mot. Si on n'entre pas dans le, c'est que on est dans le cas où c'est une tentative infructueuse et ça c'est ce qu'on a codé en dessous.
[00:39:44] Exactement.
[00:39:47] Donc là on peut se contenter de rien changer en fait. Si vous avez trouvé, si vous avez trouvé c'est cool. Mais la question c'est est-ce que ça suffit ? Est-ce que ça suffit au test ? Bon, on va regarder. Hop, les tests tournent en continu.
[00:40:01] Je suis en parle.
[00:40:02] Oui, c'est vrai, je suis hors cadre. Mais alors du coup, ça ne suffit pas. Et pourquoi ? Parce qu'en fait, il se trouve que si on regarde le test, si on revient sur le test en question.
[00:40:16] Vous voyez qu'on appelle displayable charge, c'est une méthode sur un next state qui va afficher le mot dans son état actuel à savoir est-ce que les enfin les lettres à deviner et les lettres ont déjà été révélées. Et si on regarde l'implémentation de displayable charge maintenant. Donc là on peut se contenter de rien changer en fait. Si vous avez trouvé, si vous avez trouvé, c'est cool. Mais la question c'est est-ce que ça suffit ? Est-ce que ça suffit au test ? On va regarder. Hop, si on... Les tests tournent en continu.
[00:40:00] Vous en parlez en boucle.
[00:40:01] Oui, c'est vrai, je suis hors cadre, mais alors du coup ça ne suffit pas. Et pour pourquoi ? Parce qu'en fait, euh, il se trouve que euh, si on regarde le test, si on revient sur le test en question,
[00:40:15] Vous voyez qu'on appelle displayable chars, c'est une méthode sur un next state qui va afficher euh le mot dans son état actuel, à savoir euh est-ce que les, enfin les lettres à deviner et les lettres ont déjà été révélées. Et si on regarde l'implémentation de displayable chars maintenant,
[00:40:32] Là vous voyez qu'on fait systématiquement un tableau de 5 éléments avec le point d'interrogation. Enfin, c'est pas, c'est pas du tout la bonne implémentation.
[00:40:42] Et euh, et donc c'est là où je me rends compte que j'ai grillé une étape. en ajoutant ça dans le test directement, mais c'est pas grave. Du coup, on va le faire ensemble. Donc là l'idée c'est quoi ? Bah en fait, c'est non seulement...
[00:40:50] on va commencer par des displayable chars, c'est d'avoir le statut des lettres en fait, est-ce que chacune des lettres de mot a été révélée ou pas ? Bon, on va commencer par la fin, du coup, on va commencer par des displayable chars.
[00:41:01] Et ce qu'on va faire, du coup, on va prendre euh la this.word.value, donc ça c'est notre mot.
[00:41:08] Donc ça c'est le la la la chaîne de caractère associée au mot à deviner. On va encore une fois faire un split pour récupérer les caractères un par un.
[00:41:18] Donc sur voilà, donc là on va récupérer un tableau de caractères et ensuite on va transformer caractère par caractère via la la fonction map. Il faut faire point map.
[00:41:25] Ouais. Ça marche. Je j'ai du mal avec le point.
[00:41:29] Oui, c'est la joie du clavier QWERTY. Et donc là qu'est-ce qu'on va faire ? On va prendre une fonction qui prend euh caractère par caractère. Donc on va voir la lettre.
[00:41:40] Voilà, la lettre. Et du coup là on va écrire du code qui n'existe pas encore, donc il faut faire le égal flèche pour le pour la callback. Et on va dire, euh this.word, ah oui tu peux faire comme ça aussi, ça marche aussi. C'est plus lisible, c'est encore mieux. This.word state. Donc ça c'est quelque chose qui n'existe pas encore, mais qu'on va qu'on va expliquer tout de suite après. Word state, c'est quelque chose qui va associer une lettre à si oui ou non elle a été trouvée. Et du coup, word state avec si on ouvre les crochets de letter, donc en gros, il va nous il va nous donner le statut de la lettre en question. Et donc si c'est true, donc si on fait if là-dessus si on met un if autour de ça.
[00:42:17] Euh donc si c'est true, ça veut dire que la lettre a été trouvée, dans ce cas-là, on l'affiche tel quel.
[00:42:25] C'est ce premier if. Alors on peut, on peut, on peut, on peut, on peut le comparer à true.
[00:42:28] Ah mais non, c'est ça.
[00:42:30] On peut le mettre directement comme ça. Donc dans ce cas-là, on peut faire return letter, parce que si la lettre a déjà été trouvée, on peut l'afficher, on a le droit. Si en revanche euh, donc dans le cas contraire, donc en dehors du if, euh, si c'est false, ça veut dire que la lettre n'a pas été trouvée, c'est là qu'on va afficher le fameux placeholder, le fameux point d'interrogation.
[00:42:53] Et donc là, il faut afficher, il faut faire return placeholder. Et du coup, et ça, et du coup, en fait, la ligne 15, il faut la mettre un petit point point virgule, il faut mettre un petit point virgule devant. Et supprimer la ligne 21. La ligne 21, du coup n'a plus aucune utilité. On va faire un return de ça.
[00:43:06] D'accord, c'est bon.
[00:43:07] Faut faire un return de ça. Voilà, return du tableau transformé. La ligne 21 disparaît parce que c'était juste une implémentation par défaut histoire qu'il y ait quelque chose. Et enfin, bah il reste le fameux work state à définir et à initialiser correctement et à mettre à jour. Donc du coup, bah c'est ce qu'on va faire, on peut faire alt entrée pour un introduire ce nouveau champ.
[00:43:27] Voilà. Donc en fait, ça va être, on peut, on peut émettre, omettre le type pour l'instant, ça va être un simple objet JavaScript hein. Et ce qu'on peut faire avec le dans le constructeur, c'est l'initialiser. En fait, au début, par définition, quand on commence le jeu, on a trouvé aucune lettre. Du coup, on peut itérer sur chacune des lettres. Donc de la même de this.word.value.split.
[00:43:48] On va copier.
[00:43:49] Voilà.
[00:43:53] Et donc pour chacune de ces lettres, euh, on va faire une simple boucle fort dessus. On va faire for letter of ce truc là.
[00:44:00] Ouais.
[00:44:03] Et donc ça, ça va nous donner en fait euh lettre par lettre, et on va initialiser ensuite le statut de chacun.
[00:44:07] Attends.
[00:44:08] For letter, for let letter of this.
[00:44:12] Ouais.
[00:44:13] Enfin const même ça va marcher. For const, yes, const. Les parenthèses autour du const.
[00:44:19] Voilà. Il faut des parenthèses autour de ça.
[00:44:22] Voilà, et le parenthèse ça remonte. Et tu peux mettre une parenthèse à la fin aussi.
[00:44:27] Vous voyez la joie du pairing c'est que il y a du revue de code immédiate. C'est ce qu'on vous disait.
[00:44:31] Ouais.
[00:44:32] Et du coup, dans le dans la dans le for, on va modifier un objet qui n'existe pas encore, à savoir le word state.
[00:44:39] Euh et donc word state.
[00:44:42] Crochet crochet de la lettre.
[00:44:44] Ah, c'est ça.
[00:44:46] Alors ça va être, on peut faire comme ça, on peut faire comme ça effectivement. Et donc de alors de crochets, letter, et ce sera false au début. forcément parce que chaque lettre, aucune lettre n'a été devinée à ce stade. Et donc euh et donc on va tout initialiser à false. Par contre, pour pas que ça plante cette boucle for, il va falloir juste avant la boucle for, il va falloir qu'on fasse quelque chose, il va falloir qu'on initialise this.word state à un objet vide, sinon forcément, ça va planter. Donc ça c'est la première partie du boulot, on a défini le champ et initialisé.
[00:45:15] Euh juste juste une acolade, ça suffira. On peut faire un new object ou quelque chose c'est un peu overkill. Et donc la dernière partie qui est bah c'est simplement de mettre à jour ce word state quand en cas de tentative infructueuse, hein, parce que par défaut tout est false. Et donc si on descend un peu plus bas, si on revient sur le compute next state, ce qu'il va falloir qu'on fasse c'est si on trouve bien le mot, donc les dans le if juste avant le return this, il va falloir qu'on ajoute euh donc on on passe à true en fait, this.word state de la liste. Donc la lettre, le statut de la lettre. qu'on vient d'essayer. Et on va donc la passer.
[00:45:54] Les joies du clavier QWERTY comme toujours.
[00:45:55] Ouais. Oh, c'est c'est dur.
[00:45:58] Et ça va passer à true. Et là, si tout se passe bien, si on revient sur les tests.
[00:46:05] On devrait y arriver.
[00:46:09] Si on revient sur les tests, là on devrait avoir le test qui passe. OK, donc là le test passe, ça y est, parce qu'on a effectivement une implémentation correcte de l'affichage du mot et aussi de l'état, donc notre test qui se focalisait sur le cas où ça marche bien.
[00:46:23] Donc le ben du coup là Agathe va introduire un nouveau test, à savoir par exemple le fait de pas prendre en compte une tentative infructueuse si on a déjà tenté avant. Si par exemple vous avez le mot panda, vous tentez la lettre X, si vous l'utilisez deux fois, en fait on va ignorer la deuxième fois, ce qui me semble est dans les règles du pendu. Donc pour cette fois,
[00:46:43] ça va ressembler pas mal au test précédent, c'est juste que euh on va faire deux compute next state, on va faire et deux fois pour la même lettre qui n'existe pas dans le mot. Pour l'instant, on va assez vite hein, on va on va pas faire dans la dentelle entre guillemets.
[00:46:57] Exactement.
[00:46:59] On ignore duplicate failed attempts par exemple. Parce qu'on a pas il me semble dans les règles du pendu.
[00:47:09] Alors du coup, je vois la question au passage, quelle règle se donner quant au test, s'il peut correspondre à une intention d'architecture logicielle. Et pas forcément un comportement attendu par l'utilisateur. Alors, c'est une question qui mériterait une discussion beaucoup plus longue, à mon avis. À mon avis, je laisse je laisse Agathe continuer sur son test pour pas qu'elle se déconcentre.
[00:47:29] Mais pour moi, l'architecture logicielle, elle se traduit par l'implémentation en fait. Pas par euh Enfin, ça peut c'est discutable, c'est discutable, mais pour pour moi vraiment, on essaie, j'essaie au maximum quand je suis sur une user story.
[00:47:42] Une user story, hein, c'est une anecdote fictive de l'utilisateur qui raconte une des facettes de votre produit, c'est ça que ça veut dire user story à la base. Pour moi, c'est centré sur l'utilisateur avant tout, et donc c'est des les tests sont plutôt orientés sur les actions utilisateurs. Et utilisateur, c'est pas forcément un humain hein, ça peut être ça peut être un client d'API. Ça peut être un autre système quand j'utilise l'utilisateur, c'est au sens large. Pour le coup pour l'architecture, ouais, j'ai pas forcément une super réponse sur le sujet sur l'architecture logicielle. Pour moi, c'est un plus de l'ordre avant tout de l'implémentation et éventuellement, ça c'est des contrôles automatisés que vous pouvez ajouter ensuite. Alors, il y a des outils type JQ assistant ou ce genre de choses qui permettent de renforcer par exemple des choses que un DAO va pas s'injecter un contrôleur ou un service ou ce genre de règles architecturales, mais ça pour moi c'est pas ça rentre pas dans le. dans le flot de test courant, c'est des outils qu'on peut ajouter systématiquement ensuite. Donc je sais pas si ça répond à la question ou si ça répond à côté de la plaque. Mais voilà en tout cas, n'hésitez à poser la question, à la reformuler s'il y a des aspects que j'ai pas compris. Et donc là qu'est-ce qu'on veut faire ? Bah du coup, on fait deux fois compute next state de suite. Alors idéalement, on le chaîne, même si là on fait tout par mutabilité pour pour aller un petit peu plus vite aujourd'hui, mais. Mais on peut aussi le chaîner parce qu'en vrai la la vraie implémentation devrait être également immutable et il ne faut pas dire c'est pas grave, c'est pas grave.
[00:49:02] Juste le petit point qui manque.
[00:49:04] Non, attends. Laisse-moi faire, je vais le mettre.
[00:49:08] Le ping-pong va aussi vite dans la vraie vie ? Alors euh non.
[00:49:11] Pas du tout.
[00:49:12] C'est pour ça qu'on vous ce que je disais au début quand on a commencé le live coding, c'est une version idéalisée parce que ça peut prendre du temps. En revanche, en revanche, la mécanique de ping-pong, elle est simple. Je dire, même si vous êtes sur un problème compliqué à résoudre, la mécanique est simple. C'est quand même bien de s'y tenir, c'est quand même bien d'avoir la patience et la discipline de le faire.
[00:49:28] Quand on commence le TDD ou le pair programming, c'est comme ça en fait, on attaque quelque chose de nouveau, donc voilà, comme vous pouvez le voir, moi, c'est encore en cours d'acquisition. Comme vous pouvez le voir, moi, c'est encore en cours d'acquisition. Et euh, il faut accepter que acquérir une nouvelle compétence, c'est long.
[00:49:41] Yes. Et du coup, je reprends la parole violemment parce que je sais que Agathe doit se concentrer sur son test.
[00:49:47] Son test en échec.
[00:49:49] Et donc là, vous verrez qu'en fait, dans le cas présent, on aura que euh,
[00:49:54] C'est l'horreur.
[00:49:55] Alors, c'est ça va, ça va pas être, ouais, il faut enlever le point size.
[00:49:58] Oui, oui, oui.
[00:49:59] Donc tu auras que, il y aura que un seul N parce que c'est un set, donc ça c'est c'est fourni de base, c'est cool. Et les left attempts, on aura perdu qu'une parce qu'en fait le N, on l'a déjà tenté avant. Donc oui non, alors pour revenir à la question, le ping-pong va-t-il aussi vite ? Non, c'est idéalisé, là on sait déjà plus ou moins ce qu'on fait, ce qui est rare dans la vraie vie hein, on sera en général, on est plus dans l'inconnu, ce qui justifie d'autant plus à mon sens le test driven development qui force vraiment à réfléchir étape par étape.
[00:50:20] Et pour vous donner une petite anecdote, euh un des premiers projets que j'ai fait à Pivotal Labs, euh les deux développeurs Pivotal Labs, donc moi et un collègue, on a on avait une stack Angular, on connaissait pas Angular, on connaissait Angular JS mais on connaissait pas Angular. Je pense que les on a mis euh le je crois qu'on a mis 2 jours la première fois à faire passer le test ou quelque chose comme ça. Et ça paraît énorme hein, et dans des environnements un petit peu malsains, malheureusement, passer 2 jours à essayer de à essayer de réparer un test, c'est pas quelque chose de mal de bien vu. Et n'empêche que, pendant 2 semaines, on a galéré, galéré, galéré, mais on s'est tenu à cette discipline de ping-pong, de TDD et de pairing. Et on a quand même chipé une première version en production en 3 mois. Et on connaissait rien en Angular. Donc vraiment euh faut pas avoir peur.
[00:51:00] OK, donc c'est failed attempt. Donc j'ai fait une petite coquille, c'est c'est un check. Donc forcément.
[00:51:06] Et je mets. Le B, le P c'est toujours pas bon. Le B par exemple. Pourquoi c'est bon ? C'est mon X.
[00:51:11] Voilà.
[00:51:13] Et donc, on aura aucun mot, aucun aucun affichage de de caractère parce que on a pas deviné le N.
[00:51:19] Le N, non pas deviné le N. Ah, oui, tout à fait. Donc ça, ça disparaît et euh, ça disparaît ou ça se corrige, mais c'est pareil.
[00:51:24] Ça se corrige. C'est pas grave. Non c'est bon, c'est bon. Laisse-le comme ça.
[00:51:26] D'accord.
[00:51:27] Très bien. Ça suffit.
[00:51:29] Et en fait on va diminuer le nombre d'attempt restant par par un et non pas par deux.
[00:51:35] Voilà.
[00:51:35] Parce que on va pas compter deux fois la même lettre, ce sera un peu injuste. OK. Alors, j'ai fini et si on vérifie le test.
[00:51:42] On va voir si le test passe ou pas, si le test échoue évidemment. Hop, super, il échoue, donc c'est à moi, donc je vais parler un peu moins. Sur la question du clavier, oui, sur Pivotal à Pivotal Labs, on avait chacun son clavier, certains ont QWERTY, certains ont AZERTY.
[00:51:54] La plupart du temps avec avec Florent, on on fait du pair programming à distance, donc chacun a chacun son matériel, c'est beaucoup plus simple. Là, c'est c'est exceptionnel parce que la dicté c'est rendait la chose un peu plus compliquée à gérer.
[00:52:10] Euh, comment on gère les habitudes de raccourcis, par exemple, dans des équipes variées ?
[00:52:16] Euh, bah, ça dépend de celui qui.
[00:52:20] qui code en fait. Celui qui code peut garder le format de ses habitudes de raccourcis. Moi, j'ai appris énormément de raccourcis parce que Florent, à chaque fois que je fais quelque chose, il me donne un raccourci directement. Mais euh, voilà, le but, c'est toujours de de monter en compétence chacun, d'aider l'autre à à s'améliorer. Donc euh, voilà, pourquoi pas apprendre à l'autre des raccourcis euh ou des choses.
[00:52:50] qu'il a pas l'habitude d'utiliser, voilà, des nouvelles des choses comme ça. Ça permettra de garder de gagner du temps.
[00:52:57] Voilà, là c'est vraiment particulier. Je ne suis pas du tout habitué au clavier QWERTY, je galère encore.
[00:53:03] Et avec la joie du stress de la présentation, j'ai un petit trou de mémoire sur le prochain test, mais en fait, dans la vraie vie, c'est une discussion. Quel est le prochain test, quelle est la prochaine étape, c'est une discussion dans votre paire. Donc ça, ça va justement assembler, sauf qu'on avait décidé à l'avance mais j'ai oublié.
[00:53:14] C'est surtout que tu as inversé tout ce que je devais faire.
[00:53:16] C'est ça. C'est ça, j'ai un peu décalé.
[00:53:18] Donc en fait, là on a on a dit qu'on allait ignorer les duplicata des tentatives ratées. Donc là, on va faire la même chose pour les tentatives réussies.
[00:53:26] Yes, bon, ça change.
[00:53:28] Une fois qu'on a deviné une lettre, même si euh le le joueur indique à nouveau la même lettre, et ben, ça va rien faire de particulier en fait.
[00:53:36] Alors, voyons si c'est le cas, euh s'il y a des choses à faire ou pas. Du coup, là pour l'instant, vous voyez qu'on fait pas beaucoup de refactoring. Alors non pas que c'est non pas que le code est parfait en l'état, c'est juste que on est on court un peu derrière le temps.
[00:53:50] Donc, qu'est-ce que je fais cette fois ? Euh bah j'ai deux fois P.
[00:53:55] par exemple.
[00:53:59] J'ai un set vide d'échec.
[00:54:03] Euh, et j'ai left attempts, bah j'en ai toujours, je dois toujours être au max puisque j'ai déjà trouvé. Et puis je vais quand même réintroduire mon ami displayable chars parce que je l'ai bien.
[00:54:14] Euh. Hop. Et cette fois, j'aurais trouvé qu'un seul P, donc ça devrait voilà, ça devrait rien changer. Suspense, est-ce que le test va passer en échec et est-ce que je vais pouvoir passer la main à Agathe ?
[00:54:26] Alors le test passe direct, effectivement, on a rien d'autre à faire sur l'implémentation. Donc les puristes pourraient vous dire bah supprimer le test parce qu'il a vous a rien apporté. On peut décider de le garder parce que finalement, c'est de la non régression aussi, ça peut être utile. Donc là, franchement, c'est à vous de voir aussi, on a pas de on a pas de vérité absolue. Je vais du coup, moi, je vais le garder pour l'instant et on va passer à la suite. S'il nous reste pas beaucoup de temps. Donc ouais, on va peut-être déborder de 5-10 minutes, j'espère que les ordis. ont pas trop être. être avec nous. Alors, on en est à ignorer les les tentatives du joueur.
[00:54:58] En fait, c'est la dernière étape. Quand le jeu est terminé, en fait, on a plus prendre en compte, on a plus prendre en compte les.
[00:55:03] les lettres qui va qui vont parvenir. Yes.
[00:55:11] Euh, one game is one, tiens, je vais faire plutôt, je sais pas, je le sens bien.
[00:55:15] Ou non, game is lost, parce que ce sera plus facile. Pardon. Je vais plutôt la faire comme ça pour l'instant.
[00:55:22] Oui, parce qu'en fait, une fois que le jeu est fini, il y a vous pouvez deviner tant que vous voulez, euh ça n'a plus ça ça va pas changer les stats en fait. Donc là encore une fois, on va faire du copier-coller moche, on va pas prendre de refactoring, mettre des des choses en début for each, ça c'est quelque chose qu'on va pas faire. Donc typiquement, j'ai perdu, là je vais tricher un peu. Je vais changer euh voilà, on va faire à deux.
[00:55:45] Donc si j'essaie B, si j'essaie O, bah normalement la joie est fini. Et en revanche, euh si j'essaie un, je sais pas, un petit euh voilà, bov. J'en sais rien.
[00:55:56] Pour moi, c'est toujours en blanc.
[00:55:58] Ouais. Donc c'est bon, c'est bien des failed attempts.
[00:56:00] Failed attempts, c'est le nombre d'attempts.
[00:56:02] Ouais, j'ai fait exprès, j'ai triché.
[00:56:04] Donc là, dans les failed attempts, je devrais avoir euh que B et V, le haut ne devrait pas être pris en compte parce qu'en fait, le jeu a été fini, vu que j'ai forcé à deux tentatives max ici.
[00:56:13] Oui, c'est le B et le O.
[00:56:15] Ah oui, le B et le O, pardon. Mais vous voyez, revue de code instantanée, ça c'est un bug que j'aurais passé des minutes voire des heures à chercher ensuite. Et donc par contre, j'aurais rien trouvé parce que je suis pas un très bon joueur de de Penda. Et donc là, suspense, est-ce que le test passe, est-ce que le test ne passe pas ?
[00:56:33] Le test, a priori, ne passe pas parce que vous voyez qu'il a pris le V en compte alors qu'il devrait pas. Du coup, je laisse la main à Agathe. Et euh, j'ai beaucoup trop parlé alors que j'avais le clavier.
[00:56:42] Euh, c'est pas grave. Mais euh, ce que je vais faire, en fait, c'est que je vais compléter la méthode isLost, euh, cette méthode.
[00:56:50] Yes. Je peux parler à ta place si tu veux, même si tu as déjà beaucoup parlé, mais.
[00:56:54] Ah non.
[00:56:56] Comme ça ça te permet de te focaliser.
[00:56:58] Elle va s'activer en fait quand on a plus de tentatives restantes.
[00:57:03] Yes. Du coup, l'idée c'est effectivement de bah si le jeu est fini, donc là on va recommencer par l'aspect perdu, hein.
[00:57:09] Ce sera un petit peu, un petit peu plus simple à implémenter. Bah c'est perdu quand effectivement, comme l'a dit Agathe, quand il y a plus d'essais, donc sans shift.
[00:57:17] Ouais, ouais. C'est ça.
[00:57:19] Si j'ai zéro attempts, bah c'est qu'on a fini. Donc c'est aussi simple que ça.
[00:57:25] Donc ça c'est le la définition du. Il faudra un petit avec un petit return et puis supprimer le return en dessous. Donc ça ça suffit à dire que le jeu est perdu. Maintenant, il faut il faut que le compute le next state prenne ça en compte. Si le jeu est perdu, bah je je calcule rien du tout, je m'arrête là. Donc je fais un si le jeu est perdu, je fais un return this tout simplement, je ne calcule rien d'autre.
[00:57:41] Donc ça veut dire que la première chose à vérifier, c'est si le jeu a été été fini ou pas.
[00:57:47] enfin si le jeu était perdu quoi.
[00:57:49] Exactement. This is lost, voilà. Je return this.
[00:58:01] OK, c'est bon.
[00:58:02] Alors là est-ce que le test passe suspense insoutenable.
[00:58:06] Et de la même façon, du coup, s'il passe, on va voir, bah l'idée, ça va être de faire de la même façon, euh si même si le jeu est gagné en fait. Si le jeu est gagné, ça ne fera rien, ça ne changera rien.
[00:58:16] Et donc là, il faut passer, ça ressemblait au test précédent. Et vu qu'on a pas beaucoup de temps, on va encore copier-coller comme des gorés. Ne faites ne reproduisez pas ça chez vous sans l'assistance d'un professionnel, bien sûr.
[00:58:26] Euh. On va déborder, on va déborder de 5 minutes, je pense que j'espère que c'est tolérable. Sinon, bah, sinon on sera.
[00:58:33] J'ai encore un attempt.
[00:58:35] Et donc là maintenant, cette fois, c'est un peu l'inverse, c'est quand le jeu est gagné.
[00:58:39] OK. Euh, on va mettre Bob, c'est trop rapide, c'est le nom du panda.
[00:58:46] Euh, ça m'a pas d'ailleurs.
[00:58:47] Exactement.
[00:58:49] Hop. Donc j'enlève ça.
[00:58:51] Le fait de faire BO cette fois, ça va permettre de gagner le jeu parce qu'il y a que deux lettres distinctes dans Bob.
[00:58:55] C'est ça.
[00:58:57] Et on va envoyer V qui est en fait une valeur infructueuse, mais vu qu'on a déjà gagné le jeu, en fait, il y aura dans l'effet de te, ce sera vide.
[00:59:04] Ouais.
[00:59:05] Euh, left attempts, bah il va m'en rester en fait, peu importe en vrai, dans ce test. Mais on peut juste dire que c'est max attempts, parce que on a pas grillé aucune dans dans l'absolu. Ah oui, pardon. this.next.max attempts. Ah oui, pardon.
[00:59:15] Ah, oui, pardon.
[00:59:16] Il se trouve que ça va marcher parce qu'on a en fait c'est plus une constante qu'autre chose, donc c'est un refacto qu'on pourrait faire et ne pas l'attacher à un attribut de de l'objet next state.
[00:59:25] Max attempt. OK, c'est ça.
[00:59:28] Et du coup le mot qu'on affiche, ça va être effectivement BOB parce qu'on a trouvé toutes les lettres, et le fait d'avoir essayé de deviner V après coup, ça ne va avoir aucune incidence.
[00:59:35] Dans un monde idéal, on va voir si le test passe ou pas. Donc le reste s'en va.
[00:59:40] Hop. Et donc si on regarde les tests, est-ce qu'il passe, est-ce qu'il ne passe pas ?
[00:59:47] Normalement, ça devrait être plus ou moins le dernier test qu'on va faire.
[00:59:50] Oh mon Dieu, oh mon Dieu, ça ne passe pas, vite vite vite, corrigeons-le. Et donc j'arrête de parler, promis.
[00:59:58] Euh l'objectif là c'est de voilà, de rajouter euh un autre condition euh si le jeu est remporté. On s'arrête là. Et de compléter la méthode is one.
[01:00:11] Alors, voilà. Du coup, voilà. En fait, on va vérifier que dans le word state, toutes les lettres sont passées à à true. Je perds ma souris. Pardon.
[01:00:25] Parce que rappelez-vous, dans le word state, la lettre passe, euh oui, chaque lettre trouvée passe à true. Si l'ensemble est à true, ça veut dire que le mot a été trouvé et que le jeu peut s'arrêter puisqu'il a été remporté par un joueur. Et il faut ce qu'on va faire ici, on va faire quelque chose du genre.
[01:00:50] En fait, je fais une réduction, hein, je fais un 'et' sur tout, et si j'ai un false au milieu, au début ou à la fin, si je fais false et quelque chose, c'est forcément false. Donc le isOne, il ne sera vrai que si tout est vrai. Donc c'est une façon savante de faire un forEach et de vérifier que tout est vrai. Mais normalement ça, si tout se passe bien, ça devrait suffire.
[01:01:11] Youhou, ça passe, super. Donc là, en théorie, et là ça va être un peu le suspense, on va relancer l'appli et on va voir si le jeu se comporte un peu mieux que tout à l'heure, tout à l'heure on avait beau taper n'importe quoi, il se passait absolument rien. pour ça, je vais toujours faire mon fake backend, je pourrais aussi lancer le vrai, peu importe, c'est juste un petit peu plus rapide comme ça. On va relancer, et normalement à ce stade, on pourrait avoir un test end-to-end qui valide vraiment que le fonctionne déroulement du jeu.
[01:01:33] C'est ce qu'on ferait dans la vraie vie si on avait un peu plus de temps, on aurait un autre test end-to-end qui qui nous dirait bah tiens quand j'ai quand je devine un mot, le mot s'affiche et je peux plus jouer après, ou quand je je devine mal un mot, je perds le jeu, etcetera. Donc ça, ça pourrait faire deux tests end-to-end supplémentaires qui euh permettraient de vérifier qu'effectivement, qu'effectivement on a gagné ou perdu. Et donc là, on va regarder suspense insoutenable, donc le mot à deviner, là c'est mon fake server avec le mot hardcodé, c'est panda. Donc si je fais R, bah il est liste bien la lettre R, donc ça c'est plutôt cool. J'ai bien un un essai en moins, euh si je fais G, c'est pas dedans non plus.
[01:02:08] Si je fais euh alors A, ah bah si c'est dedans.
[01:02:11] Si je fais I, c'est pas dedans, si je fais K, c'est pas dedans, bon, vous avez compris le principe. Donc là, il y a une magnifique animation, je pense qu'on va on va être multi-milliardaire avant ce jeu. Et donc voilà, et puis si j'essaie encore d'autres choses. Alors R, vous voyez que j'ai déjà essayé, hein. Je peux le ré-essayer, ça change rien à l'état, donc ça c'est bien ce que les tests nous ont permis de prouver. W, ah bah zut, et puis là, je vais puis là je vais sans doute perdre. Donc c'est parti, voilà, le panda triste et puis c'est c'est test. Et juste vérifier qu'on peut gagner quand même.
[01:02:36] Euh donc j'ai P, j'ai A, j'ai N, j'ai D. Yeah, on a gagné. Bon, voilà. Donc euh, ça y est, on a fini à peu près. Bon en vrai, vous verrez que l'implémentation alors si vous allez, c'est vrai que. On pourra peut-être l'envoyer sur le chat aussi, hein, mais si vous allez sur ce repository là, vous aurez une implémentation un petit peu moins à l'arrache entre guillemets. Pour vous occuper pendant les longues soirées de confinement. Voilà. Donc il faut juste, alors soit vous faites un fake server, quoique vous avez pas besoin de compte, soit vous passez sur Lexicala qui est un service d'API pour avoir des mots un petit peu plus random, donc un petit peu plus compliqué potentiellement à deviner. Et toutes les instructions sont là, vous pourrez voir l'implémentation aussi si le code vous intéresse. Avec un petit peu plus de tests, un petit peu plus d'immuabilité, même si c'est pas aussi beaucoup de refacture.
[01:03:14] C'est ça.
[01:03:16] Exactement, là on a fait vraiment la version brute de fonderie sans refactoring, ce qui est pas forcément recommandé en dans un.
[01:03:23] Là, si on avait eu du temps, on aurait fait un petit peu plus de refactoring. J'ai quand même fait un refactoring que j'ai pas forcément commenté tout à l'heure. Le left the times, au début, c'était un champ, et là en fait, j'en ai fait une propriété qui est qui se base simplement sur le nombre d'essaie max moins le nombre des d'échecs le nombre d'échecs. Donc ça ça suffit en fait à à arriver les problèmes. C'est comme ça que j'ai fait passer un test, voilà. Et l'objectif de ce qu'on voulait montrer ce soir, c'est que il faut pas avoir peur d'essayer des nouvelles façons de travailler.
[01:03:49] Comme le TDD ou le pair programming, ou même les deux. Mais il faut se mettre dans de bonnes conditions pour apprendre. C'est pour ça que je déconseille par exemple de commencer du TDD sur du code Legacy, je l'ai fait, c'est pas très, c'est assez dur. Quand on n'est pas accompagné, c'est plutôt compliqué. En solo, c'est clairement dur. Mais euh voilà, le but du jeu c'est euh c'est enfin en tout cas, nous, on pense que c'est bien de aussi s'approprier les méthodes qu'on utilise. Et euh parfois les les changer, les modifier un petit peu pour que ça ça corresponde à notre façon de travailler, à ce qu'on aime bien faire et que le binôme fonctionne bien. Et qu'on arrive à produire des des choses de meilleure qualité avec surtout en fait, le plus important pour moi, le TDD et le pair programming, c'est cette espèce de d'adrénaline à chaque fois qu'un test passe au vert qu'on peut en plus partager avec quelqu'un. Et euh, voilà, moi je trouve que c'est euh c'est une façon super de travailler parce que c'est extrêmement motivant et ça nous permet de produire du meilleur code. Donc n'hésitez pas si vous avez euh si vous voulez des questions, si vous voulez des infos sur des bonnes pratiques à suivre.
[01:04:56] Euh, voilà, on est disponible là tout de suite sur Twitter, voilà, il y a plusieurs façons de nous contacter, on peut vous les donner. Mais euh voilà, le but du jeu, c'est de vous montrer que c'est à la portée de tout le monde. Même des débutants et que même si vous avez rien compris à ce qu'on a fait. façon technique, euh, le but du jeu, c'est de vous montrer que vous mettez dans un échange et que quand je perds mes moyens, euh Florent est là pour m'aider, et quand il oublie euh là où on en est, et ben, je peux lui rappeler que euh on en est à tel tel.