Skip to content
Extraits de code Groupes Projets
Valider 7e3c810c rédigé par JamesRezo's avatar JamesRezo :tada:
Parcourir les fichiers

Merge spip/tests dans ./tests

parent 149cc69b
Aucune branche associée trouvée
Aucune étiquette associée trouvée
Aucune requête de fusion associée trouvée
Affichage de
avec 1381 ajouts et 0 suppression
.idea
composer.lock
/vendor/
/vendor-bin/*/vendor/
.phpunit.result.cache
.phpunit.cache/
phpunit.xml
phpunit.xml.bak
tests/bootstrap_plugins.php
tests: vendor phpunit.xml bootstrap_plugins.php
vendor/bin/phpunit --colors
phpunit.xml:
php bin/configure.php
bootstrap_plugins.php:
php bin/configure.php
vendor: composer.json
composer update
touch $@
# Tests pour SPIP
Suite de tests basée sur PHPUnit, avec un wrapper pour les tests historiques écrits en script PHP standalone ou en squelette HTML
## Installation
Placez-vous à la racine du site.
```
git clone https://git.spip.net/spip/tests.git
cd tests
make tests
```
## Commande principale
Lancer tous les tests
```
make tests
```
## Commandes spécifiques
Lancer tous les tests
```
vendor/bin/phpunit --colors tests
```
Voir le détail de tous les tests lancés (y compris leurs noms)
```
vendor/bin/phpunit --colors --debug tests
```
Lister toutes les suites de tests :
```
vendor/bin/phpunit --colors --debug --list-suites
```
Lister tous les tests :
```
vendor/bin/phpunit --colors --debug --list-tests
```
Pour filtrer les tests et n'en executer que certains :
```
vendor/bin/phpunit --colors --debug tests --filter=unit/propre/
vendor/bin/phpunit --colors --debug --filter=testCouper
```
## Ajouter des tests
TODO
## Legacy
Les tests historiques écrits sous forme de PHP ou de squelette HTML sont joués via les 2 composants `LegacyUnitHtmlTest.php` et `LegacyUnitPhpTest.php`
Il est encore possible de lancer dans le navigateur la suite de tests legacy via l'url `monsite.spip/tests/` mais cette méthode est depréciée et ne lancera pas les tests écrits directement pour PHPUnit
#!/usr/bin/env php
<?php
// les args a passer a phpUnit
$args = $argv;
array_shift($args);
$dir_tests = dirname(__DIR__) . '/';
$file_bootstrap_plugins = $dir_tests . "tests/bootstrap_plugins.php";
if (!file_exists($file_bootstrap_plugins)) {
file_put_contents($file_bootstrap_plugins,"<?"."php\n");
}
// charger SPIP
require_once $dir_tests . 'tests/bootstrap.php';
// Lister les repertoires du path qui contiennent des dossier tests/ avec des tests PHPUnit
$dirs = [];
$bootstraps = [];
foreach (creer_chemin() as $d) {
if ($d and
is_dir("{$d}tests")
and (count(glob("{$d}tests/*Test.php")) or count(glob("{$d}tests/*/*Test.php")))
) {
$bases[] = "{$d}tests";
if (file_exists($f = "{$d}tests/bootstrap.php")) {
$bootstraps[] = $f;
}
}
}
$prefixe_dir = '../';
while (!is_dir($dir_tests . $prefixe_dir . 'ecrire')) {
$prefixe_dir .= '../';
}
$testsuites = [];
foreach ($bases as $base) {
$name = dirname($base);
$testsuites[] = "<testsuite name=\"$name\"><directory>{$prefixe_dir}{$base}/</directory></testsuite>";
}
$testsuites = "\t\t" . implode("\n\t\t", $testsuites) . "\n";
// generer le phpunit.xml a jour
$config = file_get_contents($dir_tests . 'phpunit.xml.dist');
$p = strpos($config, "\t</testsuites>");
$config = substr_replace($config, $testsuites, $p, 0);
file_put_contents($dir_tests . "phpunit.xml", $config);
// generer le bootstrap_plugins.php a jour
$code = "<?" . "php\n";
foreach ($bootstraps as $bootstrap) {
$code .= "include_once '".addslashes($bootstrap)."';\n";
}
file_put_contents($file_bootstrap_plugins, $code);
{
"name": "spip/tests",
"description": "Test suite for SPIP.",
"license": [
"MIT"
],
"type": "library",
"keywords": [
"cms",
"spip"
],
"require": {
"php": ">=8.1.0",
"ext-ctype": "*",
"ext-json": "*"
},
"require-dev": {
"lolli42/finediff": "^1.0",
"phpunit/phpunit": "^10.0",
"symfony/var-dumper": "^6.2",
"symplify/easy-coding-standard": "^11.1"
},
"suggest": {
"ext-iconv": "Can be used as fallback when ext-mbstring is not available",
"ext-mbstring": "For best performance, mbstring should be installed as it is faster than ext-iconv"
},
"repositories": [],
"autoload": {
"psr-4": {
"Spip\\Core\\Testing\\": "src/"
}
},
"autoload-dev": {
"psr-4": {
"Spip\\Core\\Tests\\": "tests/",
"Utils\\Rector\\": "utils/rector/src",
"Utils\\Rector\\Tests\\": "utils/rector/tests"
}
},
"config": {
"platform": {
"php": "8.1.17"
},
"sort-packages": true
}
}
<?php
// ecs.php
use PhpCsFixer\Fixer\ArrayNotation\ArraySyntaxFixer;
use PhpCsFixer\Fixer\Whitespace\NoExtraBlankLinesFixer;
use Symplify\EasyCodingStandard\Config\ECSConfig;
use Symplify\EasyCodingStandard\ValueObject\Set\SetList;
return static function (ECSConfig $ecsConfig): void {
// A. full sets
#$ecsConfig->sets([SetList::PSR_12]);
$ecsConfig->sets([SetList::PSR_12, SetList::SYMPLIFY, SetList::COMMON, SetList::CLEAN_CODE]);
$ecsConfig->rule(NoExtraBlankLinesFixer::class);
$ecsConfig->indentation('tab');
$ecsConfig->paths([
__DIR__ . '/src',
__DIR__ . '/tests',
]);
};
<?php
$dir = (isset($_GET['dir']) AND ($_GET['dir'])) ? $_GET['dir'] : '..';
chdir($dir);
require 'ecrire/inc_version.php';
// pas admin ? passe ton chemin (ce script est un vilain trou de securite)
if ((!isset($GLOBALS['visiteur_session']['statut'])
OR $GLOBALS['visiteur_session']['statut'] != '0minirezo')
AND !in_array($_SERVER["REMOTE_ADDR"], array('127.0.0.1', '127.0.1.1', '::1')) ) {
die('Administrateur local requis !');
}
// supprimer le vieux logs de tests
spip_unlink(_DIR_TMP."testrunner.log");
// chercher les bases de tests
$bases = array('tests/unit');
foreach (creer_chemin() as $d) {
if ($d && @is_dir("{$d}tests"))
$bases[] = "{$d}tests";
}
// déclarations
$sectionold = '';
echo
"<!DOCTYPE html PUBLIC '-//W3C//DTD XHTML 1.0 Strict//EN'
'http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd'>\n",
"<html><head><title>Tests de SPIP</title>",
"<script src='tests/legacy/js/jquery-3.2.js' type='text/javascript'></script>\n",
"<script src='tests/legacy/js/testrunner.js' type='text/javascript'></script>\n",
"<link rel='stylesheet' href='tests/legacy/css/tests.css' type='text/css' />\n",
"</head><body>\n",
"<h1>",
"Tests SPIP ", version_spip(),
"</h1>\n";
include_once __DIR__ . '/tests/legacy/test_fonctions.php';
define('_DIR_TESTS', basename(__DIR__).'/');
$tests = tests_legacy_lister();
// utiliser le parametre $_GET['fichier'] pour limiter les tests a un seul fichier
if (isset($_GET['fichier']) AND $_GET['fichier'] != '' AND preg_match('[^\d\w-.]', $_GET['fichier']) != 1)
$fic = $_GET['fichier'];
foreach ($tests as $joli => $test) {
if (isset($fic) AND $fic != '' AND substr_count($test, $fic) == 0)
continue;
if (preg_match(',\.php$,', $test))
$url = '../'.$test.'?mode=test_general';
else
$url = "tests/legacy/squel.php?test=$test&amp;var_mode=recalcul";
$section = dirname($joli);
$dirTests = true;
$section_vcs = "";
if (strpos($section, 'tests/') !== 0) {
$dirTests = false;
if ($vcs = decrire_version_git(dirname(dirname($test)))) {
$section_vcs = ' ['.$vcs['commit_short'].']';
}
}
if ($section <> $sectionold) {
if ($sectionold) echo "</dl>\n";
$titre = $dirTests ? $section : "<a href='../$section'>$section</a>$section_vcs";
echo "<dl><dt>$titre</dt>\n";
$sectionold = $section;
}
echo "<dd>
<a href='$url' class='joli' title='".basename($test)."'>".basename($joli).":</a> &nbsp;
&nbsp;</dd>\n";
}
echo "</dl>\n";
echo "<div id='count'>";
echo "<span id='succes'>0</span> succ&#232;s, ";
echo "<span id='echec'>0</span> &#233;chec / ";
echo "<span id='total'>0</span> total";
echo "<br />tests exp&#233;di&#233;s en <span id='timer'>0</span>ms";
echo "</div>";
echo "</body></html>";
function version_spip() {
include_spip('inc/minipres');
$version = $GLOBALS['spip_version_affichee'];
if ($vcs = decrire_version_git(_DIR_RACINE)) {
$version .= ' ' . ($vcs['vcs'] ?? '')
. "[<a href='https://git.spip.net/spip/spip/commit/"
. $vcs['commit'] . "' onclick=\"window.open(this.href); return false;\">"
. $vcs['commit_short'] . "</a>]";
}
return $version;
}
<?xml version="1.0" encoding="UTF-8"?>
<phpunit
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
bootstrap="./tests/bootstrap.php"
colors="true"
stopOnFailure="false"
xsi:noNamespaceSchemaLocation="https://schema.phpunit.de/10.0/phpunit.xsd"
cacheDirectory=".phpunit.cache"
>
<coverage/>
<testsuites>
<testsuite name="core"><directory>./tests/</directory></testsuite>
</testsuites>
</phpunit>
<?php
declare(strict_types=1);
use Rector\CodeQuality\Rector\Class_\InlineConstructorDefaultToPropertyRector;
use Rector\Config\RectorConfig;
use Rector\Set\ValueObject\LevelSetList;
use Rector\Set\ValueObject\SetList;
use Rector\CodingStyle\Rector\Encapsed\EncapsedStringsToSprintfRector;
use Utils\Rector\Rector\Set\ValueObject\SpipTestSetList;
return static function (RectorConfig $rectorConfig): void {
$rectorConfig->disableParallel();
$rectorConfig->paths([
__DIR__ . '/src',
__DIR__ . '/tests'
]);
// define sets of rules
#$rectorConfig->sets([
# SpipTestSetList::ESSAIS_MIGRATION
#]);
};
<?php
declare(strict_types=1);
namespace Spip\Core\Testing\Constraint;
use PHPUnit\Framework\Constraint\Constraint;
final class IsOk extends Constraint
{
/**
* Returns a string representation of the constraint.
*/
public function toString(): string
{
return 'is OK';
}
/**
* Evaluates the constraint for parameter $other. Returns true if the constraint is met, false otherwise.
*
* @param mixed $other value or object to evaluate
*/
protected function matches($other): bool
{
return substr(strtolower(trim($other)), 0, 2) === 'ok';
}
/**
* Returns the description of the failure.
*
* The beginning of failure messages is "Failed asserting that" in most cases. This method should return the second
* part of that sentence.
*
* @param mixed $other evaluated value or object
*/
protected function failureDescription($other): string
{
return sprintf('"%s" is OK', $other);
}
}
<?php
declare(strict_types=1);
namespace Spip\Core\Testing\Exception;
class TemplateCompilationErrorException extends \Exception
{
public function __construct($message = '', $code = 0, \Throwable $previous = null)
{
$message = sprintf("Compilation error '%s'", $message);
parent::__construct($message, $code, $previous);
}
}
<?php
declare(strict_types=1);
namespace Spip\Core\Testing\Exception;
class TemplateNotFoundException extends \Exception
{
public function __construct($message = '', $code = 0, \Throwable $previous = null)
{
$message = sprintf("'%s' template not found", $message);
parent::__construct($message, $code, $previous);
}
}
<?php
declare(strict_types=1);
namespace Spip\Core\Testing;
use PHPUnit\Framework\Constraint\LogicalNot;
use PHPUnit\Framework\TestCase;
use Spip\Core\Testing\Constraint\IsOk;
use Spip\Core\Testing\Template\FileLoader;
use Spip\Core\Testing\Template\StringLoader;
abstract class SquelettesTestCase extends TestCase
{
/**
* Determine si une chaine débute par 'NA' (non applicable)
*/
public static function isNa(string $chaine): bool
{
return substr(strtolower(trim($chaine)), 0, 2) === 'na';
}
/**
* Retourne le chemin relatif depuis la racine de SPIP
*/
public static function relativePath(string $fullDirectory): string
{
if (! defined('_SPIP_TEST_CHDIR')) {
throw new \RuntimeException('_SPIP_TEST_CHDIR needs to be defined');
}
return substr($fullDirectory, strlen(_SPIP_TEST_CHDIR) + 1);
}
/**
* Determine si une chaine débute par 'OK'
*/
public static function assertOk($actual, string $message = ''): void
{
$constraint = new IsOk($actual);
static::assertThat($actual, $constraint, $message);
}
/**
* Determine si une chaine ne débute pas par 'OK'
*/
public static function assertNotOk($actual, string $message = ''): void
{
$constraint = new LogicalNot(new IsOk($actual));
static::assertThat($actual, $constraint, $message);
}
/**
* Assertion qui vérifie que le résultat d’un template est 'OK'
*
* @example
* $templating = new Templating(new StringLoader());
* $this->assertOkTemplate($templating, '[(#CONFIG{pasla}|non)ok]');
*
* $templating = new Templating(new FileLoader());
* $this->assertOkTemplate($templating, __DIR__ . '/data/truc.html');
*
* @uses Template
* @param string $code Code ou chemin du squelette
* @param array $contexte Contexte de calcul du squelette
* @param string $message Message pour une eventuelle erreur
*/
public static function assertOkTemplate(
Templating $templating,
string $code,
array $contexte = [],
string $message = ''
): void {
$actual = $templating->render($code, $contexte);
static::assertOk($actual, $message);
}
/**
* Assertion qui vérifie que le résultat d’un template est vide
*
* @see assertOkTemplate()
*/
public static function assertNotOkTemplate(
Templating $templating,
string $code,
array $contexte = [],
string $message = ''
): void {
$actual = $templating->render($code, $contexte);
static::assertNotOk($actual, $message);
}
/**
* Assertion qui vérifie que le résultat d’un template est vide
*
* @see assertOkTemplate()
*/
public static function assertEmptyTemplate(
Templating $templating,
string $code,
array $contexte = [],
string $message = ''
): void {
$actual = $templating->render($code, $contexte);
static::assertEmpty($actual, $message);
}
/**
* Assertion qui vérifie que le résultat d’un template n’est pas vide
*
* @see assertOkTemplate()
*/
public static function assertNotEmptyTemplate(
Templating $templating,
string $code,
array $contexte = [],
string $message = ''
): void {
$actual = $templating->render($code, $contexte);
static::assertNotEmpty($actual, $message);
}
/**
* Assertion qui vérifie le résultat d’un template
*
* @see assertOkTemplate()
*/
public static function assertEqualsTemplate(
string $expected,
Templating $templating,
string $code,
array $contexte = [],
string $message = ''
): void {
$actual = $templating->render($code, $contexte);
static::assertEquals($expected, $actual, $message);
}
/**
* Assertion qui vérifie le résultat d’un template
*
* @see assertOkTemplate()
*/
public static function assertNotEqualsTemplate(
string $expected,
Templating $templating,
string $code,
array $contexte = [],
string $message = ''
): void {
$actual = $templating->render($code, $contexte);
static::assertNotEquals($expected, $actual, $message);
}
/**
* Assertion qui vérifie que le résultat d’un code de squelette est 'OK'
*
* @example $this->assertOkCode('[(#CONFIG{pasla}|non)ok]');
*
* @uses Template
* @param string $code Code ou chemin du squelette
* @param array $contexte Contexte de calcul du squelette
* @param string $message Message pour une eventuelle erreur
*/
public static function assertOkCode(string $code, array $contexte = [], string $message = ''): void
{
static::assertOkTemplate(Templating::fromString(), $code, $contexte);
}
/**
* Assertion qui vérifie que le résultat d’un code de squelette n’est pas 'OK'
*
* @see assertOkCode()
*/
public function assertNotOkCode(string $code, array $contexte = [], $message = ''): void
{
static::assertNotOkTemplate(Templating::fromString(), $code, $contexte);
}
/**
* Assertion qui vérifie que le résultat d’un code de squelette est vide
*
* @see assertOkCode()
*/
public static function assertEmptyCode(string $code, array $contexte = [], string $message = ''): void
{
static::assertEmptyTemplate(Templating::fromString(), $code, $contexte);
}
/**
* Assertion qui vérifie que le résultat d’un code de squelette n’est pas vide
*
* @see assertOkCode()
*/
public static function assertNotEmptyCode(string $code, array $contexte = [], string $message = ''): void
{
static::assertNotEmptyTemplate(Templating::fromString(), $code, $contexte);
}
/**
* Assertion qui vérifie le résultat d’un code de squelette
*
* @see assertOkCode()
*/
public function assertEqualsCode(string $expected, string $code, array $contexte = [], $message = ''): void
{
static::assertEqualsTemplate($expected, Templating::fromString(), $code, $contexte);
}
/**
* Assertion qui vérifie le résultat d’un code de squelette
*
* @see assertOkCode()
*/
public function assertNotEqualsCode(string $expected, string $code, array $contexte = [], $message = '')
{
static::assertNotEqualsTemplate($expected, Templating::fromString(), $code, $contexte);
}
/**
* Assertion qui vérifie que le résultat d’un fichier de squelette est 'OK'
*
* @example $this->assertOkSquelette(__DIR__ . '/data/squelette.html');
*
* @uses Template
* @param string $code Code ou chemin du squelette
* @param array $contexte Contexte de calcul du squelette
* @param string $message Message pour une eventuelle erreur
*/
public static function assertOkSquelette(string $code, array $contexte = [], string $message = ''): void
{
static::assertOkTemplate(Templating::fromFile(), $code, $contexte);
}
/**
* Assertion qui vérifie que le résultat d’un fichier de squelette n’est pas 'OK'
*
* @see assertOkSquelette()
*/
public function assertNotOkSquelette(string $code, array $contexte = [], $message = ''): void
{
static::assertNotOkTemplate(Templating::fromFile(), $code, $contexte);
}
/**
* Assertion qui vérifie que le résultat d’un fichier de squelette est vide
*
* @see assertOkSquelette()
*/
public static function assertEmptySquelette(string $code, array $contexte = [], string $message = ''): void
{
static::assertEmptyTemplate(Templating::fromFile(), $code, $contexte);
}
/**
* Assertion qui vérifie que le résultat d’un fichier de squelette n’est pas vide
*
* @see assertOkSquelette()
*/
public static function assertNotEmptySquelette(string $code, array $contexte = [], string $message = ''): void
{
static::assertNotEmptyTemplate(Templating::fromFile(), $code, $contexte);
}
/**
* Assertion qui vérifie le résultat d’un fichier de squelette
*
* @see assertOkSquelette()
*/
public function assertEqualsSquelette(string $expected, string $code, array $contexte = [], $message = ''): void
{
static::assertEqualsTemplate($expected, Templating::fromFile(), $code, $contexte);
}
/**
* Assertion qui vérifie le résultat d’un fichier de squelette
*
* @see assertOkSquelette()
*/
public function assertNotEqualsSquelette(string $expected, string $code, array $contexte = [], $message = '')
{
static::assertNotEqualsTemplate($expected, Templating::fromFile(), $code, $contexte);
}
}
<?php
declare(strict_types=1);
namespace Spip\Core\Testing;
use Spip\Core\Testing\Exception\TemplateCompilationErrorException;
class Template
{
private string $fond;
public function __construct(string $fond)
{
$this->fond = $fond;
}
public function render(array $contexte = [], string $connect = ''): string
{
$infos = $this->rawRender($contexte, $connect);
if (!empty($infos['erreurs'])) {
$message = json_encode($infos['erreurs'], \JSON_UNESCAPED_UNICODE|\JSON_PRETTY_PRINT);
if (!$message) {
$erreurs = $infos['erreurs'];
foreach ($erreurs as &$erreur) {
$erreur = reset($erreur);
}
$message = json_encode($erreurs, \JSON_UNESCAPED_UNICODE|\JSON_PRETTY_PRINT);
}
throw new TemplateCompilationErrorException($message);
}
return $infos['texte'];
}
/**
* Appele recuperer_fond avec l'option raw pour obtenir un tableau d'informations que l'on complete avec le nom du fond
* et les erreurs de compilations generees
*/
public function rawRender(array $contexte = [], string $connect = ''): array
{
// vider les erreurs
$this->init_compilation_errors();
// en mode 'raw' ça ne trim pas le texte, sacrebleu !
$infos = recuperer_fond($this->fond, $contexte, [
'raw' => true,
'trim' => true,
], $connect);
$infos['texte'] = trim($infos['texte']);
// on ajoute des infos supplementaires a celles retournees
$path = pathinfo($infos['source']);
$infos['fond'] = $path['dirname'] . '/' . $path['filename']; // = $fond;
$infos['erreurs'] = $this->get_compilation_errors();
return $infos;
}
/**
* Retourne un tableau des erreurs de compilation
*/
private function get_compilation_errors(): array
{
$debusquer = charger_fonction('debusquer', 'public');
$erreurs = $debusquer('', '', [
'erreurs' => 'get',
]);
$debusquer('', '', [
'erreurs' => 'reset',
]);
return $erreurs;
}
/**
* Raz les erreurs de compilation
*/
private function init_compilation_errors(): void
{
$debusquer = charger_fonction('debusquer', 'public');
$debusquer('', '', [
'erreurs' => 'reset',
]);
}
}
<?php
declare(strict_types=1);
namespace Spip\Core\Testing\Template\Loader;
use Spip\Core\Testing\Exception\TemplateNotFoundException;
class ChainLoader implements LoaderInterface
{
/**
* @var LoaderInterface[]
*/
private array $loaders = [];
private array $cache = [];
public function __construct(array $loaders)
{
foreach ($loaders as $loader) {
$this->addLoader($loader);
}
}
public function exists(string $name): bool
{
if (isset($this->cache[$name])) {
return $this->cache[$name];
}
foreach ($this->loaders as $loader) {
if ($loader->exists($name)) {
return $this->cache[$name] = true;
}
}
return $this->cache[$name] = false;
}
public function getCacheKey(string $name): string
{
foreach ($this->loaders as $loader) {
if (! $loader->exists($name)) {
continue;
}
return $loader->getCacheKey($name);
}
throw new TemplateNotFoundException($name);
}
public function getSourceFile(string $name): string
{
foreach ($this->loaders as $loader) {
if (! $loader->exists($name)) {
continue;
}
return $loader->getSourceFile($name);
}
throw new TemplateNotFoundException($name);
}
private function addLoader(LoaderInterface $loader)
{
$this->loaders[] = $loader;
$this->cache = [];
}
}
<?php
declare(strict_types=1);
namespace Spip\Core\Testing\Template\Loader;
use Spip\Core\Testing\Exception\TemplateNotFoundException;
class FileLoader implements LoaderInterface
{
private int $rootLen;
public function __construct()
{
$this->rootLen = strlen(_SPIP_TEST_CHDIR) + 1;
}
public function exists(string $name): bool
{
$filepath = realpath($name);
return ($filepath !== false) && file_exists($filepath);
}
public function getCacheKey(string $name): string
{
return $this->getSourceFile($name);
}
public function getSourceFile(string $name): string
{
$filepath = realpath($name);
if (!$filepath or !file_exists($filepath)) {
throw new TemplateNotFoundException($name);
}
$desc = pathinfo($name);
$fond = $desc['dirname'] . '/' . $desc['filename'];
return substr($fond, $this->rootLen);
}
}
<?php
declare(strict_types=1);
namespace Spip\Core\Testing\Template\Loader;
interface LoaderInterface
{
public function exists(string $name): bool;
public function getSourceFile(string $name): string;
public function getCacheKey(string $name): string;
}
<?php
declare(strict_types=1);
namespace Spip\Core\Testing\Template\Loader;
class StringLoader implements LoaderInterface
{
private string $adresse_dernier_fichier_pour_code = '';
private string $cacheDirectory = '';
private array $options = [];
public function __construct(array $options = [])
{
include_spip('inc/flock');
$this->cacheDirectory = sous_repertoire(_DIR_CACHE, 'Tests');
$this->setOptions($options);
}
public function exists(string $name): bool
{
return true;
}
public function getCacheKey(string $name): string
{
return md5($name . serialize($this->options));
}
/**
* Écrit le code du squelette dans un fichier temporaire de cache
*/
public function getSourceFile(string $name): string
{
$fond = $this->cacheDirectory . $this->getCacheKey($name);
$options = $this->options;
$code = $name;
if (isset($options['avant_code'])) {
$code = $options['avant_code'] . $code;
}
if (isset($options['apres_code'])) {
$code .= $options['apres_code'];
}
$this->ecrire_fichier($fond . '.html', $code);
if (! empty($options['fonctions'])) {
// un fichier unique pour ces fonctions
$func = $this->cacheDirectory . 'func_' . md5($options['fonctions']) . '.php';
$this->ecrire_fichier($func, $this->php($options['fonctions']));
// une inclusion unique de ces fichiers
$this->ecrire_fichier($fond . '_fonctions.php', $this->php(sprintf('include_once(\'%s\');', $func)));
}
return $fond;
}
/**
* Définit des options de compilation du code,
*
* Notamment permet de déclarer des filtres (fonctions) pour le code à compiler
*
* Stocke des options :
* - fonctions : pour ajouter un fichier de fonction au squelette cree (on passe le contenu du fichier)
* - avant_code : pour inserer du contenu avant le code
* - apres_code : pour inserer du contenu apres le code
*
* @param array $options : param->valeur des options
*/
private function setOptions(array $options = []): void
{
$this->options = $options;
}
/**
* Retourne "<?php $code ?>"
*
* @param string $code Code php
* @return string Code php complet
*/
private function php(string $code): string
{
return '<' . "?php\n" . $code . "\n?" . '>';
}
/**
* Ecrire un fichier à l'endroit indique
*
* Le réécrit systématiquement.
*
* @param string $filename Adresse du fichier a ecrire
* @param string $content Contenu du fichier
*/
private function ecrire_fichier(string $filename, string $content): void
{
if (file_exists($filename)) {
supprimer_fichier($filename);
}
ecrire_fichier($filename, $content);
}
}
<?php
declare(strict_types=1);
namespace Spip\Core\Testing;
use Spip\Core\Testing\Template\Loader\FileLoader;
use Spip\Core\Testing\Template\Loader\LoaderInterface;
use Spip\Core\Testing\Template\Loader\StringLoader;
class Templating
{
private LoaderInterface $loader;
public function __construct(LoaderInterface $loader)
{
$this->loader = $loader;
}
public static function fromString(array $options = []): self
{
return new static(new StringLoader($options));
}
public static function fromFile(): self
{
return new static(new FileLoader());
}
public function getLoader(): LoaderInterface
{
return $this->loader;
}
public function load(string $name): Template
{
$source = $this->loader->getSourceFile($name);
return new Template($source);
}
public function render(string $name, array $contexte = [], string $connect = ''): string
{
return $this->load($name)
->render($contexte, $connect);
}
public function rawRender(string $name, array $contexte = [], string $connect = ''): array
{
return $this->load($name)
->rawRender($contexte, $connect);
}
}
<?php
declare(strict_types=1);
/***************************************************************************\
* SPIP, Système de publication pour l'internet *
* *
* Copyright © avec tendresse depuis 2001 *
* Arnaud Martin, Antoine Pitrou, Philippe Rivière, Emmanuel Saint-James *
* *
* Ce programme est un logiciel libre distribué sous licence GNU/GPL. *
* Pour plus de détails voir le fichier COPYING.txt ou l'aide en ligne. *
\***************************************************************************/
namespace Spip\Core\Tests\Action;
use PHPUnit\Framework\TestCase;
class EditerLiensTest extends TestCase
{
public static function setUpBeforeClass(): void
{
include_spip('action/editer_liens');
}
public static function tearDownAfterClass(): void
{
include_spip('base/abstract_sql');
sql_delete('spip_auteurs_liens', "objet='spirou'");
sql_delete('spip_auteurs_liens', "objet='zorglub'");
}
public function testObjetAssociable()
{
$essais = [
[
0 => false,
1 => 'article',
],
[
0 => ['id_auteur', 'spip_auteurs_liens'],
1 => 'auteur',
],
[
0 => ['id_mot', 'spip_mots_liens'],
1 => 'mot',
],
[
0 => ['id_document', 'spip_documents_liens'],
1 => 'document',
],
[
0 => false,
1 => "mot' OR 1=1'",
],
];
foreach ($essais as $k => $essai) {
$expected = array_shift($essai);
$this->assertEquals($expected, objet_associable(...$essai), "Echec {$k} : objet_associable " . end($essai));
}
}
/**
* @depends testObjetAssociable
*/
public function testObjetAssocier()
{
$essais = [
[
0 => false,
1 => [
'article' => 1,
],
2 => [
'spirou' => 1,
],
],
[
0 => 1,
1 => [
'auteur' => 1,
],
2 => [
'spirou' => 1,
],
],
[
0 => 0,
1 => [
'auteur' => 1,
],
2 => [
'spirou' => 1,
],
],
[
0 => 2,
1 => [
'auteur' => 1,
],
2 => [
'spirou' => [2, 3],
],
],
[
0 => 1,
1 => [
'auteur' => 1,
],
2 => [
'spirou' => [2, 3, 4],
],
],
[
10,
[
'auteur' => 1,
],
[
'zorglub' => [1, 2, 3, 4, 5, 6, 7, 8, 9, 10],
],
],
[
6,
[
'auteur' => 1,
],
[
'spirou' => [1, 2, 3, 4, 5, 6, 7, 8, 9, 10],
],
],
];
foreach ($essais as $k => $essai) {
$expected = array_shift($essai);
$this->assertEquals(
$expected,
objet_associer(...$essai),
"Echec {$k} : objet_associer " . json_encode($essai, JSON_THROW_ON_ERROR)
);
}
}
/**
* @depends testObjetAssocier
*/
public function testObjetQualifierLiens()
{
$essais = [
[
0 => false,
1 => [
'article' => 1,
],
2 => [
'zorglub' => 1,
],
3 => [
'vu' => 'oui',
],
],
[
0 => 1,
1 => [
'auteur' => 1,
],
2 => [
'zorglub' => 1,
],
3 => [
'vu' => 'oui',
],
],
[
0 => 1,
1 => [
'auteur' => 1,
],
2 => [
'zorglub' => 1,
],
3 => [
'vu' => 'oui',
],
],
[
0 => false,
1 => [
'auteur' => 1,
],
2 => [
'zorglub' => 1,
],
3 => [
'veraer' => 'oui',
],
],
[
0 => 2,
1 => [
'auteur' => 1,
],
2 => [
'zorglub' => [2, 3],
],
3 => [
'vu' => 'oui',
],
],
];
foreach ($essais as $k => $essai) {
$expected = array_shift($essai);
$this->assertEquals(
$expected,
objet_qualifier_liens(...$essai),
"Echec {$k} : objet_qualifier_liens " . json_encode($essai, JSON_THROW_ON_ERROR)
);
}
}
/**
* @depends testObjetQualifierLiens
*/
public function testObjetDissocier()
{
$essais = [
[
0 => false,
1 => [
'article' => 1,
],
2 => [
'zorglub' => 1,
],
],
[
0 => 1,
1 => [
'auteur' => 1,
],
2 => [
'zorglub' => 1,
],
],
[
0 => 0,
1 => [
'auteur' => 1,
],
2 => [
'zorglub' => 1,
],
],
[
0 => 2,
1 => [
'auteur' => 1,
],
2 => [
'zorglub' => [2, 3],
],
],
[
0 => 1,
1 => [
'auteur' => 1,
],
2 => [
'zorglub' => [2, 3, 4],
],
],
[
0 => 4,
1 => [
'auteur' => 1,
],
2 => [
'zorglub' => [5],
'spirou' => [2, 3, 4],
],
],
[
0 => 12,
1 => [
'auteur' => 1,
],
2 => [
'zorglub' => '*',
'spirou' => '*',
],
],
];
foreach ($essais as $k => $essai) {
$expected = array_shift($essai);
$this->assertEquals(
$expected,
objet_dissocier(...$essai),
"Echec {$k} : objet_dissocier " . json_encode($essai, JSON_THROW_ON_ERROR)
);
}
}
}
0% Chargement en cours ou .
You are about to add 0 people to the discussion. Proceed with caution.
Terminez d'abord l'édition de ce message.
Veuillez vous inscrire ou vous pour commenter