mageekblog - Mot-clé - addcslashesLe blog personnel de Frédéric Hardy. Au menu, PHP, agilité, FreeBSD, cuisine et photographies.2021-12-02T08:20:54+01:00Frédéric Hardyurn:md5:26874ca5b8cd4cac8d08b0e68e64f63aDotclearTest unitaire, chaîne de caractères et caractère de contrôleurn:md5:fafbfa1473cd8c8fb4ebcf74f3136fc42010-09-08T10:30:00+02:002010-09-08T10:30:00+02:00mageekguyPHPaddcslashesAtoumtest unitaire<p>Hier, j'ai été confronté à un problème intéressant dans le cadre d'Atoum, mon framework de tests unitaires spécifique à PHP 5.3.</p>
<p>En effet, je suis en train de développer une barre de progression permettant de visualiser l'avancement des tests au cours de leur exécution en ligne de commande.</p>
<p>Évidement, le code correspondant est testé unitairement à l'aide d'Atoum, en suivant la méthode <a href="http://fr.wikipedia.org/wiki/Test_Driven_Development"><abbr title="Test-Driven Developement">TDD</abbr></a>.</p>
<p>Et tout a parfaitement fonctionné jusqu'à ce que je fasse des assertions sur des chaînes de caractères contenant des caractères de contrôle.</p> <p>J'avais en effet l'assertion suivante :</p>
<blockquote><pre><code><?php<br /><br />class progressBar extends atoum\test<br />{<br />...<br />$this->assert<br /> ->object($progressBar->update('F'))<br /> ->isIdenticalTo($progressBar)<br /> ->string((string) $progressBar)<br /> ->isEqualTo(str_repeat("\010", $length - 1) . 'F' . str_repeat('_', 59) . '][1/1]')<br />;<br />...<br />}<br /><br />?><br /></code></pre></blockquote>
<p>Rien de bien extraordinaire, et pourtant j'ai eu un problème.</p>
<p>En effet, comme de juste lorsque l'on fait du <a href="http://fr.wikipedia.org/wiki/Test_Driven_Development"><abbr title="Test-Driven Developement">TDD</abbr></a>, la première fois que j'ai exécuté mon test, il n'est pas passé.</p>
<p>Sauf que le rapport d'exécution ne ressemblait pas du tout à ce qu'il aurait dut être.</p>
<p>J'ai en effet obtenu cela :</p>
<blockquote><pre><code>Failure ! (2 tests, 20 assertions, 1 failure)<br />There is 1 failure:<br /> mageekguy\atoum\tests\units\reporters\cli\progressBar::testUpdate():<br /> mageekguy\atoum\asserters\string::isEqualTo() failed because string(67) 'laStringQueJeVeuxAvecDes\010' in<br />file /usr/home/fch/atoum/tests/units/reporters/cli/progressBar.php at line 101<br /></code></pre></blockquote>
<p>Au lieu de cela :</p>
<blockquote><pre><code>Failure ! (2 tests, 20 assertions, 1 failure)<br />There is 1 failure:<br /> mageekguy\atoum\tests\units\reporters\cli\progressBar::testUpdate():<br /> mageekguy\atoum\asserters\string::isEqualTo() failed because string(196) 'laStringTestee' is not equal to string(198) 'laStringQueJeVeuxAvecDes\010' in file /usr/home/fch/atoum/tests/units<br />/reporters/cli/progressBar.php at line 101<br /></code></pre></blockquote>
<p>En résumé, une grande partie du rapport est effacée...</p>
<p>Connaissant parfaitement, et pour cause, mon code, je n'ai pas eu de mal à trouver l'origine de mon problème.</p>
<p>En effet, ma barre de progression fait appel au caractère de contrôle <code>\010</code> <abbr title="Also Known As">aka</abbr> <code>Backspace</code> pour mettre à jour son affichage.</p>
<p>Et si son utilisation ne pose aucun problème lors de la vérification de l'assertion, elle en pose lorsqu'il est affiché dans le rapport d’exécution puisqu'il provoque son effacement.</p>
<p>Il me fallait donc faire en sorte d'annuler le comportement de <code>\010</code> dans mes chaînes de caractères à l'affichage pour supprimer ce comportement.</p>
<p>Et la solution est simple, puisque <a href="http://www.php.net">PHP</a> dispose d'une fonction <a href="http://fr.php.net/manual/fr/function.addcslashes.php"><code>addcslashes()</code></a> dont c'est justement le rôle :</p>
<blockquote><pre><code><?php<br /><br />class progressBar extends atoum\test<br />{<br />...<br />$this->assert<br /> ->object($progressBar->update('F'))<br /> ->isIdenticalTo($progressBar)<br /> ->string(addcslashes((string) $progressBar), "\010")<br /> ->isEqualTo(addcslashes(str_repeat("\010", $length - 1) . 'F' . str_repeat('_', 59) . '][1/1]'), "\010")<br />;<br />...<br />}<br /><br />?></code></pre></blockquote>
<p>J'obtiens ainsi un rapport d'exécution beaucoup plus lisible, puisque tout les caractère <code>\010</code> sont transformés par <a href="http://fr.php.net/manual/fr/function.addcslashes.php"><code>addcslashes()</code></a> en <code>\b</code>, ce qui n'a aucune influence lors de l'affichage.</p>
<p>Évidement, la solution, telle qu'elle est mise en œuvre ci-dessus est plus un <a href="http://fr.wikipedia.org/wiki/Hack#Le_rapport_.C3.A0_l.27informatique"><q>hack</q></a> qu'autre chose, mais je compte bien profiter du système d'assertion modulaire d'Atoum pour l'intégrer avec beaucoup plus d'élégance</p>http://blog.mageekbox.net/?post/2010/09/08/Test-unitaire%2C-cha%C3%AEne-de-caract%C3%A8res-et-caract%C3%A8re-de-contr%C3%B4le#comment-formhttp://blog.mageekbox.net/?feed/atom/comments/183