1
votes

I'm currently working on a project that uses "twig" for the first time, so I apologize if this is not very clear.

I have developed a custom function that embeds SVG icons on the twig templates, but for this particular project I am graded more for coverage and unit testing than anything else. Because of this I am trying to use phpunit to test if my function works as intended.

In order to do that I believe I must render an instance of the custom function on the test file, and then compare it with the raw SVG file on my directory. But I am having trouble using the render method. I believe because I don't have a twig environment available in the test.

I have looked for something similar here and I have found this previous question: "https://stackguides.com/questions/17026405/twig-template-unit-testing?rq=1". The answer to this question recommends using the following:

$twig = self::$kernel->getContainer()->get('twig');
    $html = $twig->render('AppBundle::app/something.html.twig', ['content' => 'I am some variable value']);
    self::assertEquals($html, $response->getContent());

but when I run that I get the following error:

Error: Access to undeclared static property: App\Tests\Templates\Icons\IconsExtensionTest::$kernel

How can I access the Kernel?

Here is my currently not working test file:

<?php

// This file is part of GNU social - https://www.gnu.org/software/social
//
// GNU social is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// GNU social is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with GNU social.  If not, see <http://www.gnu.org/licenses/>.

/**
 * This file test the Macro that Embeds SVG icons.
 *
 * @package   Tests
 *
 * @author    Ângelo D. Moura <[email protected]>
 * @copyright 2019 Free Software Foundation, Inc http://www.fsf.org
 * @license   https://www.gnu.org/licenses/agpl.html GNU AGPL v3 or later
 */

namespace App\Tests\Templates\Icons;

use App\Twig\IconsExtension;
use App\Kernel;
use DirectoryIterator;
use PHPUnit\Framework\TestCase;

class IconsExtensionTest extends TestCase
{
    public function testIconsExtension()
    {

        //Get all Icon files names from "public/assets/icons"
        $icon_file_names = [];
        foreach (new DirectoryIterator('public/assets/icons/') as $file) {
            if ($file->isDot()) {
                continue;
            }
            $icon_file_names[] = $file->getFilename();
        }

        //Check if every icon file as a ".svg.twig" extension
        foreach ($icon_file_names as $icon_file_name) {
            static::assertRegExp('#([a-zA-Z0-9\s_\\.\-\(\):])+(.svg.twig)$#', $icon_file_name);
        }



        //Check if the function gives a valid HTML with a class attribute equal to the one passed
        $twig = self::$kernel->getContainer()->get('twig');

        /*
        $icon_template_render = $twig->render('public/icons/logo.svg', ['iconClass' => 'icon icon-logo']);

        $iconsExtension= new IconsExtension();

        $iconsExtension_render = $iconsExtension->embedSvgIcon($twig, 'logo', 'logo');

        self::assertEquals($icon_template_render, $iconsExtension_render);

        // Next I need to verify that the $iconsExtension_render is a valid html code (maybe through regex)

        */
    }
}

Here is my custom function (if needed):

<?php

// {{{ License
// This file is part of GNU social - https://www.gnu.org/software/social
//
// GNU social is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// GNU social is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with GNU social.  If not, see <http://www.gnu.org/licenses/>.
// }}}

/**
 * GNU social Twig extensions
 *
 * @package   GNUsocial
 * @category  Twig
 *
 * @author    Ângelo D. Moura <[email protected]>
 * @copyright 2020 Free Software Foundation, Inc http://www.fsf.org
 * @license   https://www.gnu.org/licenses/agpl.html GNU AGPL v3 or later
 */

namespace App\Twig;

use Twig\Environment;
use Twig\Error\LoaderError;
use Twig\Error\RuntimeError;
use Twig\Error\SyntaxError;
use Twig\Extension\AbstractExtension;
use Twig\TwigFunction;

class IconsExtension extends AbstractExtension
{
    public function getFunctions()
    {
        return [
            new TwigFunction('icon',
                [$this, 'embedSvgIcon'],
                ['needs_environment' => true]
            ),
        ];
    }

    /**
     * Renders the Svg Icon template and returns it.
     *
     * @param Environment $twig
     * @param string      $icon_name
     * @param string      $icon_css_class
     *
     * @return string
     *
     * @author Ângelo D. Moura <[email protected]>
     */
    public function embedSvgIcon(Environment $twig, string $icon_name = '', string $icon_css_class = '')
    {
        try {
            return $twig->render('@public_path/assets/icons/' . $icon_name . '.svg.twig', ['iconClass' => $icon_css_class]);
        } catch (LoaderError $e) {
            //return an empty string (a missing icon is not that important of an error)
            return '';
        } catch (RuntimeError $e) {
            //return an empty string (a missing icon is not that important of an error)
            return '';
        } catch (SyntaxError $e) {
            //return an empty string (a missing icon is not that important of an error)
            return '';
        }
    }
}
1

1 Answers

0
votes

TestCase (phpunit class your test extends) is insufficient. you might have missed that symfony provides an extension called KernelTestCase which provides a kernel you can get the twig environment from (or WebTestCase, which also provides a client you can use to navigate your website).

So instead of

use PHPUnit\Framework\TestCase;

class IconsExtensionTest extends TestCase

you can do

use Symfony\Bundle\FrameworkBundle\Test\KernelTestCase;

class IconsExtensionTest extends KernelTestCase

you might need to call static::bootKernel(); in your setUp method, or in the test itself, to initialize the kernel and container.

then everything should work as intended