atoum / json-schema-extension

The atoum json-schema-extension allows you to validate JSON against schemas.
Other
8 stars 4 forks source link

L'asserter json ne fonctionne pas si le namespace des tests est changé #18

Open klnjmm opened 5 years ago

klnjmm commented 5 years ago

Bonjour,

Environnement : Mac OS X Version PHP : 7.1.28

Contexte :

j'ai voulu mettre en place des tests fonctionnels avec atoum en utilisant "atoum/atoum-bundle". J'ai donc la structure de répertoire suivante

/tests
    /functional
        ControllerTest.php
    /units

Mon fichier ControllerTest.php est une class abstraite. Comme indiqué dans la doc d'atoum, j'ai changé le namespace de mes tests :

class ControllerTest extends \atoum\AtoumBundle\Test\Controller\ControllerTest
{
    public function __construct(atoum\adapter $adapter = null, atoum\annotations\extractor $annotationExtractor = null, atoum\asserter\generator $asserterGenerator = null, atoum\test\assertion\manager $assertionManager = null, \closure $reflectionClassFactory = null)
    {
        parent::__construct($adapter, $annotationExtractor, $asserterGenerator, $assertionManager, $reflectionClassFactory);
        $this->setTestNamespace('Tests\\functional');
    }

Et j'ai copié donc le code de la doc de json-schema-extension

        $this
            ->given($string = '{"foo": "bar"}')
            ->then
            ->json($string)
        ;

Et voici le retour des tests :

mageekguy\atoum\jsonschema\asserters\json() failed: string(15) '{"foo": "bar"}' is not a valid JSON string

Explication :

L'appel à la fonction $this->setTestNamespace('Tests\\functional'); a un impact direct sur l'asserter json. La méthode setTestNamespace fait appel à $this->analyzer->isRegex($testNamespace) qui est comme suit :

public function isRegex($namespace)
    {
        return false !== @preg_match($namespace, null);
    }

Le namespace contenant des backslash, l'erreur silentieuse (vu qu'il y a @) est déclenchée :

Array
(
    [type] => 2
    [message] => preg_match(): Delimiter must not be alphanumeric or backslash
    [file] => /Users/jklein/Documents/dev/symfony-tdd/vendor/atoum/atoum/classes/tools/variable/analyzer.php
    [line] => 92
)

Et dans l'asserter Json, le test pour savoir si la chaine est bien du json est la suivante :

    protected static function isJson($value)
    {
        $decoded = json_decode($value);
        return (
            error_get_last() === null &&
            ($decoded !== null || strtolower(trim($value)) === 'null')
        );
    }

error_get_last() n'est pas null (car il contient l'erreur du preg_match). Il est donc impossible de tester qu'une chaîne est bien un JSON.

Question

Pourquoi tester error_get_last() ? Faire ($decoded !== null || strtolower(trim($value)) === 'null') ne suffit pas ?

S'il est important, il faudrait je pense faire :

    protected static function isJson($value)
    {
                 error_clear_last();
        $decoded = json_decode($value);
        return (
            error_get_last() === null &&
            ($decoded !== null || strtolower(trim($value)) === 'null')
        );
    }

Je peux bien évidemment faire une PR, je voulais juste échanger avant sur ce problème.

klnjmm commented 4 years ago

Je me permets de relancer sur ce sujet. Est-il possible d'avoir un retour des mainteneurs du projet ? Comme j'ai indiqué ci-dessus, je peux m'occuper de proposer la PR.