TASK: Add first test

Add all dependencies to run tests.
Configure tests as composer task.
Add tests to travis.
Adjust code to make him exchangeable and testable.
This commit is contained in:
Daniel Siepmann 2017-12-14 23:06:08 +01:00
parent 227ca8a035
commit eba401aa9f
Signed by: Daniel Siepmann
GPG key ID: 33D6629915560EF4
10 changed files with 206 additions and 57 deletions

4
.gitignore vendored
View file

@ -12,3 +12,7 @@
.sass-cache .sass-cache
node_modules node_modules
bower_components bower_components
composer.lock
package-lock.json
typo3
vendor

View file

@ -12,3 +12,4 @@ install:
script: script:
- composer lint - composer lint
- composer cgl - composer cgl
- composer test

View file

@ -1,20 +1,6 @@
<?php <?php
declare(strict_types=1);
namespace Saccas\Mjml\Domain\Finishers; namespace Saccas\Mjml\Domain\Finishers;
/*
* This file is part of the TYPO3 CMS project.
*
* It is free software; you can redistribute it and/or modify it under
* the terms of the GNU General Public License, either version 2
* of the License, or any later version.
*
* For the full copyright and license information, please read the
* LICENSE.txt file that was distributed with this source code.
*
* The TYPO3 project - inspiring people to share!
*/
use TYPO3\CMS\Fluid\View\StandaloneView; use TYPO3\CMS\Fluid\View\StandaloneView;
use TYPO3\CMS\Form\Domain\Finishers\Exception\FinisherException; use TYPO3\CMS\Form\Domain\Finishers\Exception\FinisherException;
use TYPO3\CMS\Form\Domain\Runtime\FormRuntime; use TYPO3\CMS\Form\Domain\Runtime\FormRuntime;

View file

@ -0,0 +1,45 @@
<?php
namespace Saccas\Mjml\Domain\Renderer;
use TYPO3\CMS\Core\Utility\CommandUtility;
use TYPO3\CMS\Core\Utility\GeneralUtility;
class Command implements RendererInterface
{
protected function getHtmlFromMjml($mjml)
{
$configuration = unserialize($GLOBALS['TYPO3_CONF_VARS']['EXT']['extConf']['mjml']);
$temporaryMjmlFileWithPath = GeneralUtility::tempnam('mjml_', '.mjml');
GeneralUtility::writeFileToTypo3tempDir($temporaryMjmlFileWithPath, $mjml);
// see https://mjml.io/download and https://www.npmjs.com/package/mjml-cli
$cmd = $configuration['nodeBinaryPath'] . ' ' . $configuration['mjmlBinaryPath'] . $configuration['mjmlBinary'];
$args = $configuration['mjmlParams'] . ' ' . $temporaryMjmlFileWithPath;
$result = [];
$returnValue = '';
CommandUtility::exec($this->getEscapedCommand($cmd, $args), $result, $returnValue);
GeneralUtility::unlink_tempfile($temporaryMjmlFileWithPath);
return implode('', $result);
}
/**
* @param string $cmd
* @param string $args
* @return string
*/
protected function getEscapedCommand(string $cmd, string $args)
{
$escapedCmd = escapeshellcmd($cmd);
$argsArray = explode(' ', $args);
$escapedArgsArray = CommandUtility::escapeShellArguments($argsArray);
$escapedArgs = implode(' ', $escapedArgsArray);
return $escapedCmd . ' ' . $escapedArgs;
}
}

View file

@ -0,0 +1,16 @@
<?php
namespace Saccas\Mjml\Domain\Renderer;
/**
* Defines API of possible renderers.
*/
interface RendererInterface
{
/**
* Convert mjml strings into html.
*
* @param string $mjml
* @return string
*/
public function getHtmlFromMjml($mjml);
}

View file

@ -1,53 +1,29 @@
<?php <?php
namespace Saccas\Mjml\View; namespace Saccas\Mjml\View;
use TYPO3\CMS\Core\Utility\GeneralUtility; use Saccas\Mjml\Domain\Renderer\RendererInterface;
use TYPO3\CMS\Extbase\Mvc\Cli\Command;
use TYPO3\CMS\Fluid\View\StandaloneView; use TYPO3\CMS\Fluid\View\StandaloneView;
use TYPO3\CMS\Core\Utility\CommandUtility; use TYPO3\CMS\Frontend\ContentObject\ContentObjectRenderer;
class MjmlBasedView extends StandaloneView class MjmlBasedView extends StandaloneView
{ {
/**
* @var RendererInterface
*/
protected $renderer;
public function __construct(ContentObjectRenderer $contentObject = null, RendererInterface $renderer = null)
{
parent::__construct($contentObject);
$this->renderer = $renderer;
if ($this->renderer === null) {
$this->renderer = $this->objectManager->get(RendererInterface::class);
}
}
public function render($actionName = null) public function render($actionName = null)
{ {
return $this->getHtmlFromMjml(parent::render()); return $this->renderer->getHtmlFromMjml(parent::render($actionName));
}
protected function getHtmlFromMjml($mjml)
{
$configuration = unserialize($GLOBALS['TYPO3_CONF_VARS']['EXT']['extConf']['mjml']);
$temporaryMjmlFileWithPath = GeneralUtility::tempnam('mjml_', '.mjml');
GeneralUtility::writeFileToTypo3tempDir($temporaryMjmlFileWithPath, $mjml);
// see https://mjml.io/download and https://www.npmjs.com/package/mjml-cli
$cmd = $configuration['nodeBinaryPath'] . ' ' . $configuration['mjmlBinaryPath'] . $configuration['mjmlBinary'];
$args = $configuration['mjmlParams'] . ' ' . $temporaryMjmlFileWithPath;
$result = [];
$returnValue = '';
CommandUtility::exec($this->getEscapedCommand($cmd, $args), $result, $returnValue);
GeneralUtility::unlink_tempfile($temporaryMjmlFileWithPath);
return implode('', $result);
}
/**
* @param string $cmd
* @param string $args
* @return string
*/
private function getEscapedCommand(string $cmd, string $args)
{
$escapedCmd = escapeshellcmd($cmd);
$argsArray = explode(' ', $args);
$escapedArgsArray = CommandUtility::escapeShellArguments($argsArray);
$escapedArgs = implode(' ', $escapedArgsArray);
return $escapedCmd . ' ' . $escapedArgs;
} }
} }

View file

@ -0,0 +1,22 @@
<?php
namespace Saccas\Mjml\Tests\Unit;
use TYPO3\CMS\Core\Cache\Backend\NullBackend;
use TYPO3\CMS\Core\Cache\CacheManager;
use TYPO3\CMS\Core\Utility\GeneralUtility;
use TYPO3\TestingFramework\Core\Unit\UnitTestCase;
abstract class AbstractUnitTestCase extends UnitTestCase
{
public function setUp()
{
parent::setUp();
GeneralUtility::makeInstance(CacheManager::class)
->setCacheConfigurations([
'extbase_object' => [
'backend' => NullBackend::class,
],
]);
}
}

View file

@ -0,0 +1,55 @@
<?php
namespace Saccas\Mjml\Tests\Unit\View;
use Saccas\Mjml\Domain\Renderer\RendererInterface;
use Saccas\Mjml\Tests\Unit\AbstractUnitTestCase;
use Saccas\Mjml\View\MjmlBasedView;
class MjmlBasedViewTest extends AbstractUnitTestCase
{
public const EXAMPLE_MJML_TEMPLATE = '<mjml>
<mj-body>
<mj-container>
<mj-section>
<mj-column>
<mj-image src="/assets/img/easy-and-quick.png" width="112" />
<mj-text font-size="20px" color="#595959" align="center">Easy and Quick</mj-text>
</mj-column>
<mj-column>
<mj-image src="/assets/img/responsive.png" width="135" />
<mj-text font-size="20px" color="#595959" align="center">Responsive</mj-text>
</mj-column>
</mj-section>
<mj-section>
<mj-column>
<mj-button background-color="#F45E43" font-size="15px">Discover</mj-button>
</mj-column>
</mj-section>
</mj-container>
</mj-body>
</mjml>
';
/**
* @test
*/
public function viewCallsRendererAndReturnsRenderedHtml()
{
$expectedHtml = '<h1>Simple HTML</h1>';
$rendererMock = $this->getMockBuilder(RendererInterface::class)->getMock();
$rendererMock->expects($this->once())
->method('getHtmlFromMjml')
->with(static::EXAMPLE_MJML_TEMPLATE)
->willReturn($expectedHtml);
$subject = new MjmlBasedView(null, $rendererMock);
$subject->setTemplateSource(static::EXAMPLE_MJML_TEMPLATE);
$result = $subject->render();
$this->assertSame(
$expectedHtml,
$result,
'Rendering of view did not return expected HTML.'
);
}
}

View file

@ -10,13 +10,26 @@
"Saccas\\Mjml\\": "Classes/" "Saccas\\Mjml\\": "Classes/"
} }
}, },
"autoload-dev": {
"psr-4": {
"Saccas\\Mjml\\Tests\\": "Tests/"
}
},
"require": { "require": {
"php": ">=7.0.0 <=7.2.99", "php": ">=7.0.0 <=7.2.99",
"typo3/cms-core": "^8.7.0", "typo3/cms-core": "^8.7.0",
"typo3/cms-form": "^8.7.0" "typo3/cms-form": "^8.7.0"
}, },
"require-dev": { "require-dev": {
"squizlabs/php_codesniffer": "^3.2.0" "squizlabs/php_codesniffer": "^3.2.0",
"typo3/cms": "^8.7.0",
"typo3/testing-framework": "^1.2.2"
},
"extra": {
"typo3/cms": {
"cms-package-dir": "{$vendor-dir}/typo3/cms",
"web-dir": "typo3"
}
}, },
"scripts": { "scripts": {
"lint": [ "lint": [
@ -26,6 +39,9 @@
"cgl": [ "cgl": [
"./vendor/bin/phpcs" "./vendor/bin/phpcs"
], ],
"test": [
"TYPO3_PATH_ROOT=typo3 ./vendor/bin/phpunit"
],
"post-install-cmd": [ "post-install-cmd": [
"npm install" "npm install"
] ]

28
phpunit.xml.dist Normal file
View file

@ -0,0 +1,28 @@
<phpunit
backupGlobals="false"
backupStaticAttributes="false"
bootstrap="./vendor/typo3/testing-framework/Resources/Core/Build/UnitTestsBootstrap.php"
colors="true"
convertErrorsToExceptions="false"
convertWarningsToExceptions="false"
forceCoversAnnotation="false"
processIsolation="false"
stopOnError="false"
stopOnFailure="false"
stopOnIncomplete="false"
stopOnSkipped="false"
verbose="false">
<testsuites>
<testsuite name="unit-tests">
<directory>./Tests/Unit/</directory>
</testsuite>
</testsuites>
<filter>
<whitelist>
<directory suffix=".php">Classes</directory>
</whitelist>
</filter>
</phpunit>