maj projet

This commit is contained in:
Jephté Clain 2025-03-04 08:08:03 +04:00
parent 998d353758
commit 1685a40906
45 changed files with 78 additions and 2880 deletions

View File

@ -1,8 +1,8 @@
# nur\sery\schema
# nulib\schema
objet: s'assurer que des données soit dans un type particulier, en les
convertissant si nécessaire. la source de ces données peut-être diverse:
formulaire web, résultat d'une requête SQL, flux CSV, etc.
les classes de ce package permettent de s'assurer que des données soit dans un
type particulier, en les convertissant si nécessaire. la source de ces données
peut-être diverse: formulaire web, résultat d'une requête SQL, flux CSV, etc.
les données dont on peut modéliser le schéma sont de 3 types:
* scalaire
@ -84,8 +84,12 @@ const SCALAR_SCHEMA = [
"title" => "libellé de la valeur, utilisable par exemple dans un formulaire",
"required" => "la valeur est-elle requise? si oui, elle doit exister",
"nullable" => "si la valeur existe, peut-elle être nulle?",
"allow_null" => "si la valeur existe, peut-elle être nulle?", #XXX
"allow_empty" => "si la valeur existe, peut-elle être vide?", #XXX
"desc" => "description de la valeur",
"checker_func" => "une fonction qui vérifie une valeur et la classifie",
"analyzer_func" => "XXX",
"extractor_func" => "XXX",
"checker_func" => "XXX une fonction qui vérifie une valeur et la classifie",
"parser_func" => "une fonction qui analyse une chaine pour produire la valeur",
"messages" => "messages à afficher en cas d'erreur d'analyse",
"formatter_func" => "une fonction qui formatte la valeur pour affichage",
@ -118,9 +122,9 @@ nature scalaire si:
* c'est un tableau avec un élément à l'index 0, ainsi que d'autres éléments,
e.g `["string", null, "required" => true]`
message indique les messages à afficher en cas d'erreur d'analyse. les clés sont
normalisées et correspondent à différents états de la valeur tels qu'analysés
par `checker_func`
`messages` indique les messages à afficher en cas d'erreur d'analyse. les clés
sont normalisées et correspondent à différents états de la valeur tels
qu'analysés par `checker_func`
~~~php
const MESSAGE_SCHEMA = [
"missing" => "message si la valeur n'existe pas dans la source et qu'elle est requise",
@ -156,6 +160,7 @@ récursivement, avec cependant l'ajout de quelques clés supplémentaires:
~~~php
VALUE_SCHEMA = [
...
"key" => "nom du champ auquel assigner la valeur de la clé", #XXX
"name" => "identifiant de la valeur",
"pkey" => "chemin de clé de la valeur dans le tableau associatif",
];

View File

@ -2,15 +2,15 @@
namespace nur\sery\wip\schema;
use ArrayAccess;
use nur\sery\AccessException;
use nur\sery\cl;
use nulib\AccessException;
use nulib\cl;
use nur\sery\wip\schema\_assoc\AssocSchema;
use nur\sery\wip\schema\_list\ListSchema;
use nur\sery\wip\schema\_scalar\ScalarSchema;
abstract class Schema implements ArrayAccess {
/**
* créer si besoin une nouvelle instance de {@link Schema} à partir d'une
* créer le cas échéant une nouvelle instance de {@link Schema} à partir d'une
* définition de schéma
*
* - si $schema est une instance de schéma, la retourner
@ -38,7 +38,7 @@ abstract class Schema implements ArrayAccess {
}
/**
* Créer si besoin une nouvelle instance de {@link Value} qui référence la
* Créer une nouvelle instance de {@link Value} qui référence la
* variable $dest (si $destKey===null) ou $dest[$destKey] si $destKey n'est
* pas null
*/

View File

@ -1,4 +1,4 @@
# nur\sery\schema
# nulib\schema
* implémenter support `analyzer_func`, `extractor_func`, `parser_func`,
`normalizer_func`, `formatter_func`
@ -42,6 +42,8 @@
$type = new ttype();
const SCHEMA = [[["type", ...]], default, "required" => true];
// ou
const SCHEMA = [["type" => [...]], default, "required" => true];
# le type est instancié comme suit:
# le tableau peut être une liste ou associatif, c'est au type de décider ce
# qu'il en fait

View File

@ -1,10 +1,10 @@
<?php
namespace nur\sery\wip\schema\_scalar;
use nur\sery\cl;
use nur\sery\ref\schema\ref_analyze;
use nur\sery\ref\schema\ref_schema;
use nur\sery\ValueException;
use nulib\cl;
use nulib\ref\schema\ref_analyze;
use nulib\ref\schema\ref_schema;
use nulib\ValueException;
use nur\sery\wip\schema\Result;
/**

View File

@ -1,9 +1,9 @@
<?php
namespace nur\sery\wip\schema\_scalar;
use nur\sery\cl;
use nur\sery\ref\schema\ref_schema;
use nur\sery\ref\schema\ref_types;
use nulib\cl;
use nulib\ref\schema\ref_schema;
use nulib\ref\schema\ref_types;
use nur\sery\wip\schema\Schema;
use nur\sery\wip\schema\SchemaException;
use nur\sery\wip\schema\types\tarray;
@ -92,8 +92,10 @@ class ScalarSchema extends Schema {
$index = 0;
foreach ($keys as $key) {
if (!is_int($key)) continue;
$definition[$index] = $definition[$key];
unset($definition[$key]);
if ($key !== $index) {
$definition[$index] = $definition[$key];
unset($definition[$key]);
}
$index++;
}
}
@ -149,6 +151,7 @@ class ScalarSchema extends Schema {
$definition["pkey"] = $pkey;
$definition["header"] = $header;
# autres éléments
tarray::ensure_narray($definition["schema"]);
tstring::ensure_nstring($definition["title"]);
tbool::ensure_bool($definition["required"]);
tbool::ensure_bool($definition["nullable"]);

View File

@ -1,8 +1,8 @@
<?php
namespace nur\sery\wip\schema\_scalar;
use nur\sery\ref\schema\ref_analyze;
use nur\sery\ValueException;
use nulib\ref\schema\ref_analyze;
use nulib\ValueException;
use nur\sery\wip\schema\input\Input;
use nur\sery\wip\schema\types;
use nur\sery\wip\schema\types\IType;
@ -10,17 +10,17 @@ use nur\sery\wip\schema\Value;
class ScalarValue extends Value {
function __construct(ScalarSchema $schema, &$dest=null, $destKey=null, bool $defaultVerifix=true, ?bool $defaultThrow=null) {
if ($dest !== null && $defaultThrow = null) {
if ($dest !== null && $defaultThrow === null) {
# Si $dest est null, ne pas lancer d'exception, parce qu'on considère que
# c'est une initialisation sans conséquences
$defaultThrow = true;
}
$this->schema = $schema;
$this->defaultVerifix = $defaultVerifix;
$this->defaultThrow = $defaultThrow !== null? $defaultThrow: false;
$this->defaultThrow = $defaultThrow ?? false;
$this->result = new ScalarResult();
$this->reset($dest, $destKey);
$this->defaultThrow = $defaultThrow !== null? $defaultThrow: true;
$this->defaultThrow = $defaultThrow ?? true;
}
function isScalar(?ScalarValue &$scalar=null): bool { $scalar = $this; return true; }

View File

@ -1,7 +1,7 @@
<?php
namespace nur\sery\wip\schema\types;
use nur\sery\cl;
use nulib\cl;
class Registry {
const TYPES = [

View File

@ -1,7 +1,7 @@
<?php
namespace nur\sery\wip\schema\types;
use nur\sery\cl;
use nulib\cl;
use nur\sery\wip\schema\Result;
use nur\sery\wip\schema\Schema;

View File

@ -1,8 +1,8 @@
<?php
namespace nur\sery\wip\schema\types;
use nur\sery\cl;
use nur\sery\ValueException;
use nulib\cl;
use nulib\ValueException;
use nur\sery\wip\schema\_scalar\ScalarResult;
use nur\sery\wip\schema\_scalar\ScalarSchema;
use nur\sery\wip\schema\input\Input;

View File

@ -1,15 +1,13 @@
<?php
namespace nur\sery\wip\schema\types;
use nur\sery\php\nur_func;
use nur\sery\ValueException;
use nulib\php\func;
use nur\sery\wip\schema\Result;
use nur\sery\wip\schema\Schema;
use stdClass;
class tcallable extends _tsimple {
static function ensure_callable(&$callable): void {
if (!is_callable($callable)) throw ValueException::invalid_type($callable, "callable");
func::ensure($callable);
}
static function ensure_ncallable(&$callable): void {
@ -18,7 +16,7 @@ class tcallable extends _tsimple {
function isValid($value, ?bool &$normalized=null): bool {
$normalized = is_callable($value);
return nur_func::check_func($value, stdClass::class);
return func::check($value);
}
function verifix(&$value, Result &$result, Schema $schema): bool {

View File

@ -6,7 +6,8 @@ use nur\sery\wip\schema\Schema;
abstract class tcontent extends _tsimple {
static function ensure_content(&$content): void {
if (!is_string($content) && !is_array($content)) $content = strval($content);
if ($content === null || $content === false) $content = [];
elseif (!is_string($content) && !is_array($content)) $content = strval($content);
}
static function ensure_ncontent(&$content): void {

View File

@ -1,9 +1,10 @@
<?php
namespace nur\sery\wip\web\content;
use nur\sery\A;
use nur\sery\php\content\c;
use nur\sery\php\content\IContent;
use nulib\A;
use nulib\php\content\c;
use nulib\php\content\IContent;
class Tag implements IContent {
function __construct(string $tag, $content=null) {

View File

@ -1,26 +0,0 @@
<?php
namespace nur\sery\app;
use nulib\tests\TestCase;
use nur\sery\app\args;
class argsTest extends TestCase {
function testFrom_array() {
self::assertSame([], args::from_array(null));
self::assertSame([], args::from_array([]));
self::assertSame([], args::from_array([false]));
self::assertSame(["x"], args::from_array(["x", false]));
self::assertSame(["--opt"], args::from_array(["--opt"]));
self::assertSame(["--opt", "value"], args::from_array(["--opt", "value"]));
self::assertSame([], args::from_array(["opt" => false]));
self::assertSame(["--opt"], args::from_array(["opt" => true]));
self::assertSame(["--opt", "value"], args::from_array(["opt" => "value"]));
self::assertSame(["--opt", "42"], args::from_array(["opt" => 42]));
self::assertSame(["--opt", "1", "2", "3", "--"], args::from_array(["opt" => [1, 2, 3]]));
self::assertSame(["x", "1", "2", "3", "y"], args::from_array(["x", [1, 2, 3], "y"]));
}
}

View File

@ -1,132 +0,0 @@
<?php
namespace nur\sery {
use nulib\tests\TestCase;
use nur\sery\impl\config;
use nur\sery\impl\myapp;
use nur\sery\impl\MyApplication1;
use nur\sery\impl\MyApplication2;
class appTest extends TestCase {
function testWith() {
$projdir = config::get_projdir();
$cwd = getcwd();
myapp::reset();
$app1 = myapp::with(MyApplication1::class);
self::assertSame([
"projdir" => $projdir,
"vendor" => [
"bindir" => "$projdir/vendor/bin",
"autoload" => "$projdir/vendor/autoload.php",
],
"appcode" => "nur-sery",
"cwd" => $cwd,
"datadir" => "$projdir/devel",
"etcdir" => "$projdir/devel/etc",
"vardir" => "$projdir/devel/var",
"logdir" => "$projdir/devel/log",
"profile" => "devel",
"appgroup" => null,
"name" => "my-application1",
"title" => null,
], $app1->getParams());
$app2 = myapp::with(MyApplication2::class, $app1);
self::assertSame([
"projdir" => $projdir,
"vendor" => [
"bindir" => "$projdir/vendor/bin",
"autoload" => "$projdir/vendor/autoload.php",
],
"appcode" => "nur-sery",
"cwd" => $cwd,
"datadir" => "$projdir/devel",
"etcdir" => "$projdir/devel/etc",
"vardir" => "$projdir/devel/var",
"logdir" => "$projdir/devel/log",
"profile" => "devel",
"appgroup" => null,
"name" => "my-application2",
"title" => null,
], $app2->getParams());
}
function testInit() {
$projdir = config::get_projdir();
$cwd = getcwd();
myapp::reset();
myapp::init(MyApplication1::class);
self::assertSame([
"projdir" => $projdir,
"vendor" => [
"bindir" => "$projdir/vendor/bin",
"autoload" => "$projdir/vendor/autoload.php",
],
"appcode" => "nur-sery",
"cwd" => $cwd,
"datadir" => "$projdir/devel",
"etcdir" => "$projdir/devel/etc",
"vardir" => "$projdir/devel/var",
"logdir" => "$projdir/devel/log",
"profile" => "devel",
"appgroup" => null,
"name" => "my-application1",
"title" => null,
], myapp::get()->getParams());
myapp::init(MyApplication2::class);
self::assertSame([
"projdir" => $projdir,
"vendor" => [
"bindir" => "$projdir/vendor/bin",
"autoload" => "$projdir/vendor/autoload.php",
],
"appcode" => "nur-sery",
"cwd" => $cwd,
"datadir" => "$projdir/devel",
"etcdir" => "$projdir/devel/etc",
"vardir" => "$projdir/devel/var",
"logdir" => "$projdir/devel/log",
"profile" => "devel",
"appgroup" => null,
"name" => "my-application2",
"title" => null,
], myapp::get()->getParams());
}
}
}
namespace nur\sery\impl {
use nur\sery\app\cli\Application;
use nur\sery\os\path;
use nur\sery\app;
class config {
const PROJDIR = __DIR__.'/..';
static function get_projdir(): string {
return path::abspath(self::PROJDIR);
}
}
class myapp extends app {
static function reset(): void {
self::$app = null;
}
}
class MyApplication1 extends Application {
const PROJDIR = config::PROJDIR;
function main() {
}
}
class MyApplication2 extends Application {
const PROJDIR = null;
function main() {
}
}
}

View File

@ -1 +0,0 @@
/capacitor.db*

View File

@ -1,344 +0,0 @@
<?php
namespace nur\sery\db\sqlite;
use nulib\tests\TestCase;
use nur\sery\cl;
use nur\sery\db\Capacitor;
use nur\sery\db\CapacitorChannel;
class SqliteStorageTest extends TestCase {
function _testChargeStrings(SqliteStorage $storage, ?string $channel) {
$storage->reset($channel);
$storage->charge($channel, "first");
$storage->charge($channel, "second");
$storage->charge($channel, "third");
$items = cl::all($storage->discharge($channel, false));
self::assertSame(["first", "second", "third"], $items);
}
function _testChargeArrays(SqliteStorage $storage, ?string $channel) {
$storage->reset($channel);
$storage->charge($channel, ["id" => 10, "name" => "first"]);
$storage->charge($channel, ["name" => "second", "id" => 20]);
$storage->charge($channel, ["name" => "third", "id" => "30"]);
}
function testChargeStrings() {
$storage = new SqliteStorage(__DIR__.'/capacitor.db');
$this->_testChargeStrings($storage, null);
$storage->close();
}
function testChargeArrays() {
$storage = new SqliteStorage(__DIR__.'/capacitor.db');
$storage->addChannel(new class extends CapacitorChannel {
const NAME = "arrays";
const COLUMN_DEFINITIONS = ["id" => "integer"];
function getItemValues($item): ?array {
return ["id" => $item["id"] ?? null];
}
});
$this->_testChargeStrings($storage, "strings");
$this->_testChargeArrays($storage, "arrays");
$storage->close();
}
function testEach() {
$storage = new SqliteStorage(__DIR__.'/capacitor.db');
$capacitor = new Capacitor($storage, new class extends CapacitorChannel {
const NAME = "each";
const COLUMN_DEFINITIONS = [
"age" => "integer",
"done" => "integer default 0",
];
function getItemValues($item): ?array {
return [
"age" => $item["age"],
];
}
});
$capacitor->reset();
$capacitor->charge(["name" => "first", "age" => 5]);
$capacitor->charge(["name" => "second", "age" => 10]);
$capacitor->charge(["name" => "third", "age" => 15]);
$capacitor->charge(["name" => "fourth", "age" => 20]);
$setDone = function ($item, $row, $suffix=null) {
$updates = ["done" => 1];
if ($suffix !== null) {
$item["name"] .= $suffix;
$updates["item"] = $item;
}
return $updates;
};
$capacitor->each(["age" => [">", 10]], $setDone, ["++"]);
$capacitor->each(["done" => 0], $setDone, null);
Txx(cl::all($capacitor->discharge(false)));
$capacitor->close();
self::assertTrue(true);
}
function testPrimayKey() {
$storage = new SqliteStorage(__DIR__.'/capacitor.db');
$capacitor = new Capacitor($storage, new class extends CapacitorChannel {
const NAME = "pk";
const COLUMN_DEFINITIONS = [
"id_" => "varchar primary key",
"done" => "integer default 0",
];
function getItemValues($item): ?array {
return [
"id_" => $item["numero"],
];
}
});
$capacitor->charge(["numero" => "a", "name" => "first", "age" => 5]);
$capacitor->charge(["numero" => "b", "name" => "second", "age" => 10]);
$capacitor->charge(["numero" => "c", "name" => "third", "age" => 15]);
$capacitor->charge(["numero" => "d", "name" => "fourth", "age" => 20]);
sleep(2);
$capacitor->charge(["numero" => "b", "name" => "second", "age" => 100]);
$capacitor->charge(["numero" => "d", "name" => "fourth", "age" => 200]);
$capacitor->close();
self::assertTrue(true);
}
function testSum() {
$storage = new SqliteStorage(__DIR__.'/capacitor.db');
$capacitor = new Capacitor($storage, new class extends CapacitorChannel {
const NAME = "sum";
const COLUMN_DEFINITIONS = [
"a__" => "varchar",
"b__" => "varchar",
"b__sum_" => self::SUM_DEFINITION,
];
function getItemValues($item): ?array {
return [
"a" => $item["a"],
"b" => $item["b"],
];
}
});
$capacitor->reset();
$capacitor->charge(["a" => null, "b" => null]);
$capacitor->charge(["a" => "first", "b" => "second"]);
Txx("=== all");
/** @var Sqlite $sqlite */
$sqlite = $capacitor->getStorage()->db();
Txx(cl::all($sqlite->all([
"select",
"from" => $capacitor->getChannel()->getTableName(),
])));
Txx("=== each");
$capacitor->each(null, function ($item, $values) {
Txx($values);
});
$capacitor->close();
self::assertTrue(true);
}
function testEachValues() {
# tester que values contient bien toutes les valeurs de la ligne
$storage = new SqliteStorage(__DIR__.'/capacitor.db');
$capacitor = new Capacitor($storage, new class extends CapacitorChannel {
const NAME = "each_values";
const COLUMN_DEFINITIONS = [
"name" => "varchar primary key",
"age" => "integer",
"done" => "integer default 0",
"notes" => "text",
];
function getItemValues($item): ?array {
return [
"name" => $item["name"],
"age" => $item["age"],
];
}
});
$capacitor->reset();
$capacitor->charge(["name" => "first", "age" => 5], function($item, ?array $values, ?array $pvalues) {
self::assertSame("first", $item["name"]);
self::assertSame(5, $item["age"]);
self::assertnotnull($values);
self::assertSame(["name", "age", "item", "item__sum_", "created_", "modified_"], array_keys($values));
self::assertSame([
"name" => "first",
"age" => 5,
"item" => $item,
], cl::select($values, ["name", "age", "item"]));
self::assertNull($pvalues);
});
$capacitor->charge(["name" => "first", "age" => 10], function($item, ?array $values, ?array $pvalues) {
self::assertSame("first", $item["name"]);
self::assertSame(10, $item["age"]);
self::assertnotnull($values);
self::assertSame(["name", "age", "done", "notes", "item", "item__sum_", "created_", "modified_"], array_keys($values));
self::assertSame([
"name" => "first",
"age" => 10,
"done" => 0,
"notes" => null,
"item" => $item,
], cl::select($values, ["name", "age", "done", "notes", "item"]));
self::assertNotNull($pvalues);
self::assertSame([
"name" => "first",
"age" => 5,
"done" => 0,
"notes" => null,
"item" => ["name" => "first", "age" => 5],
], cl::select($pvalues, ["name", "age", "done", "notes", "item"]));
});
$capacitor->each(null, function($item, ?array $values) {
self::assertSame("first", $item["name"]);
self::assertSame(10, $item["age"]);
self::assertnotnull($values);
self::assertSame(["name", "age", "done", "notes", "item", "item__sum_", "created_", "modified_"], array_keys($values));
self::assertSame([
"name" => "first",
"age" => 10,
"done" => 0,
"notes" => null,
"item" => $item,
], cl::select($values, ["name", "age", "done", "notes", "item"]));
return [
"done" => 1,
"notes" => "modified",
];
});
$capacitor->charge(["name" => "first", "age" => 10], function($item, ?array $values, ?array $pvalues) {
self::assertSame("first", $item["name"]);
self::assertSame(10, $item["age"]);
self::assertnotnull($values);
self::assertSame(["name", "age", "done", "notes", "item", "item__sum_", "created_", "modified_"], array_keys($values));
self::assertSame([
"name" => "first",
"age" => 10,
"done" => 1,
"notes" => "modified",
"item" => $item,
], cl::select($values, ["name", "age", "done", "notes", "item"]));
self::assertNotNull($pvalues);
self::assertSame([
"name" => "first",
"age" => 10,
"done" => 1,
"notes" => "modified",
"item" => $item,
], cl::select($pvalues, ["name", "age", "done", "notes", "item"]));
});
$capacitor->charge(["name" => "first", "age" => 20], function($item, ?array $values, ?array $pvalues) {
self::assertSame("first", $item["name"]);
self::assertSame(20, $item["age"]);
self::assertnotnull($values);
self::assertSame(["name", "age", "done", "notes", "item", "item__sum_", "created_", "modified_"], array_keys($values));
self::assertSame([
"name" => "first",
"age" => 20,
"done" => 1,
"notes" => "modified",
"item" => $item,
], cl::select($values, ["name", "age", "done", "notes", "item"]));
self::assertNotNull($pvalues);
self::assertSame([
"name" => "first",
"age" => 10,
"done" => 1,
"notes" => "modified",
"item" => ["name" => "first", "age" => 10],
], cl::select($pvalues, ["name", "age", "done", "notes", "item"]));
});
}
function testSetItemNull() {
# tester le forçage de $îtem à null pour économiser la place
$storage = new SqliteStorage(__DIR__.'/capacitor.db');
$capacitor = new Capacitor($storage, new class extends CapacitorChannel {
const NAME = "set_item_null";
const COLUMN_DEFINITIONS = [
"name" => "varchar primary key",
"age" => "integer",
"done" => "integer default 0",
"notes" => "text",
];
function getItemValues($item): ?array {
return [
"name" => $item["name"],
"age" => $item["age"],
];
}
});
$capacitor->reset();
$nbModified = $capacitor->charge(["name" => "first", "age" => 5], function ($item, ?array $values, ?array $pvalues) {
self::assertSame([
"name" => "first", "age" => 5,
"item" => $item,
], cl::select($values, ["name", "age", "item"]));
return ["item" => null];
});
self::assertSame(1, $nbModified);
sleep(1);
# nb: on met des sleep() pour que la date de modification soit systématiquement différente
$nbModified = $capacitor->charge(["name" => "first", "age" => 10], function ($item, ?array $values, ?array $pvalues) {
self::assertSame([
"name" => "first", "age" => 10,
"item" => $item, "item__sum_" => "9181336dfca20c86313d6065d89aa2ad5070b0fc",
], cl::select($values, ["name", "age", "item", "item__sum_"]));
self::assertSame([
"name" => "first", "age" => 5,
"item" => null, "item__sum_" => null,
], cl::select($pvalues, ["name", "age", "item", "item__sum_"]));
return ["item" => null];
});
self::assertSame(1, $nbModified);
sleep(1);
# pas de modification ici
$nbModified = $capacitor->charge(["name" => "first", "age" => 10], function ($item, ?array $values, ?array $pvalues) {
self::assertSame([
"name" => "first", "age" => 10,
"item" => $item, "item__sum_" => "9181336dfca20c86313d6065d89aa2ad5070b0fc",
], cl::select($values, ["name", "age", "item", "item__sum_"]));
self::assertSame([
"name" => "first", "age" => 10,
"item" => null, "item__sum_" => null,
], cl::select($pvalues, ["name", "age", "item", "item__sum_"]));
return ["item" => null];
});
self::assertSame(0, $nbModified);
sleep(1);
$nbModified = $capacitor->charge(["name" => "first", "age" => 20], function ($item, ?array $values, ?array $pvalues) {
self::assertSame([
"name" => "first", "age" => 20,
"item" => $item, "item__sum_" => "001b91982b4e0883b75428c0eb28573a5dc5f7a5",
], cl::select($values, ["name", "age", "item", "item__sum_"]));
self::assertSame([
"name" => "first", "age" => 10,
"item" => null, "item__sum_" => null,
], cl::select($pvalues, ["name", "age", "item", "item__sum_"]));
return ["item" => null];
});
self::assertSame(1, $nbModified);
sleep(1);
}
}

View File

@ -1,146 +0,0 @@
<?php
namespace nur\sery\db\sqlite;
use Exception;
use nulib\tests\TestCase;
class SqliteTest extends TestCase {
const CREATE_PERSON = "create table person(nom varchar, prenom varchar, age integer)";
const INSERT_JEPHTE = "insert into person(nom, prenom, age) values ('clain', 'jephte', 50)";
const INSERT_JEAN = "insert into person(nom, prenom, age) values ('payet', 'jean', 32)";
function testMigration() {
$sqlite = new Sqlite(":memory:", [
"migrate" => [
self::CREATE_PERSON,
self::INSERT_JEPHTE,
],
]);
self::assertSame("clain", $sqlite->get("select nom, age from person"));
self::assertSame([
"nom" => "clain",
"age" => 50,
], $sqlite->get("select nom, age from person", null, true));
$sqlite->exec(self::INSERT_JEAN);
self::assertSame("payet", $sqlite->get("select nom, age from person where nom = 'payet'"));
self::assertSame([
"nom" => "payet",
"age" => 32,
], $sqlite->get("select nom, age from person where nom = 'payet'", null, true));
self::assertSame([
["key" => "0", "value" => self::CREATE_PERSON, "done" => 1],
["key" => "1", "value" => self::INSERT_JEPHTE, "done" => 1],
], iterator_to_array($sqlite->all("select key, value, done from _migration")));
}
function testException() {
$sqlite = new Sqlite(":memory:");
self::assertException(Exception::class, [$sqlite, "exec"], "prout");
self::assertException(SqliteException::class, [$sqlite, "exec"], ["prout"]);
}
protected function assertInserted(Sqlite $sqlite, array $row, array $query): void {
$sqlite->exec($query);
self::assertSame($row, $sqlite->one("select * from mapping where i = :i", [
"i" => $query["values"]["i"],
]));
}
function testInsert() {
$sqlite = new Sqlite(":memory:", [
"migrate" => "create table mapping (i integer, s varchar)",
]);
$sqlite->exec(["insert into mapping", "values" => ["i" => 1, "s" => "un"]]);
$sqlite->exec(["insert mapping", "values" => ["i" => 2, "s" => "deux"]]);
$sqlite->exec(["insert into", "into" => "mapping", "values" => ["i" => 3, "s" => "trois"]]);
$sqlite->exec(["insert", "into" => "mapping", "values" => ["i" => 4, "s" => "quatre"]]);
$sqlite->exec(["insert into mapping(i)", "values" => ["i" => 5, "s" => "cinq"]]);
$sqlite->exec(["insert into (i)", "into" => "mapping", "values" => ["i" => 6, "s" => "six"]]);
$sqlite->exec(["insert into mapping(i) values ()", "values" => ["i" => 7, "s" => "sept"]]);
$sqlite->exec(["insert into mapping(i) values (8)", "values" => ["i" => 42, "s" => "whatever"]]);
$sqlite->exec(["insert into mapping(i, s) values (9, 'neuf')", "values" => ["i" => 43, "s" => "garbage"]]);
$sqlite->exec(["insert into mapping", "cols" => ["i"], "values" => ["i" => 10, "s" => "dix"]]);
self::assertSame([
["i" => 1, "s" => "un"],
["i" => 2, "s" => "deux"],
["i" => 3, "s" => "trois"],
["i" => 4, "s" => "quatre"],
["i" => 5, "s" => null/*"cinq"*/],
["i" => 6, "s" => null/*"six"*/],
["i" => 7, "s" => null/*"sept"*/],
["i" => 8, "s" => null/*"huit"*/],
["i" => 9, "s" => "neuf"],
["i" => 10, "s" => null/*"dix"*/],
], iterator_to_array($sqlite->all("select * from mapping")));
}
function testSelect() {
$sqlite = new Sqlite(":memory:", [
"migrate" => "create table user (name varchar, amount integer)",
]);
$sqlite->exec(["insert into user", "values" => ["name" => "jclain1", "amount" => 1]]);
$sqlite->exec(["insert into user", "values" => ["name" => "jclain2", "amount" => 2]]);
$sqlite->exec(["insert into user", "values" => ["name" => "jclain5", "amount" => 5]]);
$sqlite->exec(["insert into user", "values" => ["name" => "fclain7", "amount" => 7]]);
$sqlite->exec(["insert into user", "values" => ["name" => "fclain9", "amount" => 9]]);
$sqlite->exec(["insert into user", "values" => ["name" => "fclain10", "amount" => 10]]);
self::assertSame([
"name" => "jclain1",
"amount" => 1,
], $sqlite->one("select * from user where name = 'jclain1'"));
self::assertSame([
"name" => "jclain1",
"amount" => 1,
], $sqlite->one(["select * from user where name = 'jclain1'"]));
self::assertSame([
"name" => "jclain1",
"amount" => 1,
], $sqlite->one(["select from user where name = 'jclain1'"]));
self::assertSame([
"name" => "jclain1",
"amount" => 1,
], $sqlite->one(["select from user where", "where" => ["name = 'jclain1'"]]));
self::assertSame([
"name" => "jclain1",
"amount" => 1,
], $sqlite->one(["select from user", "where" => ["name = 'jclain1'"]]));
self::assertSame([
"name" => "jclain1",
"amount" => 1,
], $sqlite->one(["select", "from" => "user", "where" => ["name = 'jclain1'"]]));
self::assertSame([
"name" => "jclain1",
"amount" => 1,
], $sqlite->one(["select", "from" => "user", "where" => ["name" => "jclain1"]]));
self::assertSame([
"name" => "jclain1",
], $sqlite->one(["select name", "from" => "user", "where" => ["name" => "jclain1"]]));
self::assertSame([
"name" => "jclain1",
], $sqlite->one(["select", "cols" => "name", "from" => "user", "where" => ["name" => "jclain1"]]));
self::assertSame([
"name" => "jclain1",
], $sqlite->one(["select", "cols" => ["name"], "from" => "user", "where" => ["name" => "jclain1"]]));
self::assertSame([
"plouf" => "jclain1",
], $sqlite->one(["select", "cols" => ["plouf" => "name"], "from" => "user", "where" => ["name" => "jclain1"]]));
}
function testSelectGroupBy() {
$sqlite = new Sqlite(":memory:", [
"migrate" => "create table user (name varchar, amount integer)",
]);
$sqlite->exec(["insert into user", "values" => ["name" => "jclain1", "amount" => 1]]);
$sqlite->exec(["insert into user", "values" => ["name" => "jclain2", "amount" => 1]]);
$sqlite->exec(["insert into user", "values" => ["name" => "jclain5", "amount" => 2]]);
$sqlite->exec(["insert into user", "values" => ["name" => "fclain7", "amount" => 2]]);
$sqlite->exec(["insert into user", "values" => ["name" => "fclain9", "amount" => 2]]);
$sqlite->exec(["insert into user", "values" => ["name" => "fclain10", "amount" => 3]]);
self::assertSame([
["count" => 2],
], iterator_to_array($sqlite->all(["select count(name) as count from user", "group by" => ["amount"], "having" => ["count(name) = 2"]])));
}
}

View File

@ -1,125 +0,0 @@
<?php
namespace nur\sery\db\sqlite;
use PHPUnit\Framework\TestCase;
class _queryTest extends TestCase {
function testParseConds(): void {
$sql = $params = null;
_query_base::parse_conds(null, $sql, $params);
self::assertNull($sql);
self::assertNull($params);
$sql = $params = null;
_query_base::parse_conds([], $sql, $params);
self::assertNull($sql);
self::assertNull($params);
$sql = $params = null;
_query_base::parse_conds(["col" => null], $sql, $params);
self::assertSame(["col is null"], $sql);
self::assertNull($params);
$sql = $params = null;
_query_base::parse_conds(["col = 'value'"], $sql, $params);
self::assertSame(["col = 'value'"], $sql);
self::assertNull($params);
$sql = $params = null;
_query_base::parse_conds([["col = 'value'"]], $sql, $params);
self::assertSame(["col = 'value'"], $sql);
self::assertNull($params);
$sql = $params = null;
_query_base::parse_conds(["int" => 42, "string" => "value"], $sql, $params);
self::assertSame(["(int = :int and string = :string)"], $sql);
self::assertSame(["int" => 42, "string" => "value"], $params);
$sql = $params = null;
_query_base::parse_conds(["or", "int" => 42, "string" => "value"], $sql, $params);
self::assertSame(["(int = :int or string = :string)"], $sql);
self::assertSame(["int" => 42, "string" => "value"], $params);
$sql = $params = null;
_query_base::parse_conds([["int" => 42, "string" => "value"], ["int" => 24, "string" => "eulav"]], $sql, $params);
self::assertSame(["((int = :int and string = :string) and (int = :int2 and string = :string2))"], $sql);
self::assertSame(["int" => 42, "string" => "value", "int2" => 24, "string2" => "eulav"], $params);
$sql = $params = null;
_query_base::parse_conds(["int" => ["is null"], "string" => ["<>", "value"]], $sql, $params);
self::assertSame(["(int is null and string <> :string)"], $sql);
self::assertSame(["string" => "value"], $params);
$sql = $params = null;
_query_base::parse_conds(["col" => ["between", "lower", "upper"]], $sql, $params);
self::assertSame(["col between :col and :col2"], $sql);
self::assertSame(["col" => "lower", "col2" => "upper"], $params);
$sql = $params = null;
_query_base::parse_conds(["col" => ["in", "one"]], $sql, $params);
self::assertSame(["col in (:col)"], $sql);
self::assertSame(["col" => "one"], $params);
$sql = $params = null;
_query_base::parse_conds(["col" => ["in", ["one", "two"]]], $sql, $params);
self::assertSame(["col in (:col, :col2)"], $sql);
self::assertSame(["col" => "one", "col2" => "two"], $params);
$sql = $params = null;
_query_base::parse_conds(["col" => ["=", ["one", "two"]]], $sql, $params);
self::assertSame(["col = :col and col = :col2"], $sql);
self::assertSame(["col" => "one", "col2" => "two"], $params);
$sql = $params = null;
_query_base::parse_conds(["or", "col" => ["=", ["one", "two"]]], $sql, $params);
self::assertSame(["col = :col or col = :col2"], $sql);
self::assertSame(["col" => "one", "col2" => "two"], $params);
$sql = $params = null;
_query_base::parse_conds(["col" => ["<>", ["one", "two"]]], $sql, $params);
self::assertSame(["col <> :col and col <> :col2"], $sql);
self::assertSame(["col" => "one", "col2" => "two"], $params);
$sql = $params = null;
_query_base::parse_conds(["or", "col" => ["<>", ["one", "two"]]], $sql, $params);
self::assertSame(["col <> :col or col <> :col2"], $sql);
self::assertSame(["col" => "one", "col2" => "two"], $params);
}
function testParseValues(): void {
$sql = $params = null;
_query_base::parse_set_values(null, $sql, $params);
self::assertNull($sql);
self::assertNull($params);
$sql = $params = null;
_query_base::parse_set_values([], $sql, $params);
self::assertNull($sql);
self::assertNull($params);
$sql = $params = null;
_query_base::parse_set_values(["col = 'value'"], $sql, $params);
self::assertSame(["col = 'value'"], $sql);
self::assertNull($params);
$sql = $params = null;
_query_base::parse_set_values([["col = 'value'"]], $sql, $params);
self::assertSame(["col = 'value'"], $sql);
self::assertNull($params);
$sql = $params = null;
_query_base::parse_set_values(["int" => 42, "string" => "value"], $sql, $params);
self::assertSame(["int = :int", "string = :string"], $sql);
self::assertSame(["int" => 42, "string" => "value"], $params);
$sql = $params = null;
_query_base::parse_set_values(["int" => 42, "string" => "value"], $sql, $params);
self::assertSame(["int = :int", "string = :string"], $sql);
self::assertSame(["int" => 42, "string" => "value"], $params);
$sql = $params = null;
_query_base::parse_set_values([["int" => 42, "string" => "value"], ["int" => 24, "string" => "eulav"]], $sql, $params);
self::assertSame(["int = :int", "string = :string", "int = :int2", "string = :string2"], $sql);
self::assertSame(["int" => 42, "string" => "value", "int2" => 24, "string2" => "eulav"], $params);
}
}

View File

@ -1,63 +0,0 @@
<?php
namespace nur\sery\file\base;
use nur\sery\file\FileReader;
use PHPUnit\Framework\TestCase;
class FileReaderTest extends TestCase {
function testIgnoreBom() {
# la lecture avec et sans BOM doit être identique
## sans BOM
$reader = new FileReader(__DIR__ . '/impl/sans_bom.txt');
self::assertSame("0123456789", $reader->fread(10));
self::assertSame(10, $reader->ftell());
$reader->seek(30);
self::assertSame("abcdefghij", $reader->fread(10));
self::assertSame(40, $reader->ftell());
$reader->seek(10);
self::assertSame("ABCDEFGHIJ", $reader->fread(10));
self::assertSame(20, $reader->ftell());
$reader->seek(40);
self::assertSame("0123456789\n", $reader->getContents());
$reader->close();
## avec BOM
$reader = new FileReader(__DIR__ . '/impl/avec_bom.txt');
self::assertSame("0123456789", $reader->fread(10));
self::assertSame(10, $reader->ftell());
$reader->seek(30);
self::assertSame("abcdefghij", $reader->fread(10));
self::assertSame(40, $reader->ftell());
$reader->seek(10);
self::assertSame("ABCDEFGHIJ", $reader->fread(10));
self::assertSame(20, $reader->ftell());
$reader->seek(40);
self::assertSame("0123456789\n", $reader->getContents());
$reader->close();
}
function testCsvAutoParams() {
$reader = new FileReader(__DIR__ . '/impl/msexcel.csv');
self::assertSame(["nom", "prenom", "age"], $reader->fgetcsv());
self::assertSame(["clain", "jephte", "50"], $reader->fgetcsv());
self::assertNull($reader->fgetcsv());
$reader->close();
$reader = new FileReader(__DIR__ . '/impl/ooffice.csv');
self::assertSame(["nom", "prenom", "age"], $reader->fgetcsv());
self::assertSame(["clain", "jephte", "50"], $reader->fgetcsv());
self::assertNull($reader->fgetcsv());
$reader->close();
$reader = new FileReader(__DIR__ . '/impl/weird.tsv');
self::assertSame(["nom", "prenom", "age"], $reader->fgetcsv());
self::assertSame(["clain", "jephte", "50"], $reader->fgetcsv());
self::assertNull($reader->fgetcsv());
$reader->close();
$reader = new FileReader(__DIR__ . '/impl/avec_bom.csv');
self::assertSame(["nom", "prenom", "age"], $reader->fgetcsv());
self::assertSame(["clain", "jephte", "50"], $reader->fgetcsv());
self::assertNull($reader->fgetcsv());
$reader->close();
}
}

View File

@ -1,2 +0,0 @@
nom,prenom,age
clain,jephte,50
1 nom prenom age
2 clain jephte 50

View File

@ -1 +0,0 @@
0123456789ABCDEFGHIJ0123456789abcdefghij0123456789

View File

@ -1,2 +0,0 @@
nom;prenom;age
clain;jephte;50
1 nom prenom age
2 clain jephte 50

View File

@ -1,2 +0,0 @@
nom,prenom,age
clain,jephte,50
1 nom prenom age
2 clain jephte 50

View File

@ -1 +0,0 @@
0123456789ABCDEFGHIJ0123456789abcdefghij0123456789

View File

@ -1,2 +0,0 @@
nom prenom age
clain jephte 50
1 nom prenom age
2 clain jephte 50

File diff suppressed because it is too large Load Diff

View File

@ -1,292 +0,0 @@
<?php
namespace {
function func36(): int { return 36; }
function func_m1($a): array { return [$a]; }
function func_o1($b=9): array { return [$b]; }
function func_v(...$c): array { return [...$c]; }
function func_m1o1($a, $b=9): array { return [$a, $b]; }
function func_m1v($a, ...$c): array { return [$a, ...$c]; }
function func_m1o1v($a, $b=9, ...$c): array { return [$a, $b, ...$c]; }
function func_o1v($b=9, ...$c): array { return [$b, ...$c]; }
}
namespace nur\sery\php {
use nulib\tests\TestCase;
class nur_funcTest extends TestCase {
function testIs_static() {
self::assertFalse(nur_func::is_static(null));
self::assertFalse(nur_func::is_static(""));
self::assertFalse(nur_func::is_static("::"));
self::assertFalse(nur_func::is_static("xxx::"));
self::assertFalse(nur_func::is_static([]));
self::assertFalse(nur_func::is_static([""]));
self::assertFalse(nur_func::is_static([null, ""]));
self::assertFalse(nur_func::is_static(["xxx", ""]));
self::assertTrue(nur_func::is_static("::xxx"));
self::assertTrue(nur_func::is_static(["xxx"]));
self::assertTrue(nur_func::is_static([null, "yyy"]));
self::assertTrue(nur_func::is_static(["xxx", "yyy"]));
self::assertTrue(nur_func::is_static([null, "yyy", "aaa"]));
self::assertTrue(nur_func::is_static(["xxx", "yyy", "aaa"]));
}
function testFix_static() {
$class = "class";
$func = "::xxx";
nur_func::fix_static($func, $class);
self::assertSame("class::xxx", $func);
$func = ["xxx"];
nur_func::fix_static($func, $class);
self::assertSame(["class", "xxx"], $func);
$func = [null, "yyy"];
nur_func::fix_static($func, $class);
self::assertSame(["class", "yyy"], $func);
$func = ["xxx", "yyy"];
nur_func::fix_static($func, $class);
self::assertSame(["xxx", "yyy"], $func);
$func = [null, "yyy", "aaa"];
nur_func::fix_static($func, $class);
self::assertSame(["class", "yyy", "aaa"], $func);
$func = ["xxx", "yyy", "aaa"];
nur_func::fix_static($func, $class);
self::assertSame(["xxx", "yyy", "aaa"], $func);
}
function testIs_method() {
self::assertFalse(nur_func::is_method(null));
self::assertFalse(nur_func::is_method(""));
self::assertFalse(nur_func::is_method("->"));
self::assertFalse(nur_func::is_method([]));
self::assertFalse(nur_func::is_method([""]));
self::assertFalse(nur_func::is_method([null, "->"]));
self::assertFalse(nur_func::is_method(["xxx", "->"]));
self::assertTrue(nur_func::is_method("->xxx"));
self::assertTrue(nur_func::is_method(["->xxx"]));
self::assertTrue(nur_func::is_method([null, "->yyy"]));
self::assertTrue(nur_func::is_method(["xxx", "->yyy"]));
self::assertTrue(nur_func::is_method([null, "->yyy", "aaa"]));
self::assertTrue(nur_func::is_method(["xxx", "->yyy", "aaa"]));
}
function testFix_method() {
$object = new \stdClass();
$func= "->xxx";
nur_func::fix_method($func, $object);
self::assertSame([$object, "xxx"], $func);
$func= ["->xxx"];
nur_func::fix_method($func, $object);
self::assertSame([$object, "xxx"], $func);
$func= [null, "->yyy"];
nur_func::fix_method($func, $object);
self::assertSame([$object, "yyy"], $func);
$func= ["xxx", "->yyy"];
nur_func::fix_method($func, $object);
self::assertSame([$object, "yyy"], $func);
$func= [null, "->yyy", "aaa"];
nur_func::fix_method($func, $object);
self::assertSame([$object, "yyy", "aaa"], $func);
$func= ["xxx", "->yyy", "aaa"];
nur_func::fix_method($func, $object);
self::assertSame([$object, "yyy", "aaa"], $func);
}
function testCall() {
self::assertSame(36, nur_func::call("func36"));
self::assertSame(12, nur_func::call(TC::class."::method"));
self::assertSame(12, nur_func::call([TC::class, "method"]));
$closure = function() {
return 21;
};
self::assertSame(21, nur_func::call($closure));
}
function test_prepare_fill() {
# vérifier que les arguments sont bien remplis, en fonction du fait qu'ils
# soient obligatoires, facultatifs ou variadiques
# m1
self::assertSame([null], nur_func::call("func_m1"));
self::assertSame([null], nur_func::call("func_m1", null));
self::assertSame([null], nur_func::call("func_m1", null, null));
self::assertSame([null], nur_func::call("func_m1", null, null, null));
self::assertSame([null], nur_func::call("func_m1", null, null, null, null));
self::assertSame([1], nur_func::call("func_m1", 1));
self::assertSame([1], nur_func::call("func_m1", 1, 2));
self::assertSame([1], nur_func::call("func_m1", 1, 2, 3));
self::assertSame([1], nur_func::call("func_m1", 1, 2, 3, 4));
# o1
self::assertSame([9], nur_func::call("func_o1"));
self::assertSame([null], nur_func::call("func_o1", null));
self::assertSame([null], nur_func::call("func_o1", null, null));
self::assertSame([null], nur_func::call("func_o1", null, null, null));
self::assertSame([null], nur_func::call("func_o1", null, null, null, null));
self::assertSame([1], nur_func::call("func_o1", 1));
self::assertSame([1], nur_func::call("func_o1", 1, 2));
self::assertSame([1], nur_func::call("func_o1", 1, 2, 3));
self::assertSame([1], nur_func::call("func_o1", 1, 2, 3, 4));
# v
self::assertSame([], nur_func::call("func_v"));
self::assertSame([null], nur_func::call("func_v", null));
self::assertSame([null, null], nur_func::call("func_v", null, null));
self::assertSame([null, null, null], nur_func::call("func_v", null, null, null));
self::assertSame([null, null, null, null], nur_func::call("func_v", null, null, null, null));
self::assertSame([1], nur_func::call("func_v", 1));
self::assertSame([1, 2], nur_func::call("func_v", 1, 2));
self::assertSame([1, 2, 3], nur_func::call("func_v", 1, 2, 3));
self::assertSame([1, 2, 3, 4], nur_func::call("func_v", 1, 2, 3, 4));
# m1o1
self::assertSame([null, 9], nur_func::call("func_m1o1"));
self::assertSame([null, 9], nur_func::call("func_m1o1", null));
self::assertSame([null, null], nur_func::call("func_m1o1", null, null));
self::assertSame([null, null], nur_func::call("func_m1o1", null, null, null));
self::assertSame([null, null], nur_func::call("func_m1o1", null, null, null, null));
self::assertSame([1, 9], nur_func::call("func_m1o1", 1));
self::assertSame([1, 2], nur_func::call("func_m1o1", 1, 2));
self::assertSame([1, 2], nur_func::call("func_m1o1", 1, 2, 3));
self::assertSame([1, 2], nur_func::call("func_m1o1", 1, 2, 3, 4));
# m1v
self::assertSame([null], nur_func::call("func_m1v"));
self::assertSame([null], nur_func::call("func_m1v", null));
self::assertSame([null, null], nur_func::call("func_m1v", null, null));
self::assertSame([null, null, null], nur_func::call("func_m1v", null, null, null));
self::assertSame([null, null, null, null], nur_func::call("func_m1v", null, null, null, null));
self::assertSame([1], nur_func::call("func_m1v", 1));
self::assertSame([1, 2], nur_func::call("func_m1v", 1, 2));
self::assertSame([1, 2, 3], nur_func::call("func_m1v", 1, 2, 3));
self::assertSame([1, 2, 3, 4], nur_func::call("func_m1v", 1, 2, 3, 4));
# m1o1v
self::assertSame([null, 9], nur_func::call("func_m1o1v"));
self::assertSame([null, 9], nur_func::call("func_m1o1v", null));
self::assertSame([null, null], nur_func::call("func_m1o1v", null, null));
self::assertSame([null, null, null], nur_func::call("func_m1o1v", null, null, null));
self::assertSame([null, null, null, null], nur_func::call("func_m1o1v", null, null, null, null));
self::assertSame([1, 9], nur_func::call("func_m1o1v", 1));
self::assertSame([1, 2], nur_func::call("func_m1o1v", 1, 2));
self::assertSame([1, 2, 3], nur_func::call("func_m1o1v", 1, 2, 3));
self::assertSame([1, 2, 3, 4], nur_func::call("func_m1o1v", 1, 2, 3, 4));
# o1v
self::assertSame([9], nur_func::call("func_o1v"));
self::assertSame([null], nur_func::call("func_o1v", null));
self::assertSame([null, null], nur_func::call("func_o1v", null, null));
self::assertSame([null, null, null], nur_func::call("func_o1v", null, null, null));
self::assertSame([null, null, null, null], nur_func::call("func_o1v", null, null, null, null));
self::assertSame([1], nur_func::call("func_o1v", 1));
self::assertSame([1, 2], nur_func::call("func_o1v", 1, 2));
self::assertSame([1, 2, 3], nur_func::call("func_o1v", 1, 2, 3));
self::assertSame([1, 2, 3, 4], nur_func::call("func_o1v", 1, 2, 3, 4));
}
function testCall_all() {
$c1 = new C1();
$c2 = new C2();
$c3 = new C3();
self::assertSameValues([11, 12], nur_func::call_all(C1::class));
self::assertSameValues([11, 12, 21, 22], nur_func::call_all($c1));
self::assertSameValues([13, 11, 12], nur_func::call_all(C2::class));
self::assertSameValues([13, 23, 11, 12, 21, 22], nur_func::call_all($c2));
self::assertSameValues([111, 13, 12], nur_func::call_all(C3::class));
self::assertSameValues([111, 121, 13, 23, 12, 22], nur_func::call_all($c3));
$options = "conf";
self::assertSameValues([11], nur_func::call_all(C1::class, $options));
self::assertSameValues([11, 21], nur_func::call_all($c1, $options));
self::assertSameValues([11], nur_func::call_all(C2::class, $options));
self::assertSameValues([11, 21], nur_func::call_all($c2, $options));
self::assertSameValues([111], nur_func::call_all(C3::class, $options));
self::assertSameValues([111, 121], nur_func::call_all($c3, $options));
$options = ["prefix" => "conf"];
self::assertSameValues([11], nur_func::call_all(C1::class, $options));
self::assertSameValues([11, 21], nur_func::call_all($c1, $options));
self::assertSameValues([11], nur_func::call_all(C2::class, $options));
self::assertSameValues([11, 21], nur_func::call_all($c2, $options));
self::assertSameValues([111], nur_func::call_all(C3::class, $options));
self::assertSameValues([111, 121], nur_func::call_all($c3, $options));
self::assertSameValues([11, 12], nur_func::call_all($c1, ["include" => "x"]));
self::assertSameValues([11, 21], nur_func::call_all($c1, ["include" => "y"]));
self::assertSameValues([11, 12, 21], nur_func::call_all($c1, ["include" => ["x", "y"]]));
self::assertSameValues([21, 22], nur_func::call_all($c1, ["exclude" => "x"]));
self::assertSameValues([12, 22], nur_func::call_all($c1, ["exclude" => "y"]));
self::assertSameValues([22], nur_func::call_all($c1, ["exclude" => ["x", "y"]]));
self::assertSameValues([12], nur_func::call_all($c1, ["include" => "x", "exclude" => "y"]));
}
function testCons() {
$obj1 = nur_func::cons(WoCons::class, 1, 2, 3);
self::assertInstanceOf(WoCons::class, $obj1);
$obj2 = nur_func::cons(WithEmptyCons::class, 1, 2, 3);
self::assertInstanceOf(WithEmptyCons::class, $obj2);
$obj3 = nur_func::cons(WithCons::class, 1, 2, 3);
self::assertInstanceOf(WithCons::class, $obj3);
self::assertSame(1, $obj3->first);
}
}
class WoCons {
}
class WithEmptyCons {
function __construct() {
}
}
class WithCons {
public $first;
function __construct($first) {
$this->first = $first;
}
}
class TC {
static function method() {
return 12;
}
}
class C1 {
static function confps1_xy() {
return 11;
}
static function ps2_x() {
return 12;
}
function confp1_y() {
return 21;
}
function p2() {
return 22;
}
}
class C2 extends C1 {
static function ps3() {
return 13;
}
function p3() {
return 23;
}
}
class C3 extends C2 {
static function confps1_xy() {
return 111;
}
function confp1_y() {
return 121;
}
}
}

View File

@ -1,85 +0,0 @@
<?php
namespace nur\sery\php\time;
use DateTimeZone;
use nulib\tests\TestCase;
class DateTest extends TestCase {
protected static function dt(string $datetime): Date {
return new Date($datetime, new DateTimeZone("Indian/Reunion"));
}
function testDate() {
$date = self::dt("2024-04-05 09:15:23");
self::assertSame("05/04/2024", $date->format());
self::assertSame("05/04/2024", strval($date));
self::assertSame(2024, $date->year);
self::assertSame(4, $date->month);
self::assertSame(5, $date->day);
self::assertSame(0, $date->hour);
self::assertSame(0, $date->minute);
self::assertSame(0, $date->second);
self::assertSame(5, $date->wday);
self::assertSame(14, $date->wnum);
self::assertSame("+04:00", $date->timezone);
self::assertSame("05/04/2024 00:00:00", $date->datetime);
self::assertSame("05/04/2024", $date->date);
}
function testClone() {
$date = self::dt("now");
$clone = Date::clone($date);
self::assertInstanceOf(DateTime::class, $clone);
}
function testConstruct() {
$y = date("Y");
self::assertSame("05/04/$y", strval(new Date("5/4")));
self::assertSame("05/04/2024", strval(new Date("5/4/24")));
self::assertSame("05/04/2024", strval(new Date("5/4/2024")));
self::assertSame("05/04/2024", strval(new Date("05/04/2024")));
self::assertSame("05/04/2024", strval(new Date("20240405")));
self::assertSame("05/04/2024", strval(new Date("240405")));
self::assertSame("05/04/2024", strval(new Date("20240405T091523")));
self::assertSame("05/04/2024", strval(new Date("20240405T091523Z")));
self::assertSame("05/04/2024", strval(new Date("5/4/2024 9:15:23")));
self::assertSame("05/04/2024", strval(new Date("5/4/2024 9.15.23")));
self::assertSame("05/04/2024", strval(new Date("5/4/2024 9:15")));
self::assertSame("05/04/2024", strval(new Date("5/4/2024 9.15")));
self::assertSame("05/04/2024", strval(new Date("5/4/2024 9h15")));
self::assertSame("05/04/2024", strval(new Date("5/4/2024 09:15:23")));
self::assertSame("05/04/2024", strval(new Date("5/4/2024 09:15")));
self::assertSame("05/04/2024", strval(new Date("5/4/2024 09h15")));
}
function testCompare() {
$a = new Date("10/02/2024");
$b = new Date("15/02/2024");
$c = new Date("20/02/2024");
$a2 = new Date("10/02/2024");
$b2 = new Date("15/02/2024");
$c2 = new Date("20/02/2024");
self::assertTrue($a == $a2);
self::assertFalse($a === $a2);
self::assertTrue($b == $b2);
self::assertTrue($c == $c2);
self::assertFalse($a < $a);
self::assertTrue($a < $b);
self::assertTrue($a < $c);
self::assertTrue($a <= $a);
self::assertTrue($a <= $b);
self::assertTrue($a <= $c);
self::assertFalse($c > $c);
self::assertTrue($c > $b);
self::assertTrue($c > $a);
self::assertTrue($c >= $c);
self::assertTrue($c >= $b);
self::assertTrue($c >= $a);
}
}

View File

@ -1,109 +0,0 @@
<?php
namespace nur\sery\php\time;
use DateTimeZone;
use nulib\tests\TestCase;
class DateTimeTest extends TestCase {
protected static function dt(string $datetime): DateTime {
return new DateTime($datetime, new DateTimeZone("Indian/Reunion"));
}
function testDateTime() {
$date = self::dt("2024-04-05 09:15:23");
self::assertEquals("05/04/2024 09:15:23", $date->format());
self::assertEquals("05/04/2024 09:15:23", strval($date));
self::assertSame(2024, $date->year);
self::assertSame(4, $date->month);
self::assertSame(5, $date->day);
self::assertSame(9, $date->hour);
self::assertSame(15, $date->minute);
self::assertSame(23, $date->second);
self::assertSame(5, $date->wday);
self::assertSame(14, $date->wnum);
self::assertEquals("+04:00", $date->timezone);
self::assertSame("05/04/2024 09:15:23", $date->datetime);
self::assertSame("05/04/2024", $date->date);
self::assertSame("20240405", $date->Ymd);
self::assertSame("20240405T091523", $date->YmdHMS);
self::assertSame("20240405T091523+04:00", $date->YmdHMSZ);
}
function testDateTimeZ() {
$date = new DateTime("20240405T091523Z");
self::assertSame("20240405T091523", $date->YmdHMS);
self::assertSame("20240405T091523Z", $date->YmdHMSZ);
}
function testClone() {
$date = self::dt("now");
$clone = DateTime::clone($date);
self::assertInstanceOf(DateTime::class, $clone);
}
function testConstruct() {
$y = date("Y");
self::assertSame("05/04/$y 00:00:00", strval(new DateTime("5/4")));
self::assertSame("05/04/2024 00:00:00", strval(new DateTime("5/4/24")));
self::assertSame("05/04/2024 00:00:00", strval(new DateTime("5/4/2024")));
self::assertSame("05/04/2024 00:00:00", strval(new DateTime("05/04/2024")));
self::assertSame("05/04/2024 00:00:00", strval(new DateTime("20240405")));
self::assertSame("05/04/2024 00:00:00", strval(new DateTime("240405")));
self::assertSame("05/04/2024 09:15:23", strval(new DateTime("20240405T091523")));
self::assertSame("05/04/2024 09:15:23", strval(new DateTime("20240405T091523Z")));
self::assertSame("05/04/2024 09:15:23", strval(new DateTime("5/4/2024 9:15:23")));
self::assertSame("05/04/2024 09:15:23", strval(new DateTime("5/4/2024 9.15.23")));
self::assertSame("05/04/2024 09:15:00", strval(new DateTime("5/4/2024 9:15")));
self::assertSame("05/04/2024 09:15:00", strval(new DateTime("5/4/2024 9.15")));
self::assertSame("05/04/2024 09:15:00", strval(new DateTime("5/4/2024 9h15")));
self::assertSame("05/04/2024 09:15:23", strval(new DateTime("5/4/2024 09:15:23")));
self::assertSame("05/04/2024 09:15:00", strval(new DateTime("5/4/2024 09:15")));
self::assertSame("05/04/2024 09:15:00", strval(new DateTime("5/4/2024 09h15")));
}
function testCompare() {
$a = new DateTime("10/02/2024");
$a2 = new DateTime("10/02/2024 8:30");
$a3 = new DateTime("10/02/2024 15:45");
$b = new DateTime("15/02/2024");
$b2 = new DateTime("15/02/2024 8:30");
$b3 = new DateTime("15/02/2024 15:45");
$x = new DateTime("10/02/2024");
$x2 = new DateTime("10/02/2024 8:30");
$x3 = new DateTime("10/02/2024 15:45");
self::assertTrue($a == $x);
self::assertFalse($a === $x);
self::assertTrue($a2 == $x2);
self::assertTrue($a3 == $x3);
self::assertFalse($a < $a);
self::assertTrue($a < $a2);
self::assertTrue($a < $a3);
self::assertTrue($a < $b);
self::assertTrue($a < $b2);
self::assertTrue($a < $b3);
self::assertTrue($a <= $a);
self::assertTrue($a <= $a2);
self::assertTrue($a <= $a3);
self::assertTrue($a <= $b);
self::assertTrue($a <= $b2);
self::assertTrue($a <= $b3);
self::assertTrue($b > $a);
self::assertTrue($b > $a2);
self::assertTrue($b > $a3);
self::assertFalse($b > $b);
self::assertFalse($b > $b2);
self::assertFalse($b > $b3);
self::assertTrue($b >= $a);
self::assertTrue($b >= $a2);
self::assertTrue($b >= $a3);
self::assertTrue($b >= $b);
self::assertFalse($b >= $b2);
self::assertFalse($b >= $b3);
}
}

View File

@ -1,83 +0,0 @@
<?php
namespace nur\sery\php\time;
use DateTimeZone;
use nulib\tests\TestCase;
class DelayTest extends TestCase {
protected static function dt(string $datetime): DateTime {
return new DateTime($datetime, new DateTimeZone("Indian/Reunion"));
}
function testDelay() {
$from = self::dt("2024-04-05 09:15:23");
$delay = new Delay(10, $from);
self::assertEquals(self::dt("2024-04-05 09:15:33"), $delay->getDest());
$delay = new Delay("10", $from);
self::assertEquals(self::dt("2024-04-05 09:15:33"), $delay->getDest());
$delay = new Delay("10s", $from);
self::assertEquals(self::dt("2024-04-05 09:15:33"), $delay->getDest());
$delay = new Delay("s", $from);
self::assertEquals(self::dt("2024-04-05 09:15:24"), $delay->getDest());
$delay = new Delay("5m", $from);
self::assertEquals(self::dt("2024-04-05 09:20:00"), $delay->getDest());
$delay = new Delay("5m0", $from);
self::assertEquals(self::dt("2024-04-05 09:20:00"), $delay->getDest());
$delay = new Delay("5m2", $from);
self::assertEquals(self::dt("2024-04-05 09:20:02"), $delay->getDest());
$delay = new Delay("m", $from);
self::assertEquals(self::dt("2024-04-05 09:16:00"), $delay->getDest());
$delay = new Delay("5h", $from);
self::assertEquals(self::dt("2024-04-05 14:00:00"), $delay->getDest());
$delay = new Delay("5h0", $from);
self::assertEquals(self::dt("2024-04-05 14:00:00"), $delay->getDest());
$delay = new Delay("5h2", $from);
self::assertEquals(self::dt("2024-04-05 14:02:00"), $delay->getDest());
$delay = new Delay("h", $from);
self::assertEquals(self::dt("2024-04-05 10:00:00"), $delay->getDest());
$delay = new Delay("5d", $from);
self::assertEquals(self::dt("2024-04-10 05:00:00"), $delay->getDest());
$delay = new Delay("5d2", $from);
self::assertEquals(self::dt("2024-04-10 02:00:00"), $delay->getDest());
$delay = new Delay("5d0", $from);
self::assertEquals(self::dt("2024-04-10 00:00:00"), $delay->getDest());
$delay = new Delay("d", $from);
self::assertEquals(self::dt("2024-04-06 05:00:00"), $delay->getDest());
$delay = new Delay("2w", $from);
self::assertEquals(self::dt("2024-04-21 05:00:00"), $delay->getDest());
$delay = new Delay("2w2", $from);
self::assertEquals(self::dt("2024-04-21 02:00:00"), $delay->getDest());
$delay = new Delay("2w0", $from);
self::assertEquals(self::dt("2024-04-21 00:00:00"), $delay->getDest());
$delay = new Delay("w", $from);
self::assertEquals(self::dt("2024-04-07 05:00:00"), $delay->getDest());
}
function testElapsed() {
$delay = new Delay(5);
sleep(2);
self::assertFalse($delay->isElapsed());
sleep(5);
self::assertTrue($delay->isElapsed());
}
}

View File

@ -1,28 +0,0 @@
<?php
namespace nur\sery;
use nulib\tests\TestCase;
class strTest extends TestCase {
function testCamel2us() {
self::assertSame("a", str::camel2us("a"));
self::assertSame("aa", str::camel2us("aa"));
self::assertSame("aaa", str::camel2us("aaa"));
self::assertSame("a", str::camel2us("A"));
self::assertSame("aa", str::camel2us("Aa"));
self::assertSame("aa", str::camel2us("AA"));
self::assertSame("aaa", str::camel2us("Aaa"));
self::assertSame("aaa", str::camel2us("AAA"));
self::assertSame("a_aa", str::camel2us("AAa"));
self::assertSame("a_b", str::camel2us("aB"));
self::assertSame("aa_bb", str::camel2us("aaBb"));
self::assertSame("aaa_bbb", str::camel2us("aaaBbb"));
self::assertSame("aa_bb", str::camel2us("AaBb"));
self::assertSame("aaa_bbb", str::camel2us("AaaBbb"));
self::assertSame("_aaa", str::camel2us("_aaa"));
self::assertSame("__aaa_bbb", str::camel2us("__aaaBbb"));
self::assertSame("___aaa_bbb", str::camel2us("___AaaBbb"));
}
}

View File

@ -1,200 +0,0 @@
<?php
namespace nur\sery\web;
use PHPUnit\Framework\TestCase;
class uploadsTest extends TestCase {
const _FILES = [
# name="simple"
'simple' => [
'name' => '',
'type' => '',
'tmp_name' => '',
'error' => 4,
'size' => 0,
],
# name=multiple[], name=multiple[]
'multiple' => [
'name' => [
0 => '',
1 => '',
],
'type' => [
0 => '',
1 => '',
],
'tmp_name' => [
0 => '',
1 => '',
],
'error' => [
0 => 4,
1 => 4,
],
'size' => [
0 => 0,
1 => 0,
],
],
# name=onelevel[a], name=onelevel[b]
'onelevel' => [
'name' => [
'a' => '',
'b' => '',
],
'type' => [
'a' => '',
'b' => '',
],
'tmp_name' => [
'a' => '',
'b' => '',
],
'error' => [
'a' => 4,
'b' => 4,
],
'size' => [
'a' => 0,
'b' => 0,
],
],
# name=multiplelevel[a][], name=multiplelevel[a][], name=multiplelevel[b][], name=multiplelevel[b][]
'multiplelevel' => [
'name' => [
'a' => [
0 => '',
1 => '',
],
'b' => [
0 => '',
1 => '',
],
],
'type' => [
'a' => [
0 => '',
1 => '',
],
'b' => [
0 => '',
1 => '',
],
],
'tmp_name' => [
'a' => [
0 => '',
1 => '',
],
'b' => [
0 => '',
1 => '',
],
],
'error' => [
'a' => [
0 => 4,
1 => 4,
],
'b' => [
0 => 4,
1 => 4,
],
],
'size' => [
'a' => [
0 => 0,
1 => 0,
],
'b' => [
0 => 0,
1 => 0,
],
],
],
];
const PARSED = [
# name="simple"
'simple' => [
'name' => '',
'type' => '',
'tmp_name' => '',
'error' => 4,
'size' => 0,
],
# name=multiple[], name=multiple[]
'multiple' => [
0 => [
'name' => '',
'type' => '',
'tmp_name' => '',
'error' => 4,
'size' => 0,
],
1 => [
'name' => '',
'type' => '',
'tmp_name' => '',
'error' => 4,
'size' => 0,
],
],
# name=onelevel[a], name=onelevel[b]
'onelevel' => [
'a' => [
'name' => '',
'type' => '',
'tmp_name' => '',
'error' => 4,
'size' => 0,
],
'b' => [
'name' => '',
'type' => '',
'tmp_name' => '',
'error' => 4,
'size' => 0,
],
],
# name=multiplelevel[a][], name=multiplelevel[a][], name=multiplelevel[b][], name=multiplelevel[b][]
'multiplelevel' => [
'a' => [
0 => [
'name' => '',
'type' => '',
'tmp_name' => '',
'error' => 4,
'size' => 0,
],
1 => [
'name' => '',
'type' => '',
'tmp_name' => '',
'error' => 4,
'size' => 0,
],
],
'b' => [
0 => [
'name' => '',
'type' => '',
'tmp_name' => '',
'error' => 4,
'size' => 0,
],
1 => [
'name' => '',
'type' => '',
'tmp_name' => '',
'error' => 4,
'size' => 0,
],
],
],
];
function test_files() {
self::assertSame(self::PARSED, uploads::_files(self::_FILES));
}
}

View File

@ -1,8 +1,7 @@
<?php
namespace nur\sery\php\access;
namespace nur\sery\wip\php\access;
use nulib\tests\TestCase;
use nur\sery\wip\php\access\KeyAccess;
use stdClass;
class KeyAccessTest extends TestCase {

View File

@ -1,8 +1,7 @@
<?php
namespace nur\sery\php\access;
namespace nur\sery\wip\php\access;
use nulib\tests\TestCase;
use nur\sery\wip\php\access\ValueAccess;
use stdClass;
class ValueAccessTest extends TestCase {

View File

@ -1,7 +1,8 @@
<?php
namespace nur\sery\php\content;
namespace nur\sery\wip\php\content;
use nur\sery\php\content\impl\html;
use nulib\php\content\c;
use nur\sery\wip\php\content\impl\html;
use nur\sery\wip\web\content\v;
use PHPUnit\Framework\TestCase;

View File

@ -1,7 +1,7 @@
<?php
namespace nur\sery\php\content\impl;
namespace nur\sery\wip\php\content\impl;
use nur\sery\php\content\IContent;
use nulib\php\content\IContent;
class AContent implements IContent {
function getContent(): iterable {

View File

@ -1,7 +1,7 @@
<?php
namespace nur\sery\php\content\impl;
namespace nur\sery\wip\php\content\impl;
use nur\sery\php\content\IPrintable;
use nulib\php\content\IPrintable;
class APrintable implements IPrintable {
function print(): void {

View File

@ -1,8 +1,8 @@
<?php
namespace nur\sery\php\content\impl;
namespace nur\sery\wip\php\content\impl;
use nur\sery\php\content\c;
use nur\sery\php\content\IContent;
use nulib\php\content\c;
use nulib\php\content\IContent;
class ATag implements IContent {
function __construct(string $tag, $content=null) {

View File

@ -1,5 +1,5 @@
<?php
namespace nur\sery\php\content\impl;
namespace nur\sery\wip\php\content\impl;
class html {
const H1 = [self::class, "h1"];

View File

@ -1,8 +1,7 @@
<?php
namespace nur\sery\schema\_scalar;
namespace nur\sery\wip\schema\_scalar;
use nulib\tests\TestCase;
use nur\sery\wip\schema\_scalar\ScalarSchema;
use nur\sery\wip\schema\SchemaException;
class ScalarSchemaTest extends TestCase {
@ -21,6 +20,7 @@ class ScalarSchemaTest extends TestCase {
"formatter_func" => null,
"format" => null,
"" => ["scalar"],
"schema" => null,
"name" => null,
"pkey" => null,
"header" => null,

View File

@ -1,10 +1,10 @@
<?php
namespace nur\sery\schema\types;
namespace nur\sery\wip\schema\types;
use Exception;
use nulib\tests\TestCase;
use nur\sery\schema\_scalar\ScalarValue;
use nur\sery\schema\Schema;
use nur\sery\wip\schema\_scalar\ScalarValue;
use nur\sery\wip\schema\Schema;
class boolTest extends TestCase {
function commonTests($destv, &$dest, callable $destvSetter): void {

View File

@ -1,10 +1,10 @@
<?php
namespace nur\sery\schema\types;
namespace nur\sery\wip\schema\types;
use Exception;
use nulib\tests\TestCase;
use nur\sery\schema\_scalar\ScalarValue;
use nur\sery\schema\Schema;
use nur\sery\wip\schema\_scalar\ScalarValue;
use nur\sery\wip\schema\Schema;
class floatTest extends TestCase {
function commonTests($destv, &$dest, callable $destvSetter): void {

View File

@ -1,10 +1,10 @@
<?php
namespace nur\sery\schema\types;
namespace nur\sery\wip\schema\types;
use Exception;
use nulib\tests\TestCase;
use nur\sery\schema\_scalar\ScalarValue;
use nur\sery\schema\Schema;
use nur\sery\wip\schema\_scalar\ScalarValue;
use nur\sery\wip\schema\Schema;
class intTest extends TestCase {
function commonTests($destv, &$dest, callable $destvSetter): void {

View File

@ -1,5 +1,5 @@
<?php
namespace nur\sery\schema\types;
namespace nur\sery\wip\schema\types;
use Exception;
use nulib\tests\TestCase;

View File

@ -1,9 +1,9 @@
<?php
namespace nur\sery\schema\types;
namespace nur\sery\wip\schema\types;
use nulib\tests\TestCase;
use nur\sery\schema\_scalar\ScalarValue;
use nur\sery\schema\Schema;
use nur\sery\wip\schema\_scalar\ScalarValue;
use nur\sery\wip\schema\Schema;
class unionTest extends TestCase {
function testUnionTypes() {