symfony1 icon indicating copy to clipboard operation
symfony1 copied to clipboard

[tests] port the test system to phpunit

Open connorhu opened this issue 2 years ago • 12 comments

This is an issue to track the progression.

Branch: https://github.com/connorhu/symfony1/tree/feature/phpunit Target php version: php7.4

Components:

  • [x] action
  • [x] addon
  • [x] autoload
  • [x] cache
  • [x] command
  • [x] config
  • [x] controller
  • [x] database
  • [x] debug
  • [x] escaper
  • [x] event
  • [x] exception
  • [x] filter
  • [x] form
  • [x] generator
  • [x] helper
  • [x] i18n
  • [x] log
  • [x] mailer
  • [x] plugin
  • [x] request
  • [x] response
  • [x] routing
  • [x] service
  • [x] storage
  • [x] task
  • [x] test
  • [x] user
  • [x] util
  • [x] validator
  • [x] view
  • [x] widget
  • [x] yaml

connorhu avatar Feb 19 '23 10:02 connorhu

https://github.com/connorhu/symfony1/blob/feature/phpunit/tests/controller/sfWebControllerTest.php#L37-L51 sfWebControllerTest now fail because of type error.

       yield ['module/action?id=12', array(
            '',
            array(
                'module' => 'module',
                'action' => 'action',
                'id'     => 12,
            ),
        )];

:

--- Expected
+++ Actual
@@ @@
     1 => Array &1 (
         'module' => 'module'
         'action' => 'action'
-        'id' => 12
+        'id' => '12'
     )
 )

If we look at the test writer intent, then all numeric arguments must be converted to real numbers.

connorhu avatar Feb 23 '23 08:02 connorhu

A copy from issue #285

PHPUnit brings up the errors nicely. The first assert fails because of an acceptParameter method bug.

        $option = new sfCommandOption('foo', null, sfCommandOption::IS_ARRAY);
        $this->assertSame(true, $option->acceptParameter());

        $option = new sfCommandOption('foo', null, sfCommandOption::PARAMETER_OPTIONAL);
        $this->assertSame(true, $option->acceptParameter());

        $option = new sfCommandOption('foo', null, sfCommandOption::PARAMETER_REQUIRED);
        $this->assertSame(true, $option->acceptParameter());

        $option = new sfCommandOption('foo', null, sfCommandOption::PARAMETER_NONE);
        $this->assertSame(false, $option->acceptParameter());

Description of acceptParameter describes how it should work, but the implementation doesn't do that:

https://github.com/FriendsOfSymfony1/symfony1/blob/master/lib/command/sfCommandOption.class.php#L105-L110

I guess the implementation should something like this:

  public function acceptParameter(): bool
  {
    return self::PARAMETER_NONE !== (self::PARAMETER_NONE & $this->mode);
  }

The sfCommandOptionTest test it, but because of [] == false is true, the test don't fail. https://github.com/FriendsOfSymfony1/symfony1/blob/d9a1684cf3cde16a812eaed75dbc5ea0e8d55863/test/unit/command/sfCommandOptionTest.php#L89-L90

What should we do with bugs like this? Fix it in 1.5.x or we wait for 1.6.x and after I finish the integration of phpunit we fix it and backport to 1.5.x?

connorhu avatar Feb 23 '23 08:02 connorhu

Another "who made a mistake?" memo

https://github.com/FriendsOfSymfony1/symfony1/blob/2826410bbfdb8dd69db968b9c44ca2550a38a9da/test/unit/routing/sfPatternRoutingTest.php#L546

Test message says: "->findRoute() returns null on non-matching route"

The findRoute method calls getRouteThatMatchesUrl protected method.

https://github.com/FriendsOfSymfony1/symfony1/blob/2826410bbfdb8dd69db968b9c44ca2550a38a9da/lib/routing/sfPatternRouting.class.php#L368-L411

https://github.com/FriendsOfSymfony1/symfony1/blob/2826410bbfdb8dd69db968b9c44ca2550a38a9da/lib/routing/sfPatternRouting.class.php#L474-L487

The getRouteThatMatchesUrl method returns false.

IMHO the test is wrong because the return annotation of findRoute method says: array|false An array with routing information or false if no route matched.

connorhu avatar Nov 29 '23 08:11 connorhu

IMHO annotation is just a comment and comments can lie.

The only things that do not lie is the code behaviour.

The question is what kind of assertion is done with $t->is(), === or == ?

alquerci avatar Nov 29 '23 12:11 alquerci

During porting, I change the is method to the more type-strict assertSame method, so I look at the tester's intent in each case. However, here the tester intent is wrong.

connorhu avatar Nov 29 '23 16:11 connorhu

IMHO good idea, but it tends to complexity this migration.

So in this context, the source of truth is the production code.

On this example: if return value is false then assertFalse is the way to go.

Like you said. The test code is good, but the test message is misleading. My message was abstract.

alquerci avatar Nov 29 '23 18:11 alquerci

Another "who made a mistake? / where is the bug?" memo

sfWebRequestTest.php

        $request->languages = null;
        $_SERVER['HTTP_ACCEPT_LANGUAGE'] = '';
        $this->is($request->getLanguages(), [], '->getLanguages() returns an empty array if the client send an empty ACCEPT_LANGUAGE header');

Test message says: getLanguages() returns an empty array if the client send an empty ACCEPT_LANGUAGE header

https://github.com/FriendsOfSymfony1/symfony1/blob/2826410bbfdb8dd69db968b9c44ca2550a38a9da/lib/request/sfWebRequest.class.php#L433-L441

Now the isset() is not enough we should check empty() too.

connorhu avatar Dec 15 '23 14:12 connorhu

Another "who made a mistake? / where is the bug?" memo

sfI18NTest.php

$t->is($i18n->getTimeForCulture(null), null, '->getTimeForCulture() returns null in case of conversion problem');

Test message says: ->getTimeForCulture() returns null in case of conversion problem

https://github.com/FriendsOfSymfony1/symfony1/blob/2826410bbfdb8dd69db968b9c44ca2550a38a9da/lib/i18n/sfI18N.class.php#L316-L322

I guess there is an implementation bug and we should return null here not 0.

An extra typo is that the phpdoc return type is not only an array but also null.

connorhu avatar Dec 15 '23 16:12 connorhu

https://github.com/FriendsOfSymfony1/symfony1/issues/286#issuecomment-1857974108

$acceptLanguage = '0';
empty($acceptLanguage) // true

Does a string "0" is an empty ACCEPT_LANGUAGE header ?

alquerci avatar Dec 15 '23 20:12 alquerci

sfViewCacheManager::has() method with null return

https://github.com/FriendsOfSymfony1/symfony1/blob/2826410bbfdb8dd69db968b9c44ca2550a38a9da/lib/view/sfViewCacheManager.class.php#L384-L391

connorhu avatar Dec 15 '23 22:12 connorhu

#286 (comment)

$acceptLanguage = '0';
empty($acceptLanguage) // true

Does a string "0" is an empty ACCEPT_LANGUAGE header ?

An empty array is fine when client send 0. After all, this is an invalid value.

https://github.com/connorhu/symfony1/blob/998c9a40e210f1fd9acab51aa51cd32400811ca0/tests/request/sfWebRequestTest.php#L39-L42

connorhu avatar Dec 15 '23 22:12 connorhu

Side note: we should deprecate and totally remove pear support (plugin component). PEAR is a deprecation hell and not working with composer.

connorhu avatar Dec 16 '23 10:12 connorhu