mirror of
https://github.com/Karaka-Management/phpOMS.git
synced 2026-01-18 12:48:41 +00:00
test fixes and added more tests
This commit is contained in:
parent
2cf30d1073
commit
002112fca4
|
|
@ -205,7 +205,7 @@ final class BasicOcr
|
|||
foreach ($candidateLabels as $i => $label) {
|
||||
$predictedLabels[] = [
|
||||
'label' => $label,
|
||||
'prob' => $countedCandidates[$candidateLabels[$i]] / $k,
|
||||
'prob' => $countedCandidates[$label] / $k,
|
||||
];
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -97,7 +97,7 @@ class MazeGenerator
|
|||
$pos = \array_pop($path);
|
||||
|
||||
if ($pos === null) {
|
||||
break;
|
||||
break; // @codeCoverageIgnore
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -64,14 +64,16 @@ final class CycleSort implements SortInterface
|
|||
++$pos;
|
||||
}
|
||||
|
||||
$old = $list[$pos];
|
||||
$list[$pos] = $item;
|
||||
$item = $old;
|
||||
if ($pos !== $start) {
|
||||
$old = $list[$pos];
|
||||
$list[$pos] = $item;
|
||||
$item = $old;
|
||||
}
|
||||
|
||||
while ($pos !== $start) {
|
||||
$pos = $start;
|
||||
$length1 = \count($list);
|
||||
for ($i = $start + 1; $i < $length1; ++$i) {
|
||||
$pos = $start;
|
||||
|
||||
for ($i = $start + 1; $i < $n; ++$i) {
|
||||
if (!$list[$i]->compare($item, $order)) {
|
||||
++$pos;
|
||||
}
|
||||
|
|
@ -81,9 +83,11 @@ final class CycleSort implements SortInterface
|
|||
++$pos;
|
||||
}
|
||||
|
||||
$old = $list[$pos];
|
||||
$list[$pos] = $item;
|
||||
$item = $old;
|
||||
if (!$item->equals($list[$pos])) {
|
||||
$old = $list[$pos];
|
||||
$list[$pos] = $item;
|
||||
$item = $old;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -67,7 +67,7 @@ final class QuickSort implements SortInterface
|
|||
{
|
||||
if ($lo < $hi) {
|
||||
$i = self::partition($list, $lo, $hi, $order);
|
||||
self::qsort($list, $lo, $i, $order);
|
||||
self::qsort($list, $lo, $i - 1, $order);
|
||||
self::qsort($list, $i + 1, $hi, $order);
|
||||
}
|
||||
}
|
||||
|
|
@ -86,26 +86,22 @@ final class QuickSort implements SortInterface
|
|||
*/
|
||||
private static function partition(array &$list, int $lo, int $hi, int $order) : int
|
||||
{
|
||||
$pivot = $list[$lo + ((int) (($hi - $lo) / 2))];
|
||||
while (true) {
|
||||
while (!$list[$lo]->compare($pivot, $order)) {
|
||||
++$lo;
|
||||
$pivot = $list[$hi];
|
||||
$i = $lo - 1;
|
||||
|
||||
for ($j = $lo; $j <= $hi - 1; ++$j) {
|
||||
if (!$list[$j]->compare($pivot, $order)) {
|
||||
++$i;
|
||||
$old = $list[$i];
|
||||
$list[$i] = $list[$j];
|
||||
$list[$j] = $old;
|
||||
}
|
||||
|
||||
while ($list[$hi]->compare($pivot, $order)) {
|
||||
--$hi;
|
||||
}
|
||||
|
||||
if ($lo >= $hi) {
|
||||
return $hi;
|
||||
}
|
||||
|
||||
$old = $list[$lo];
|
||||
$list[$lo] = $list[$hi];
|
||||
$list[$hi] = $old;
|
||||
|
||||
++$lo;
|
||||
--$hi;
|
||||
}
|
||||
|
||||
$old = $list[$i + 1];
|
||||
$list[$i + 1] = $list[$hi];
|
||||
$list[$hi] = $old;
|
||||
|
||||
return $i + 1;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -98,11 +98,7 @@ final class ApplicationManager
|
|||
$destination = \rtrim($destination, '\\/');
|
||||
$source = \rtrim($source, '/\\');
|
||||
|
||||
if (!\is_dir($source) || \is_dir($destination)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!\is_file($source . '/Admin/Installer.php')) {
|
||||
if (!\is_dir($source) || \is_dir($destination) || !\is_file($source . '/Admin/Installer.php')) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
@ -124,6 +120,73 @@ final class ApplicationManager
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Uninstall the application
|
||||
*
|
||||
* @param string $source Source of the application
|
||||
*
|
||||
* @return bool
|
||||
*
|
||||
* @since 1.0.0
|
||||
*/
|
||||
public function uninstall(string $source) : bool
|
||||
{
|
||||
$source = \rtrim($source, '/\\');
|
||||
if (!\is_dir($source) || !\is_file($source . '/Admin/Uninstaller.php')) {
|
||||
return false;
|
||||
}
|
||||
|
||||
try {
|
||||
$info = $this->loadInfo($source . '/info.json');
|
||||
$this->installed[$info->getInternalName()] = $info;
|
||||
|
||||
$classPath = \substr(\realpath($source) . '/Admin/Uninstaller', $t = \strlen(\realpath(__DIR__ . '/../../')));
|
||||
|
||||
$class = \str_replace('/', '\\', $classPath);
|
||||
$class::uninstall($this->app->dbPool, $info, $this->app->appSettings);
|
||||
|
||||
$this->uninstallFiles($source);
|
||||
|
||||
return true;
|
||||
} catch (\Throwable $t) {
|
||||
return false; // @codeCoverageIgnore
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Re-init application.
|
||||
*
|
||||
* @param string $appPath App path
|
||||
*
|
||||
* @return void
|
||||
*
|
||||
* @throws InvalidModuleException Throws this exception in case the installer doesn't exist
|
||||
*
|
||||
* @since 1.0.0
|
||||
*/
|
||||
public function reInit(string $appPath) : void
|
||||
{
|
||||
$info = $this->loadInfo($appPath . '/info.json');
|
||||
if ($info === null) {
|
||||
return;
|
||||
}
|
||||
|
||||
$classPath = \substr(\realpath($appPath) . '/Admin/Installer', \strlen(\realpath(__DIR__ . '/../../')));
|
||||
$class = \str_replace('/', '\\', $classPath);
|
||||
|
||||
/** @var $class InstallerAbstract */
|
||||
$class::reInit($info);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all applications who are providing for a specific module.
|
||||
*
|
||||
* @param string $module Module to check providings for
|
||||
*
|
||||
* @return array<string, string[]>
|
||||
*
|
||||
* @since 1.0.0
|
||||
*/
|
||||
public function getProvidingForModule(string $module) : array
|
||||
{
|
||||
$providing = [];
|
||||
|
|
@ -189,6 +252,20 @@ final class ApplicationManager
|
|||
Directory::copy($source, $destination);
|
||||
}
|
||||
|
||||
/**
|
||||
* Uninstall files
|
||||
*
|
||||
* @param string $source Source path
|
||||
*
|
||||
* @return void
|
||||
*
|
||||
* @since 1.0.0
|
||||
*/
|
||||
private function uninstallFiles(string $source) : void
|
||||
{
|
||||
Directory::delete($source);
|
||||
}
|
||||
|
||||
/**
|
||||
* Replace placeholder string (application placeholder name)
|
||||
*
|
||||
|
|
|
|||
|
|
@ -143,6 +143,10 @@ abstract class InstallerAbstract
|
|||
$classPath = \substr(\realpath(static::PATH) . '/Status', \strlen(\realpath(__DIR__ . '/../../')));
|
||||
|
||||
$class = \str_replace('/', '\\', $classPath);
|
||||
|
||||
$class::clearRoutes();
|
||||
$class::clearHooks();
|
||||
|
||||
$class::activateRoutes($info);
|
||||
$class::activateHooks($info);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -63,7 +63,7 @@ abstract class StatusAbstract
|
|||
*/
|
||||
public static function activateRoutes(ApplicationInfo $appInfo = null) : void
|
||||
{
|
||||
self::installRoutes(static::PATH . '/../Routes.php', static::PATH . '/../Admin/Install/Application/Routes.php');
|
||||
self::installRoutesHooks(static::PATH . '/../Routes.php', static::PATH . '/../Admin/Install/Application/Routes.php');
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -79,7 +79,7 @@ abstract class StatusAbstract
|
|||
*/
|
||||
public static function activateHooks(ApplicationInfo $appInfo = null) : void
|
||||
{
|
||||
self::installRoutes(static::PATH . '/../Hooks.php', static::PATH . '/../Admin/Install/Application/Hooks.php');
|
||||
self::installRoutesHooks(static::PATH . '/../Hooks.php', static::PATH . '/../Admin/Install/Application/Hooks.php');
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -94,7 +94,7 @@ abstract class StatusAbstract
|
|||
*
|
||||
* @since 1.0.0
|
||||
*/
|
||||
protected static function installRoutes(string $destRoutePath, string $srcRoutePath) : void
|
||||
protected static function installRoutesHooks(string $destRoutePath, string $srcRoutePath) : void
|
||||
{
|
||||
if (!\is_file($destRoutePath)) {
|
||||
\file_put_contents($destRoutePath, '<?php return [];');
|
||||
|
|
@ -115,175 +115,40 @@ abstract class StatusAbstract
|
|||
/** @noinspection PhpIncludeInspection */
|
||||
$appRoutes = include $destRoutePath;
|
||||
/** @noinspection PhpIncludeInspection */
|
||||
$moduleRoutes = include $srcRoutePath;
|
||||
$srcRoutes = include $srcRoutePath;
|
||||
|
||||
$appRoutes = \array_merge_recursive($appRoutes, $moduleRoutes);
|
||||
$appRoutes = \array_merge_recursive($appRoutes, $srcRoutes);
|
||||
|
||||
\file_put_contents($destRoutePath, '<?php return ' . ArrayParser::serializeArray($appRoutes) . ';', \LOCK_EX);
|
||||
}
|
||||
|
||||
/**
|
||||
* Install hooks.
|
||||
*
|
||||
* @param string $destHookPath Destination hook path
|
||||
* @param string $srcHookPath Source hook path
|
||||
*
|
||||
* @return void
|
||||
*
|
||||
* @throws PathException This exception is thrown if the hook file doesn't exist
|
||||
* @throws PermissionException This exception is thrown if the hook file couldn't be updated (no write permission)
|
||||
*
|
||||
* @since 1.0.0
|
||||
*/
|
||||
protected static function installHooks(string $destHookPath, string $srcHookPath) : void
|
||||
{
|
||||
if (!\is_file($destHookPath)) {
|
||||
\file_put_contents($destHookPath, '<?php return [];');
|
||||
}
|
||||
|
||||
if (!\is_file($srcHookPath)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!\is_file($destHookPath)) {
|
||||
throw new PathException($destHookPath);
|
||||
}
|
||||
|
||||
if (!\is_writable($destHookPath)) {
|
||||
throw new PermissionException($destHookPath);
|
||||
}
|
||||
|
||||
/** @noinspection PhpIncludeInspection */
|
||||
$appHooks = include $destHookPath;
|
||||
/** @noinspection PhpIncludeInspection */
|
||||
$moduleHooks = include $srcHookPath;
|
||||
|
||||
$appHooks = \array_merge_recursive($appHooks, $moduleHooks);
|
||||
|
||||
\file_put_contents($destHookPath, '<?php return ' . ArrayParser::serializeArray($appHooks) . ';', \LOCK_EX);
|
||||
}
|
||||
|
||||
/**
|
||||
* Deactivate routes.
|
||||
*
|
||||
* @param ApplicationInfo $appInfo Application info
|
||||
* Clear all routes.
|
||||
*
|
||||
* @return void
|
||||
*
|
||||
* @throws PathException
|
||||
* @throws PermissionException
|
||||
*
|
||||
* @since 1.0.0
|
||||
*/
|
||||
public static function deactivateRoutes(ApplicationInfo $appInfo) : void
|
||||
public static function clearRoutes() : void
|
||||
{
|
||||
self::installRoutes(static::PATH . '/../Routes.php', static::PATH . '/../Admin/Install/Application/Routes.php');
|
||||
\file_put_contents(static::PATH . '/../Routes.php', '<?php return [];', \LOCK_EX);
|
||||
}
|
||||
|
||||
/**
|
||||
* Deactivate hooks.
|
||||
*
|
||||
* @param ApplicationInfo $appInfo Application info
|
||||
* Clear all hooks.
|
||||
*
|
||||
* @return void
|
||||
*
|
||||
* @throws PathException
|
||||
* @throws PermissionException
|
||||
*
|
||||
* @since 1.0.0
|
||||
*/
|
||||
public static function deactivateHooks(ApplicationInfo $appInfo) : void
|
||||
public static function clearHooks() : void
|
||||
{
|
||||
self::installRoutes(static::PATH . '/../Hooks.php', static::PATH . '/../Admin/Install/Application/Hooks.php');
|
||||
}
|
||||
|
||||
/**
|
||||
* Uninstall routes.
|
||||
*
|
||||
* @param string $destRoutePath Destination route path
|
||||
* @param string $srcRoutePath Source route path
|
||||
*
|
||||
* @return void
|
||||
*
|
||||
* @throws PermissionException
|
||||
*
|
||||
* @since 1.0.0
|
||||
*/
|
||||
public static function uninstallRoutes(string $destRoutePath, string $srcRoutePath) : void
|
||||
{
|
||||
if (!\is_file($destRoutePath)
|
||||
|| !\is_file($srcRoutePath)
|
||||
) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!\is_file($destRoutePath)) {
|
||||
throw new PathException($destRoutePath);
|
||||
}
|
||||
|
||||
if (!\is_writable($destRoutePath)) {
|
||||
throw new PermissionException($destRoutePath);
|
||||
}
|
||||
|
||||
/** @noinspection PhpIncludeInspection */
|
||||
$appRoutes = include $destRoutePath;
|
||||
/** @noinspection PhpIncludeInspection */
|
||||
$moduleRoutes = include $srcRoutePath;
|
||||
|
||||
$appRoutes = ArrayUtils::array_diff_assoc_recursive($appRoutes, $moduleRoutes);
|
||||
|
||||
\file_put_contents($destRoutePath, '<?php return ' . ArrayParser::serializeArray($appRoutes) . ';', \LOCK_EX);
|
||||
}
|
||||
|
||||
/**
|
||||
* Uninstall hooks.
|
||||
*
|
||||
* @param string $destHookPath Destination hook path
|
||||
* @param string $srcHookPath Source hook path
|
||||
*
|
||||
* @return void
|
||||
*
|
||||
* @throws PermissionException
|
||||
*
|
||||
* @since 1.0.0
|
||||
*/
|
||||
protected static function uninstallHooks(string $destHookPath, string $srcHookPath) : void
|
||||
{
|
||||
if (!\is_file($destHookPath)
|
||||
|| !\is_file($srcHookPath)
|
||||
) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!\is_file($destHookPath)) {
|
||||
throw new PathException($destHookPath);
|
||||
}
|
||||
|
||||
if (!\is_writable($destHookPath)) {
|
||||
throw new PermissionException($destHookPath);
|
||||
}
|
||||
|
||||
/** @noinspection PhpIncludeInspection */
|
||||
$appHooks = include $destHookPath;
|
||||
/** @noinspection PhpIncludeInspection */
|
||||
$moduleHooks = include $srcHookPath;
|
||||
|
||||
$appHooks = ArrayUtils::array_diff_assoc_recursive($appHooks, $moduleHooks);
|
||||
|
||||
\file_put_contents($destHookPath, '<?php return ' . ArrayParser::serializeArray($appHooks) . ';', \LOCK_EX);
|
||||
}
|
||||
|
||||
/**
|
||||
* Deactivate app.
|
||||
*
|
||||
* @param DatabasePool $dbPool Database instance
|
||||
* @param ApplicationInfo $info Module info
|
||||
*
|
||||
* @return void
|
||||
*
|
||||
* @since 1.0.0
|
||||
*/
|
||||
public static function deactivate(DatabasePool $dbPool, ApplicationInfo $info) : void
|
||||
{
|
||||
self::deactivateRoutes($info);
|
||||
self::deactivateHooks($info);
|
||||
\file_put_contents(static::PATH . '/../Hooks.php', '<?php return [];', \LOCK_EX);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -40,7 +40,7 @@ abstract class UninstallerAbstract
|
|||
*/
|
||||
public static function uninstall(DatabasePool $dbPool, ApplicationInfo $info) : void
|
||||
{
|
||||
self::deactivate($dbPool, $info);
|
||||
//self::deactivate($dbPool, $info);
|
||||
self::dropTables($dbPool, $info);
|
||||
self::unregisterFromDatabase($dbPool, $info);
|
||||
}
|
||||
|
|
@ -55,12 +55,14 @@ abstract class UninstallerAbstract
|
|||
*
|
||||
* @since 1.0.0
|
||||
*/
|
||||
/*
|
||||
protected static function deactivate(DatabasePool $dbPool, ApplicationInfo $info) : void
|
||||
{
|
||||
/** @var StatusAbstract $class */
|
||||
$class = '\Web\\' . $info->getInternalName() . '\Admin\Status';
|
||||
$classPath = \substr(\realpath(static::PATH) . '/Status', \strlen(\realpath(__DIR__ . '/../../')));
|
||||
|
||||
$class = \str_replace('/', '\\', $classPath);
|
||||
$class::deactivate($dbPool, $info);
|
||||
}
|
||||
}*/
|
||||
|
||||
/**
|
||||
* Drop tables of app.
|
||||
|
|
@ -74,8 +76,7 @@ abstract class UninstallerAbstract
|
|||
*/
|
||||
public static function dropTables(DatabasePool $dbPool, ApplicationInfo $info) : void
|
||||
{
|
||||
$path = __DIR__ . '/../../Web/' . $info->getInternalName() . '/Admin/Install/db.json';
|
||||
|
||||
$path = static::PATH . '/Install/db.json';
|
||||
if (!\is_file($path)) {
|
||||
return;
|
||||
}
|
||||
|
|
@ -88,8 +89,8 @@ abstract class UninstallerAbstract
|
|||
$definitions = \json_decode($content, true);
|
||||
$builder = new SchemaBuilder($dbPool->get('schema'));
|
||||
|
||||
foreach ($definitions as $definition) {
|
||||
$builder->dropTable($definition['table'] ?? '');
|
||||
foreach ($definitions as $name => $definition) {
|
||||
$builder->dropTable($name ?? '');
|
||||
}
|
||||
|
||||
$builder->execute();
|
||||
|
|
|
|||
|
|
@ -27,7 +27,7 @@ final class CustomerValue
|
|||
/**
|
||||
* Simple customer lifetime value
|
||||
*
|
||||
* Hazard Model, same as $margin * (1 + $discountRate) / (1 + $discountRate - $retentionRate)
|
||||
* Hazard Model
|
||||
*
|
||||
* @param float $margin Margin per period (or revenue/sales)
|
||||
* @param float $retentionRate Rate of remaining customers per period (= average lifetime / (1 + average lifetime))
|
||||
|
|
@ -42,32 +42,6 @@ final class CustomerValue
|
|||
return $margin * $retentionRate / (1 + $discountRate - $retentionRate);
|
||||
}
|
||||
|
||||
/**
|
||||
* Basic customer lifetime value
|
||||
*
|
||||
* Hazard Model, same as $margin * (1 + $discountRate) / (1 + $discountRate - $retentionRate)
|
||||
*
|
||||
* @param array $margins Margin per period (or revenue/sales)
|
||||
* @param float $retentionRate Rate of remaining customers per period (= average lifetime / (1 + average lifetime))
|
||||
* @param float $discountRate Cost of capital to discount future revenue
|
||||
*
|
||||
* @return float
|
||||
*
|
||||
* @since 1.0.0
|
||||
*/
|
||||
public static function getBasicCLV(array $margins, float $retentionRate, float $discountRate) : float
|
||||
{
|
||||
$clv = 0.0;
|
||||
$c = 1;
|
||||
foreach ($margins as $margin) {
|
||||
$clv += ($retentionRate ** $c) * $margin * \pow(1 / (1 + $discountRate), $c);
|
||||
|
||||
++$c;
|
||||
}
|
||||
|
||||
return $clv;
|
||||
}
|
||||
|
||||
/**
|
||||
* Normalized measure of recurring revenue
|
||||
*
|
||||
|
|
|
|||
|
|
@ -90,26 +90,12 @@ final class Metrics
|
|||
return $rc * (1 - \exp(-$r * $t));
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculate the average lifetime duration
|
||||
*
|
||||
* @param array $retainedCustomers Retained customers per period
|
||||
*
|
||||
* @return float
|
||||
*
|
||||
* @since 1.0.0
|
||||
*/
|
||||
public static function averageLifetimeDuration(array $retainedCustomers) : float
|
||||
{
|
||||
return \array_sum($retainedCustomers) / \count($retainedCustomers);
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculate the probability of a customer being active
|
||||
*
|
||||
* @param int $purchases Number of purchases during the periods
|
||||
* @param int $periods Number of periods (e.g. number of months)
|
||||
* @param int $lastPurchase In which period was the last purchase
|
||||
* @param int $lastPurchase In which period was the last purchase (lastPurchase = periods: means customer purchased in this period)
|
||||
*
|
||||
* @return float
|
||||
*
|
||||
|
|
|
|||
|
|
@ -45,11 +45,11 @@ interface ConnectionInterface extends DataStorageConnectionInterface
|
|||
* @param int|string $key Unique cache key
|
||||
* @param int $value By value
|
||||
*
|
||||
* @return void
|
||||
* @return bool
|
||||
*
|
||||
* @since 1.0.0
|
||||
*/
|
||||
public function increment(int | string $key, int $value = 1) : void;
|
||||
public function increment(int | string $key, int $value = 1) : bool;
|
||||
|
||||
/**
|
||||
* Decrement value.
|
||||
|
|
@ -57,11 +57,11 @@ interface ConnectionInterface extends DataStorageConnectionInterface
|
|||
* @param int|string $key Unique cache key
|
||||
* @param int $value By value
|
||||
*
|
||||
* @return void
|
||||
* @return bool
|
||||
*
|
||||
* @since 1.0.0
|
||||
*/
|
||||
public function decrement(int | string $key, int $value = 1) : void;
|
||||
public function decrement(int | string $key, int $value = 1) : bool;
|
||||
|
||||
/**
|
||||
* Rename cache key.
|
||||
|
|
|
|||
|
|
@ -238,7 +238,7 @@ final class FileCache extends ConnectionAbstract
|
|||
return '';
|
||||
}
|
||||
|
||||
throw new InvalidEnumValue($type);
|
||||
throw new InvalidEnumValue($type); // @codeCoverageIgnore
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -281,7 +281,7 @@ final class FileCache extends ConnectionAbstract
|
|||
|
||||
$raw = \file_get_contents($path);
|
||||
if ($raw === false) {
|
||||
return null;
|
||||
return null; // @codeCoverageIgnore
|
||||
}
|
||||
|
||||
$type = (int) $raw[0];
|
||||
|
|
@ -289,7 +289,7 @@ final class FileCache extends ConnectionAbstract
|
|||
$expireEnd = (int) \strpos($raw, self::DELIM, $expireStart + 1);
|
||||
|
||||
if ($expireStart < 0 || $expireEnd < 0) {
|
||||
return null;
|
||||
return null; // @codeCoverageIgnore
|
||||
}
|
||||
|
||||
$cacheExpire = \substr($raw, $expireStart + 1, $expireEnd - ($expireStart + 1));
|
||||
|
|
@ -337,7 +337,7 @@ final class FileCache extends ConnectionAbstract
|
|||
$namespace = \substr($raw, $namespaceStart + 1, $namespaceEnd - $namespaceStart - 1);
|
||||
|
||||
if ($namespace === false) {
|
||||
return null;
|
||||
return null; // @codeCoverageIgnore
|
||||
}
|
||||
|
||||
return new $namespace();
|
||||
|
|
@ -347,7 +347,7 @@ final class FileCache extends ConnectionAbstract
|
|||
$namespace = \substr($raw, $namespaceStart + 1, $namespaceEnd - $namespaceStart - 1);
|
||||
|
||||
if ($namespace === false) {
|
||||
return null;
|
||||
return null; // @codeCoverageIgnore
|
||||
}
|
||||
|
||||
$obj = new $namespace();
|
||||
|
|
@ -385,7 +385,7 @@ final class FileCache extends ConnectionAbstract
|
|||
$raw = \file_get_contents($path);
|
||||
|
||||
if ($raw === false) {
|
||||
return false;
|
||||
return false; // @codeCoverageIgnore
|
||||
}
|
||||
|
||||
$cacheExpire = $this->getExpire($raw);
|
||||
|
|
@ -426,7 +426,7 @@ final class FileCache extends ConnectionAbstract
|
|||
|
||||
$raw = \file_get_contents($path);
|
||||
if ($raw === false) {
|
||||
return false;
|
||||
return false; // @codeCoverageIgnore
|
||||
}
|
||||
|
||||
$type = (int) $raw[0];
|
||||
|
|
@ -434,7 +434,7 @@ final class FileCache extends ConnectionAbstract
|
|||
$expireEnd = (int) \strpos($raw, self::DELIM, $expireStart + 1);
|
||||
|
||||
if ($expireStart < 0 || $expireEnd < 0) {
|
||||
return false;
|
||||
return false; // @codeCoverageIgnore
|
||||
}
|
||||
|
||||
$cacheExpire = \substr($raw, $expireStart + 1, $expireEnd - ($expireStart + 1));
|
||||
|
|
@ -452,11 +452,11 @@ final class FileCache extends ConnectionAbstract
|
|||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function increment(int | string $key, int $value = 1) : void
|
||||
public function increment(int | string $key, int $value = 1) : bool
|
||||
{
|
||||
$path = $this->getPath($key);
|
||||
if (!File::exists($path)) {
|
||||
return;
|
||||
return false;
|
||||
}
|
||||
|
||||
$created = File::created($path)->getTimestamp();
|
||||
|
|
@ -464,7 +464,7 @@ final class FileCache extends ConnectionAbstract
|
|||
|
||||
$raw = \file_get_contents($path);
|
||||
if ($raw === false) {
|
||||
return;
|
||||
return false; // @codeCoverageIgnore
|
||||
}
|
||||
|
||||
$type = (int) $raw[0];
|
||||
|
|
@ -472,7 +472,7 @@ final class FileCache extends ConnectionAbstract
|
|||
$expireEnd = (int) \strpos($raw, self::DELIM, $expireStart + 1);
|
||||
|
||||
if ($expireStart < 0 || $expireEnd < 0) {
|
||||
return;
|
||||
return false; // @codeCoverageIgnore
|
||||
}
|
||||
|
||||
$cacheExpire = \substr($raw, $expireStart + 1, $expireEnd - ($expireStart + 1));
|
||||
|
|
@ -480,16 +480,18 @@ final class FileCache extends ConnectionAbstract
|
|||
|
||||
$val = $this->reverseValue($type, $raw, $expireEnd);
|
||||
$this->set($key, $val + $value, $cacheExpire);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function decrement(int | string $key, int $value = 1) : void
|
||||
public function decrement(int | string $key, int $value = 1) : bool
|
||||
{
|
||||
$path = $this->getPath($key);
|
||||
if (!File::exists($path)) {
|
||||
return;
|
||||
return false;
|
||||
}
|
||||
|
||||
$created = File::created($path)->getTimestamp();
|
||||
|
|
@ -497,7 +499,7 @@ final class FileCache extends ConnectionAbstract
|
|||
|
||||
$raw = \file_get_contents($path);
|
||||
if ($raw === false) {
|
||||
return;
|
||||
return false; // @codeCoverageIgnore
|
||||
}
|
||||
|
||||
$type = (int) $raw[0];
|
||||
|
|
@ -505,7 +507,7 @@ final class FileCache extends ConnectionAbstract
|
|||
$expireEnd = (int) \strpos($raw, self::DELIM, $expireStart + 1);
|
||||
|
||||
if ($expireStart < 0 || $expireEnd < 0) {
|
||||
return;
|
||||
return false; // @codeCoverageIgnore
|
||||
}
|
||||
|
||||
$cacheExpire = \substr($raw, $expireStart + 1, $expireEnd - ($expireStart + 1));
|
||||
|
|
@ -513,6 +515,8 @@ final class FileCache extends ConnectionAbstract
|
|||
|
||||
$val = $this->reverseValue($type, $raw, $expireEnd);
|
||||
$this->set($key, $val - $value, $cacheExpire);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -548,7 +552,7 @@ final class FileCache extends ConnectionAbstract
|
|||
|
||||
$raw = \file_get_contents($path);
|
||||
if ($raw === false) {
|
||||
continue;
|
||||
continue; // @codeCoverageIgnore
|
||||
}
|
||||
|
||||
$type = (int) $raw[0];
|
||||
|
|
@ -556,7 +560,7 @@ final class FileCache extends ConnectionAbstract
|
|||
$expireEnd = (int) \strpos($raw, self::DELIM, $expireStart + 1);
|
||||
|
||||
if ($expireStart < 0 || $expireEnd < 0) {
|
||||
continue;
|
||||
continue; // @codeCoverageIgnore
|
||||
}
|
||||
|
||||
$cacheExpire = \substr($raw, $expireStart + 1, $expireEnd - ($expireStart + 1));
|
||||
|
|
@ -600,7 +604,7 @@ final class FileCache extends ConnectionAbstract
|
|||
$raw = \file_get_contents($path);
|
||||
|
||||
if ($raw === false) {
|
||||
continue;
|
||||
continue; // @codeCoverageIgnore
|
||||
}
|
||||
|
||||
$cacheExpire = $this->getExpire($raw);
|
||||
|
|
|
|||
|
|
@ -154,17 +154,21 @@ final class MemCached extends ConnectionAbstract
|
|||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function increment(int | string $key, int $value = 1) : void
|
||||
public function increment(int | string $key, int $value = 1) : bool
|
||||
{
|
||||
$this->con->increment($key, $value);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function decrement(int | string $key, int $value = 1) : void
|
||||
public function decrement(int | string $key, int $value = 1) : bool
|
||||
{
|
||||
$this->con->decrement($key, $value);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -41,15 +41,17 @@ final class NullCache extends ConnectionAbstract
|
|||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function increment(int | string $key, int $value = 1) : void
|
||||
public function increment(int | string $key, int $value = 1) : bool
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function decrement(int | string $key, int $value = 1) : void
|
||||
public function decrement(int | string $key, int $value = 1) : bool
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -182,17 +182,21 @@ final class RedisCache extends ConnectionAbstract
|
|||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function increment(int | string $key, int $value = 1) : void
|
||||
public function increment(int | string $key, int $value = 1) : bool
|
||||
{
|
||||
$this->con->incrBy($key, $value);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function decrement(int | string $key, int $value = 1) : void
|
||||
public function decrement(int | string $key, int $value = 1) : bool
|
||||
{
|
||||
$this->con->decrBy($key, $value);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -54,10 +54,10 @@ class Builder extends QueryBuilder
|
|||
/**
|
||||
* Table to drop.
|
||||
*
|
||||
* @var string
|
||||
* @var array
|
||||
* @since 1.0.0
|
||||
*/
|
||||
public string $dropTable = '';
|
||||
public array $dropTable = [];
|
||||
|
||||
/**
|
||||
* Tables.
|
||||
|
|
@ -192,8 +192,8 @@ class Builder extends QueryBuilder
|
|||
*/
|
||||
public function dropTable(string $table) : self
|
||||
{
|
||||
$this->type = QueryType::DROP_TABLE;
|
||||
$this->dropTable = $table;
|
||||
$this->type = QueryType::DROP_TABLE;
|
||||
$this->dropTable[] = $table;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -232,16 +232,16 @@ class Grammar extends QueryGrammar
|
|||
/**
|
||||
* Compile drop query.
|
||||
*
|
||||
* @param BuilderAbstract $query Query
|
||||
* @param string $table Tables to drop
|
||||
* @param BuilderAbstract $query Query
|
||||
* @param string $database Tables to drop
|
||||
*
|
||||
* @return string
|
||||
*
|
||||
* @since 1.0.0
|
||||
*/
|
||||
protected function compileDropDatabase(BuilderAbstract $query, string $table) : string
|
||||
protected function compileDropDatabase(BuilderAbstract $query, string $database) : string
|
||||
{
|
||||
$expression = $this->expressionizeTableColumn([$table]);
|
||||
$expression = $this->expressionizeTableColumn([$database]);
|
||||
|
||||
if ($expression === '') {
|
||||
$expression = '*';
|
||||
|
|
@ -253,16 +253,16 @@ class Grammar extends QueryGrammar
|
|||
/**
|
||||
* Compile drop query.
|
||||
*
|
||||
* @param BuilderAbstract $query Query
|
||||
* @param string $table Tables to drop
|
||||
* @param BuilderAbstract $query Query
|
||||
* @param array $tables Tables to drop
|
||||
*
|
||||
* @return string
|
||||
*
|
||||
* @since 1.0.0
|
||||
*/
|
||||
protected function compileDropTable(BuilderAbstract $query, string $table) : string
|
||||
protected function compileDropTable(BuilderAbstract $query, array $tables) : string
|
||||
{
|
||||
$expression = $this->expressionizeTableColumn([$table]);
|
||||
$expression = $this->expressionizeTableColumn($tables);
|
||||
|
||||
if ($expression === '') {
|
||||
$expression = '*';
|
||||
|
|
|
|||
|
|
@ -142,7 +142,7 @@ final class Prime
|
|||
$primes = \array_combine($range, $range);
|
||||
|
||||
if ($primes === false) {
|
||||
return [];
|
||||
return []; // @codeCoverageIgnore
|
||||
}
|
||||
|
||||
while ($number * $number < $n) {
|
||||
|
|
|
|||
|
|
@ -121,7 +121,7 @@ abstract class ModuleAbstract
|
|||
public static function getLocalization(string $language, string $destination) : array
|
||||
{
|
||||
$lang = [];
|
||||
if (\is_file($oldPath = static::PATH . static::NAME . '/Theme/' . $destination . '/Lang/' . $language . '.lang.php')) {
|
||||
if (\is_file($oldPath = static::PATH . '/Theme/' . $destination . '/Lang/' . $language . '.lang.php')) {
|
||||
/** @noinspection PhpIncludeInspection */
|
||||
return include $oldPath;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -77,7 +77,7 @@ abstract class StatusAbstract
|
|||
continue;
|
||||
}
|
||||
|
||||
self::installRoutes(__DIR__ . '/../../' . $child->getName() . '/' . \basename($file->getName(), '.php') . '/Routes.php', $file->getPath());
|
||||
self::installRoutesHooks(__DIR__ . '/../../' . $child->getName() . '/' . \basename($file->getName(), '.php') . '/Routes.php', $file->getPath());
|
||||
}
|
||||
} elseif ($child instanceof File) {
|
||||
if (!\is_dir(__DIR__ . '/../../' . $child->getName())
|
||||
|
|
@ -86,7 +86,7 @@ abstract class StatusAbstract
|
|||
continue;
|
||||
}
|
||||
|
||||
self::installRoutes(__DIR__ . '/../../' . $child->getName() . '/Routes.php', $child->getPath());
|
||||
self::installRoutesHooks(__DIR__ . '/../../' . $child->getName() . '/Routes.php', $child->getPath());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -103,7 +103,7 @@ abstract class StatusAbstract
|
|||
*
|
||||
* @since 1.0.0
|
||||
*/
|
||||
protected static function installRoutes(string $destRoutePath, string $srcRoutePath) : void
|
||||
protected static function installRoutesHooks(string $destRoutePath, string $srcRoutePath) : void
|
||||
{
|
||||
if (!\is_file($destRoutePath)) {
|
||||
\file_put_contents($destRoutePath, '<?php return [];');
|
||||
|
|
@ -157,7 +157,7 @@ abstract class StatusAbstract
|
|||
continue;
|
||||
}
|
||||
|
||||
self::installHooks(__DIR__ . '/../../' . $child->getName() . '/' . \basename($file->getName(), '.php') . '/Hooks.php', $file->getPath());
|
||||
self::installRoutesHooks(__DIR__ . '/../../' . $child->getName() . '/' . \basename($file->getName(), '.php') . '/Hooks.php', $file->getPath());
|
||||
}
|
||||
} elseif ($child instanceof File) {
|
||||
if (!\is_dir(__DIR__ . '/../../' . $child->getName())
|
||||
|
|
@ -166,52 +166,11 @@ abstract class StatusAbstract
|
|||
continue;
|
||||
}
|
||||
|
||||
self::installHooks(__DIR__ . '/../../' . $child->getName() . '/Hooks.php', $child->getPath());
|
||||
self::installRoutesHooks(__DIR__ . '/../../' . $child->getName() . '/Hooks.php', $child->getPath());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Install hooks.
|
||||
*
|
||||
* @param string $destHookPath Destination hook path
|
||||
* @param string $srcHookPath Source hook path
|
||||
*
|
||||
* @return void
|
||||
*
|
||||
* @throws PathException This exception is thrown if the hook file doesn't exist
|
||||
* @throws PermissionException This exception is thrown if the hook file couldn't be updated (no write permission)
|
||||
*
|
||||
* @since 1.0.0
|
||||
*/
|
||||
protected static function installHooks(string $destHookPath, string $srcHookPath) : void
|
||||
{
|
||||
if (!\is_file($destHookPath)) {
|
||||
\file_put_contents($destHookPath, '<?php return [];');
|
||||
}
|
||||
|
||||
if (!\is_file($srcHookPath)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!\is_file($destHookPath)) {
|
||||
throw new PathException($destHookPath);
|
||||
}
|
||||
|
||||
if (!\is_writable($destHookPath)) {
|
||||
throw new PermissionException($destHookPath);
|
||||
}
|
||||
|
||||
/** @noinspection PhpIncludeInspection */
|
||||
$appHooks = include $destHookPath;
|
||||
/** @noinspection PhpIncludeInspection */
|
||||
$moduleHooks = include $srcHookPath;
|
||||
|
||||
$appHooks = \array_merge_recursive($appHooks, $moduleHooks);
|
||||
|
||||
\file_put_contents($destHookPath, '<?php return ' . ArrayParser::serializeArray($appHooks) . ';', \LOCK_EX);
|
||||
}
|
||||
|
||||
/**
|
||||
* Deactivate module.
|
||||
*
|
||||
|
|
@ -252,7 +211,7 @@ abstract class StatusAbstract
|
|||
continue;
|
||||
}
|
||||
|
||||
self::uninstallRoutes(__DIR__ . '/../../' . $child->getName() . '/' . \basename($file->getName(), '.php') . '/Routes.php', $file->getPath());
|
||||
self::uninstallRoutesHooks(__DIR__ . '/../../' . $child->getName() . '/' . \basename($file->getName(), '.php') . '/Routes.php', $file->getPath());
|
||||
}
|
||||
} elseif ($child instanceof File) {
|
||||
if (!\is_dir(__DIR__ . '/../../' . $child->getName())
|
||||
|
|
@ -261,7 +220,7 @@ abstract class StatusAbstract
|
|||
continue;
|
||||
}
|
||||
|
||||
self::uninstallRoutes(__DIR__ . '/../../' . $child->getName() . '/Routes.php', $child->getPath());
|
||||
self::uninstallRoutesHooks(__DIR__ . '/../../' . $child->getName() . '/Routes.php', $child->getPath());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -278,7 +237,7 @@ abstract class StatusAbstract
|
|||
*
|
||||
* @since 1.0.0
|
||||
*/
|
||||
public static function uninstallRoutes(string $destRoutePath, string $srcRoutePath) : void
|
||||
public static function uninstallRoutesHooks(string $destRoutePath, string $srcRoutePath) : void
|
||||
{
|
||||
if (!\is_file($destRoutePath)
|
||||
|| !\is_file($srcRoutePath)
|
||||
|
|
@ -328,7 +287,7 @@ abstract class StatusAbstract
|
|||
continue;
|
||||
}
|
||||
|
||||
self::uninstallHooks(__DIR__ . '/../../' . $child->getName() . '/' . \basename($file->getName(), '.php') . '/Hooks.php', $file->getPath());
|
||||
self::uninstallRoutesHooks(__DIR__ . '/../../' . $child->getName() . '/' . \basename($file->getName(), '.php') . '/Hooks.php', $file->getPath());
|
||||
}
|
||||
} elseif ($child instanceof File) {
|
||||
if (!\is_dir(__DIR__ . '/../../' . $child->getName())
|
||||
|
|
@ -337,46 +296,8 @@ abstract class StatusAbstract
|
|||
continue;
|
||||
}
|
||||
|
||||
self::uninstallHooks(__DIR__ . '/../../' . $child->getName() . '/Hooks.php', $child->getPath());
|
||||
self::uninstallRoutesHooks(__DIR__ . '/../../' . $child->getName() . '/Hooks.php', $child->getPath());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Uninstall hooks.
|
||||
*
|
||||
* @param string $destHookPath Destination hook path
|
||||
* @param string $srcHookPath Source hook path
|
||||
*
|
||||
* @return void
|
||||
*
|
||||
* @throws PermissionException
|
||||
*
|
||||
* @since 1.0.0
|
||||
*/
|
||||
protected static function uninstallHooks(string $destHookPath, string $srcHookPath) : void
|
||||
{
|
||||
if (!\is_file($destHookPath)
|
||||
|| !\is_file($srcHookPath)
|
||||
) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!\is_file($destHookPath)) {
|
||||
throw new PathException($destHookPath);
|
||||
}
|
||||
|
||||
if (!\is_writable($destHookPath)) {
|
||||
throw new PermissionException($destHookPath);
|
||||
}
|
||||
|
||||
/** @noinspection PhpIncludeInspection */
|
||||
$appHooks = include $destHookPath;
|
||||
/** @noinspection PhpIncludeInspection */
|
||||
$moduleHooks = include $srcHookPath;
|
||||
|
||||
$appHooks = ArrayUtils::array_diff_assoc_recursive($appHooks, $moduleHooks);
|
||||
|
||||
\file_put_contents($destHookPath, '<?php return ' . ArrayParser::serializeArray($appHooks) . ';', \LOCK_EX);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -88,8 +88,8 @@ abstract class UninstallerAbstract
|
|||
$definitions = \json_decode($content, true);
|
||||
$builder = new SchemaBuilder($dbPool->get('schema'));
|
||||
|
||||
foreach ($definitions as $definition) {
|
||||
$builder->dropTable($definition['table'] ?? '');
|
||||
foreach ($definitions as $name => $definition) {
|
||||
$builder->dropTable($name ?? '');
|
||||
}
|
||||
|
||||
$builder->execute();
|
||||
|
|
|
|||
|
|
@ -18,6 +18,7 @@ use phpOMS\Account\Account;
|
|||
use phpOMS\Account\AccountStatus;
|
||||
use phpOMS\Account\AccountType;
|
||||
use phpOMS\Account\Group;
|
||||
use phpOMS\Account\NullGroup;
|
||||
use phpOMS\Account\PermissionAbstract;
|
||||
use phpOMS\Account\PermissionType;
|
||||
use phpOMS\Localization\L11nManager;
|
||||
|
|
@ -107,6 +108,7 @@ class AccountTest extends \PHPUnit\Framework\TestCase
|
|||
self::assertEquals(AccountType::USER, $account->getType());
|
||||
|
||||
self::assertEquals([], $account->getPermissions());
|
||||
self::assertFalse($account->hasGroup(2));
|
||||
|
||||
self::assertInstanceOf('\DateTimeInterface', $account->getLastActive());
|
||||
self::assertInstanceOf('\DateTimeImmutable', $account->createdAt);
|
||||
|
|
@ -151,8 +153,9 @@ class AccountTest extends \PHPUnit\Framework\TestCase
|
|||
$account = new Account();
|
||||
$account->generatePassword('abcd');
|
||||
|
||||
$account->addGroup(new Group());
|
||||
$account->addGroup(new NullGroup(2));
|
||||
self::assertCount(1, $account->getGroups());
|
||||
self::assertTrue($account->hasGroup(2));
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -32,9 +32,9 @@ class WeightedTest extends \PHPUnit\Framework\TestCase
|
|||
public function testNoOverlappingScheduling() : void
|
||||
{
|
||||
$jobs = [
|
||||
new Job(10, new \DateTime('2000-01-01'), null, '0'),
|
||||
new Job(20, new \DateTime('2003-01-01'), new \DateTime('2010-01-01'), 'A'),
|
||||
new Job(50, new \DateTime('2001-01-01'), new \DateTime('2002-01-01'), 'B'),
|
||||
new Job(10, new \DateTime('2000-01-01'), null, '0'),
|
||||
new Job(100, new \DateTime('2006-01-01'), new \DateTime('2019-01-01'), 'C'),
|
||||
new Job(200, new \DateTime('2002-01-01'), new \DateTime('2020-01-01'), 'D'),
|
||||
new Job(300, new \DateTime('2004-01-01'), null, '1'),
|
||||
|
|
|
|||
|
|
@ -17,6 +17,7 @@ namespace phpOMS\tests\Algorithm\PathFinding;
|
|||
use phpOMS\Algorithm\PathFinding\AStar;
|
||||
use phpOMS\Algorithm\PathFinding\AStarNode;
|
||||
use phpOMS\Algorithm\PathFinding\Grid;
|
||||
use phpOMS\Algorithm\PathFinding\Path;
|
||||
use phpOMS\Algorithm\PathFinding\HeuristicType;
|
||||
use phpOMS\Algorithm\PathFinding\MovementType;
|
||||
|
||||
|
|
@ -249,4 +250,23 @@ class AStarTest extends \PHPUnit\Framework\TestCase
|
|||
[0, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, ],
|
||||
], $this->gridArray);
|
||||
}
|
||||
|
||||
/**
|
||||
* @testdox A invalid start or end node returns the grid
|
||||
* @covers phpOMS\Algorithm\PathFinding\AStar
|
||||
* @group framework
|
||||
*/
|
||||
public function testInvalidStartEndNode() : void
|
||||
{
|
||||
$grid = Grid::createGridFromArray($this->gridArray, AStarNode::class);
|
||||
|
||||
self::assertEquals(
|
||||
new Path($grid),
|
||||
$path = AStar::findPath(
|
||||
999, 999,
|
||||
-999, -999,
|
||||
$grid, HeuristicType::EUCLIDEAN, MovementType::DIAGONAL_NO_OBSTACLE
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -15,6 +15,7 @@ declare(strict_types=1);
|
|||
namespace phpOMS\tests\Algorithm\PathFinding;
|
||||
|
||||
use phpOMS\Algorithm\PathFinding\Grid;
|
||||
use phpOMS\Algorithm\PathFinding\Path;
|
||||
use phpOMS\Algorithm\PathFinding\HeuristicType;
|
||||
use phpOMS\Algorithm\PathFinding\JumpPointNode;
|
||||
use phpOMS\Algorithm\PathFinding\JumpPointSearch;
|
||||
|
|
@ -249,4 +250,23 @@ class JumpPointSearchTest extends \PHPUnit\Framework\TestCase
|
|||
[0, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, ],
|
||||
], $this->gridArray);
|
||||
}
|
||||
|
||||
/**
|
||||
* @testdox A invalid start or end node returns the grid
|
||||
* @covers phpOMS\Algorithm\PathFinding\JumpPointSearch
|
||||
* @group framework
|
||||
*/
|
||||
public function testInvalidStartEndNode() : void
|
||||
{
|
||||
$grid = Grid::createGridFromArray($this->gridArray, JumpPointNode::class);
|
||||
|
||||
self::assertEquals(
|
||||
new Path($grid),
|
||||
$path = JumpPointSearch::findPath(
|
||||
999, 999,
|
||||
-999, -999,
|
||||
$grid, HeuristicType::EUCLIDEAN, MovementType::DIAGONAL_NO_OBSTACLE
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -38,6 +38,7 @@ class CycleSortTest extends \PHPUnit\Framework\TestCase
|
|||
new NumericElement(1),
|
||||
new NumericElement(4),
|
||||
new NumericElement(2),
|
||||
new NumericElement(2),
|
||||
new NumericElement(8),
|
||||
];
|
||||
}
|
||||
|
|
@ -62,11 +63,11 @@ class CycleSortTest extends \PHPUnit\Framework\TestCase
|
|||
{
|
||||
$newList = CycleSort::sort($this->list);
|
||||
self::assertEquals(
|
||||
[1, 2, 4, 5, 8], [$newList[0]->value, $newList[1]->value, $newList[2]->value, $newList[3]->value, $newList[4]->value,]
|
||||
[1, 2, 2, 4, 5, 8], [$newList[0]->value, $newList[1]->value, $newList[2]->value, $newList[3]->value, $newList[4]->value, $newList[5]->value,]
|
||||
);
|
||||
|
||||
self::assertEquals(
|
||||
[5, 1, 4, 2, 8], [$this->list[0]->value, $this->list[1]->value, $this->list[2]->value, $this->list[3]->value, $this->list[4]->value,]
|
||||
[5, 1, 4, 2, 2, 8], [$this->list[0]->value, $this->list[1]->value, $this->list[2]->value, $this->list[3]->value, $this->list[4]->value, $this->list[5]->value,]
|
||||
);
|
||||
}
|
||||
|
||||
|
|
@ -78,11 +79,11 @@ class CycleSortTest extends \PHPUnit\Framework\TestCase
|
|||
{
|
||||
$newList = CycleSort::sort($this->list, SortOrder::DESC);
|
||||
self::assertEquals(
|
||||
[8, 5, 4, 2, 1], [$newList[0]->value, $newList[1]->value, $newList[2]->value, $newList[3]->value, $newList[4]->value,]
|
||||
[8, 5, 4, 2, 2, 1], [$newList[0]->value, $newList[1]->value, $newList[2]->value, $newList[3]->value, $newList[4]->value, $newList[5]->value,]
|
||||
);
|
||||
|
||||
self::assertEquals(
|
||||
[5, 1, 4, 2, 8], [$this->list[0]->value, $this->list[1]->value, $this->list[2]->value, $this->list[3]->value, $this->list[4]->value,]
|
||||
[5, 1, 4, 2, 2, 8], [$this->list[0]->value, $this->list[1]->value, $this->list[2]->value, $this->list[3]->value, $this->list[4]->value, $this->list[5]->value,]
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -32,7 +32,7 @@ float $value = 0;
|
|||
|
||||
public function compare(SortableInterface $obj, int $order = SortOrder::ASC) : bool
|
||||
{
|
||||
return $order === SortOrder::ASC ? $this->value > $obj->value : $this->value < $obj->value;
|
||||
return $order === SortOrder::ASC ? $this->value >= $obj->value : $this->value <= $obj->value;
|
||||
}
|
||||
|
||||
public function equals(SortableInterface $obj) : bool
|
||||
|
|
|
|||
|
|
@ -38,6 +38,7 @@ class StoogeSortTest extends \PHPUnit\Framework\TestCase
|
|||
new NumericElement(1),
|
||||
new NumericElement(4),
|
||||
new NumericElement(2),
|
||||
new NumericElement(2),
|
||||
new NumericElement(8),
|
||||
];
|
||||
}
|
||||
|
|
@ -62,11 +63,11 @@ class StoogeSortTest extends \PHPUnit\Framework\TestCase
|
|||
{
|
||||
$newList = StoogeSort::sort($this->list);
|
||||
self::assertEquals(
|
||||
[1, 2, 4, 5, 8], [$newList[0]->value, $newList[1]->value, $newList[2]->value, $newList[3]->value, $newList[4]->value,]
|
||||
[1, 2, 2, 4, 5, 8], [$newList[0]->value, $newList[1]->value, $newList[2]->value, $newList[3]->value, $newList[4]->value, $newList[5]->value,]
|
||||
);
|
||||
|
||||
self::assertEquals(
|
||||
[5, 1, 4, 2, 8], [$this->list[0]->value, $this->list[1]->value, $this->list[2]->value, $this->list[3]->value, $this->list[4]->value,]
|
||||
[5, 1, 4, 2, 2, 8], [$this->list[0]->value, $this->list[1]->value, $this->list[2]->value, $this->list[3]->value, $this->list[4]->value, $this->list[5]->value,]
|
||||
);
|
||||
}
|
||||
|
||||
|
|
@ -78,11 +79,11 @@ class StoogeSortTest extends \PHPUnit\Framework\TestCase
|
|||
{
|
||||
$newList = StoogeSort::sort($this->list, SortOrder::DESC);
|
||||
self::assertEquals(
|
||||
[8, 5, 4, 2, 1], [$newList[0]->value, $newList[1]->value, $newList[2]->value, $newList[3]->value, $newList[4]->value,]
|
||||
[8, 5, 4, 2, 2, 1], [$newList[0]->value, $newList[1]->value, $newList[2]->value, $newList[3]->value, $newList[4]->value, $newList[5]->value,]
|
||||
);
|
||||
|
||||
self::assertEquals(
|
||||
[5, 1, 4, 2, 8], [$this->list[0]->value, $this->list[1]->value, $this->list[2]->value, $this->list[3]->value, $this->list[4]->value,]
|
||||
[5, 1, 4, 2, 2, 8], [$this->list[0]->value, $this->list[1]->value, $this->list[2]->value, $this->list[3]->value, $this->list[4]->value, $this->list[5]->value,]
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -76,10 +76,11 @@ class ApplicationManagerTest extends \PHPUnit\Framework\TestCase
|
|||
/**
|
||||
* @covers phpOMS\Application\ApplicationManager
|
||||
* @covers phpOMS\Application\InstallerAbstract
|
||||
* @covers phpOMS\Application\UninstallerAbstract
|
||||
* @covers phpOMS\Application\StatusAbstract
|
||||
* @group framework
|
||||
*/
|
||||
public function testInstall() : void
|
||||
public function testInstallUninstall() : void
|
||||
{
|
||||
self::assertTrue($this->appManager->install(__DIR__ . '/Testapp', __DIR__ . '/Apps/Testapp'));
|
||||
self::assertTrue(\is_dir(__DIR__ . '/Apps/Testapp'));
|
||||
|
|
@ -89,10 +90,32 @@ class ApplicationManagerTest extends \PHPUnit\Framework\TestCase
|
|||
self::assertTrue(isset($apps['Testapp']));
|
||||
|
||||
$providing = $this->appManager->getProvidingForModule('Navigation');
|
||||
Directory::delete(__DIR__ . '/Apps/Testapp');
|
||||
|
||||
self::assertTrue(isset($providing['Testapp']));
|
||||
self::assertTrue(\in_array('Navigation', $providing['Testapp']));
|
||||
|
||||
$this->appManager->uninstall(__DIR__ . '/Apps/Testapp');
|
||||
self::assertFalse(\is_dir(__DIR__ . '/Apps/Testapp'));
|
||||
}
|
||||
|
||||
/**
|
||||
* @testdox A module can be re-initialized
|
||||
* @covers phpOMS\Application\ApplicationManager
|
||||
* @covers phpOMS\Application\InstallerAbstract
|
||||
* @covers phpOMS\Application\StatusAbstract
|
||||
* @group framework
|
||||
*/
|
||||
public function testReInit() : void
|
||||
{
|
||||
Directory::delete(__DIR__ . '/Apps/Testapp');
|
||||
|
||||
$this->appManager->install(__DIR__ . '/Testapp', __DIR__ . '/Apps/Testapp');
|
||||
|
||||
$this->appManager->reInit(__DIR__ . '/Apps/Testapp');
|
||||
self::assertEquals($r1 = include __DIR__ . '/Testapp/Admin/Install/Application/Routes.php', $r2 = include __DIR__ . '/Apps/Testapp/Routes.php');
|
||||
self::assertEquals($h1 = include __DIR__ . '/Testapp/Admin/Install/Application/Hooks.php', $h2 = include __DIR__ . '/Apps/Testapp/Hooks.php');
|
||||
|
||||
Directory::delete(__DIR__ . '/Apps/Testapp');
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -105,12 +128,40 @@ class ApplicationManagerTest extends \PHPUnit\Framework\TestCase
|
|||
self::assertFalse($this->appManager->install(__DIR__, __DIR__));
|
||||
}
|
||||
|
||||
/**
|
||||
* @covers phpOMS\Application\ApplicationManager
|
||||
* @group framework
|
||||
*/
|
||||
public function testMissingInstallerPath() : void
|
||||
{
|
||||
self::assertFalse($this->appManager->install(__DIR__ . '/MissingInstaller', __DIR__ . '/Apps/MissingInstaller'));
|
||||
}
|
||||
|
||||
/**
|
||||
* @covers phpOMS\Application\ApplicationManager
|
||||
* @group framework
|
||||
*/
|
||||
public function testMissingApplicationInfoFile() : void
|
||||
{
|
||||
self::assertFalse($this->appManager->install(__DIR__, __DIR__ . '/newapp', __DIR__ . '/Apps/newapp'));
|
||||
self::assertFalse($this->appManager->install(__DIR__ . '/MissingInfo', __DIR__ . '/Apps/MissingInfo'));
|
||||
}
|
||||
|
||||
/**
|
||||
* @covers phpOMS\Application\ApplicationManager
|
||||
* @group framework
|
||||
*/
|
||||
public function testInvalidSourceUninstallPath() : void
|
||||
{
|
||||
self::assertFalse($this->appManager->uninstall(__DIR__ . '/invalid', __DIR__));
|
||||
self::assertFalse($this->appManager->uninstall(__DIR__, __DIR__));
|
||||
}
|
||||
|
||||
/**
|
||||
* @covers phpOMS\Application\ApplicationManager
|
||||
* @group framework
|
||||
*/
|
||||
public function testMissingUninstallerPath() : void
|
||||
{
|
||||
self::assertFalse($this->appManager->uninstall(__DIR__ . '/Apps/MissingInstaller'));
|
||||
}
|
||||
}
|
||||
|
|
|
|||
49
tests/Application/InstallerAbstractTest.php
Normal file
49
tests/Application/InstallerAbstractTest.php
Normal file
|
|
@ -0,0 +1,49 @@
|
|||
<?php
|
||||
/**
|
||||
* Orange Management
|
||||
*
|
||||
* PHP Version 8.0
|
||||
*
|
||||
* @package tests
|
||||
* @copyright Dennis Eichhorn
|
||||
* @license OMS License 1.0
|
||||
* @version 1.0.0
|
||||
* @link https://orange-management.org
|
||||
*/
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace phpOMS\tests\Application;
|
||||
|
||||
require_once __DIR__ . '/../Autoloader.php';
|
||||
|
||||
use phpOMS\Application\InstallerAbstract;
|
||||
|
||||
/**
|
||||
* @testdox phpOMS\tests\Application\InstallerAbstractTest: Application installer
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
class InstallerAbstractTest extends \PHPUnit\Framework\TestCase
|
||||
{
|
||||
protected InstallerAbstract $installer;
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function setUp() : void
|
||||
{
|
||||
$this->installer = new class() extends InstallerAbstract {
|
||||
public const PATH = __DIR__ . '/Invalid';
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* @covers phpOMS\Application\InstallerAbstract
|
||||
* @group framework
|
||||
*/
|
||||
public function testInvalidTheme() : void
|
||||
{
|
||||
$this->installer::installTheme(__DIR__, 'Invalid');
|
||||
self::assertFalse(\is_dir(__DIR__ . '/css'));
|
||||
}
|
||||
}
|
||||
1
tests/Application/MissingInfo/Admin/Installer.php
Normal file
1
tests/Application/MissingInfo/Admin/Installer.php
Normal file
|
|
@ -0,0 +1 @@
|
|||
<?php
|
||||
1
tests/Application/MissingInstaller/info.json
Normal file
1
tests/Application/MissingInstaller/info.json
Normal file
|
|
@ -0,0 +1 @@
|
|||
{}
|
||||
51
tests/Application/StatusAbstractTest.php
Normal file
51
tests/Application/StatusAbstractTest.php
Normal file
|
|
@ -0,0 +1,51 @@
|
|||
<?php
|
||||
/**
|
||||
* Orange Management
|
||||
*
|
||||
* PHP Version 8.0
|
||||
*
|
||||
* @package tests
|
||||
* @copyright Dennis Eichhorn
|
||||
* @license OMS License 1.0
|
||||
* @version 1.0.0
|
||||
* @link https://orange-management.org
|
||||
*/
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace phpOMS\tests\Application;
|
||||
|
||||
require_once __DIR__ . '/../Autoloader.php';
|
||||
|
||||
use phpOMS\Application\StatusAbstract;
|
||||
|
||||
/**
|
||||
* @testdox phpOMS\tests\Application\StatusAbstractTest: Application status
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
class StatusAbstractTest extends \PHPUnit\Framework\TestCase
|
||||
{
|
||||
protected StatusAbstract $status;
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function setUp() : void
|
||||
{
|
||||
$this->status = new class() extends StatusAbstract {
|
||||
public const PATH = __DIR__ . '/Invalid';
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* @covers phpOMS\Application\StatusAbstract
|
||||
* @group framework
|
||||
*/
|
||||
public function testInvalidAppPathActivation() : void
|
||||
{
|
||||
$this->status::activateRoutes();
|
||||
$this->status::activateHooks();
|
||||
|
||||
self::assertFalse(\is_file(__DIR__ . '/Routes.php'));
|
||||
}
|
||||
}
|
||||
|
|
@ -4,7 +4,7 @@
|
|||
*
|
||||
* PHP Version 8.0
|
||||
*
|
||||
* @package Web\Api\Admin
|
||||
* @package phpOMS\tests\Application\Apps\{APPNAME}\Admin
|
||||
* @copyright Dennis Eichhorn
|
||||
* @license OMS License 1.0
|
||||
* @version 1.0.0
|
||||
|
|
@ -19,7 +19,7 @@ use phpOMS\Application\InstallerAbstract;
|
|||
/**
|
||||
* Installer class.
|
||||
*
|
||||
* @package Web\Api\Admin
|
||||
* @package phpOMS\tests\Application\Apps\{APPNAME}\Admin
|
||||
* @license OMS License 1.0
|
||||
* @link https://orange-management.org
|
||||
* @since 1.0.0
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@
|
|||
*
|
||||
* PHP Version 8.0
|
||||
*
|
||||
* @package Web\Api\Admin
|
||||
* @package phpOMS\tests\Application\Apps\{APPNAME}\Admin
|
||||
* @copyright Dennis Eichhorn
|
||||
* @license OMS License 1.0
|
||||
* @version 1.0.0
|
||||
|
|
@ -19,7 +19,7 @@ use phpOMS\Application\StatusAbstract;
|
|||
/**
|
||||
* Status class.
|
||||
*
|
||||
* @package Web\Api\Admin
|
||||
* @package phpOMS\tests\Application\Apps\{APPNAME}\Admin
|
||||
* @license OMS License 1.0
|
||||
* @link https://orange-management.org
|
||||
* @since 1.0.0
|
||||
|
|
|
|||
30
tests/Application/Testapp/Admin/Uninstaller.php
Normal file
30
tests/Application/Testapp/Admin/Uninstaller.php
Normal file
|
|
@ -0,0 +1,30 @@
|
|||
<?php
|
||||
/**
|
||||
* Orange Management
|
||||
*
|
||||
* PHP Version 8.0
|
||||
*
|
||||
* @package phpOMS\tests\Application\Apps\{APPNAME}\Admin
|
||||
* @copyright Dennis Eichhorn
|
||||
* @license OMS License 1.0
|
||||
* @version 1.0.0
|
||||
* @link https://orange-management.org
|
||||
*/
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace phpOMS\tests\Application\Apps\{APPNAME}\Admin;
|
||||
|
||||
use phpOMS\Application\UninstallerAbstract;
|
||||
|
||||
/**
|
||||
* Uninstaller class.
|
||||
*
|
||||
* @package phpOMS\tests\Application\Apps\{APPNAME}\Admin
|
||||
* @license OMS License 1.0
|
||||
* @link https://orange-management.org
|
||||
* @since 1.0.0
|
||||
*/
|
||||
final class Uninstaller extends UninstallerAbstract
|
||||
{
|
||||
public const PATH = __DIR__;
|
||||
}
|
||||
|
|
@ -26,4 +26,4 @@ use phpOMS\Module\ModuleAbstract;
|
|||
*/
|
||||
final class Controller extends ModuleAbstract
|
||||
{
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,3 +1 @@
|
|||
#test {
|
||||
color: #000;
|
||||
}
|
||||
html {}
|
||||
1
tests/Application/Testapp/css/styles.css
Normal file
1
tests/Application/Testapp/css/styles.css
Normal file
|
|
@ -0,0 +1 @@
|
|||
body {}
|
||||
|
|
@ -17,7 +17,8 @@
|
|||
"description": "The administration module.",
|
||||
"directory": "Admin",
|
||||
"providing": {
|
||||
"Navigation": "*"
|
||||
"Navigation": "*",
|
||||
"Invalid": "*"
|
||||
},
|
||||
"dependencies": []
|
||||
}
|
||||
|
|
@ -83,7 +83,7 @@ class MetricsTest extends \PHPUnit\Framework\TestCase
|
|||
}
|
||||
|
||||
/**
|
||||
* @testdox The CLTV can be calculated using the migration model
|
||||
* @testdox The CLTV can be calculated using the migration model
|
||||
* @group framework
|
||||
*/
|
||||
public function testMigrationModel() : void
|
||||
|
|
@ -101,7 +101,7 @@ class MetricsTest extends \PHPUnit\Framework\TestCase
|
|||
}
|
||||
|
||||
/**
|
||||
* @testdox The migration model can be used in order to determin which buying/none-buying customer group should receive a mailing
|
||||
* @testdox The migration model can be used in order to determin which buying/none-buying customer group should receive a mailing
|
||||
* @group framework
|
||||
*/
|
||||
public function testMailingSuccessEstimation() : void
|
||||
|
|
@ -116,4 +116,17 @@ class MetricsTest extends \PHPUnit\Framework\TestCase
|
|||
0.1
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @testdox The probability of a customer buying can be calculated based on his previous purchase behavior
|
||||
* @group framework
|
||||
*/
|
||||
public function testCustomerActiveProbability() : void
|
||||
{
|
||||
$purchases = 10;
|
||||
$periods = 36; // months
|
||||
|
||||
self::assertEqualsWithDelta(0.017, Metrics::customerActiveProbability($purchases, $periods, 24), 0.001);
|
||||
self::assertEqualsWithDelta(1.0, Metrics::customerActiveProbability($purchases, $periods, 36), 0.001);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -127,6 +127,29 @@ class FileCacheTest extends \PHPUnit\Framework\TestCase
|
|||
self::assertEquals('testValAdd', $this->cache->get('addKey'));
|
||||
}
|
||||
|
||||
public function testExists() : void
|
||||
{
|
||||
self::assertTrue($this->cache->add('addKey', 'testValAdd'));
|
||||
self::assertTrue($this->cache->exists('addKey'));
|
||||
self::assertFalse($this->cache->exists('invalid'));
|
||||
}
|
||||
|
||||
public function testExpiredExists() : void
|
||||
{
|
||||
$this->cache->set('key2', 'testVal2', 2);
|
||||
\sleep(1);
|
||||
self::assertTrue($this->cache->exists('key2'));
|
||||
self::assertFalse($this->cache->exists('key2', 0));
|
||||
\sleep(3);
|
||||
self::assertFalse($this->cache->exists('key2'));
|
||||
}
|
||||
|
||||
public function testExistsInvalidStatus() : void
|
||||
{
|
||||
TestUtils::setMember($this->cache, 'status', CacheStatus::FAILURE);
|
||||
self::assertFalse($this->cache->exists('invalid'));
|
||||
}
|
||||
|
||||
public function testGetLike() : void
|
||||
{
|
||||
$this->cache->set('key1', 'testVal1');
|
||||
|
|
@ -134,20 +157,47 @@ class FileCacheTest extends \PHPUnit\Framework\TestCase
|
|||
self::assertEquals([], \array_diff(['testVal1', 'testVal2'], $this->cache->getLike('key\d')));
|
||||
}
|
||||
|
||||
public function testExpiredGetLike() : void
|
||||
{
|
||||
$this->cache->set('key1', 'testVal1', 2);
|
||||
$this->cache->set('key2', 'testVal2', 2);
|
||||
\sleep(1);
|
||||
self::assertEquals([], \array_diff(['testVal1', 'testVal2'], $this->cache->getLike('key\d')));
|
||||
self::assertEquals([], $this->cache->getLike('key\d', 0));
|
||||
\sleep(3);
|
||||
self::assertEquals([], $this->cache->getLike('key\d'));
|
||||
}
|
||||
|
||||
public function testGetLikeInvalidStatus() : void
|
||||
{
|
||||
TestUtils::setMember($this->cache, 'status', CacheStatus::FAILURE);
|
||||
self::assertEquals([], $this->cache->getLike('key\d'));
|
||||
}
|
||||
|
||||
public function testIncrement() : void
|
||||
{
|
||||
$this->cache->set(1, 1);
|
||||
$this->cache->increment(1, 2);
|
||||
self::assertTrue($this->cache->increment(1, 2));
|
||||
self::assertEquals(3, $this->cache->get(1));
|
||||
}
|
||||
|
||||
public function testInvalidKeyIncrement() : void
|
||||
{
|
||||
self::assertFalse($this->cache->increment('invalid', 2));
|
||||
}
|
||||
|
||||
public function testDecrement() : void
|
||||
{
|
||||
$this->cache->set(1, 3);
|
||||
$this->cache->decrement(1, 2);
|
||||
self::assertTrue($this->cache->decrement(1, 2));
|
||||
self::assertEquals(1, $this->cache->get(1));
|
||||
}
|
||||
|
||||
public function testInvalidKeyDecrement() : void
|
||||
{
|
||||
self::assertFalse($this->cache->decrement('invalid', 2));
|
||||
}
|
||||
|
||||
public function testRename() : void
|
||||
{
|
||||
$this->cache->set('a', 'testVal1');
|
||||
|
|
@ -163,6 +213,23 @@ class FileCacheTest extends \PHPUnit\Framework\TestCase
|
|||
self::assertEquals([], $this->cache->getLike('key\d'));
|
||||
}
|
||||
|
||||
public function testExpiredDelteLike() : void
|
||||
{
|
||||
$this->cache->set('key1', 'testVal1', 2);
|
||||
$this->cache->set('key2', 'testVal2', 2);
|
||||
|
||||
\sleep(1);
|
||||
|
||||
self::assertTrue($this->cache->deleteLike('key\d', 0));
|
||||
self::assertEquals([], $this->cache->getLike('key\d'));
|
||||
}
|
||||
|
||||
public function testDeleteLikeInvalidStatus() : void
|
||||
{
|
||||
TestUtils::setMember($this->cache, 'status', CacheStatus::FAILURE);
|
||||
self::assertFalse($this->cache->deleteLike('key\d'));
|
||||
}
|
||||
|
||||
public function testUpdateExpire() : void
|
||||
{
|
||||
$this->cache->set('key2', 'testVal2', 1);
|
||||
|
|
@ -222,6 +289,11 @@ class FileCacheTest extends \PHPUnit\Framework\TestCase
|
|||
self::assertNull($this->cache->get('key4'));
|
||||
}
|
||||
|
||||
public function testInvalidKeyDelete() : void
|
||||
{
|
||||
self::assertTrue($this->cache->delete('invalid'));
|
||||
}
|
||||
|
||||
/**
|
||||
* @testdox The cache correctly handles general cache information
|
||||
* @covers phpOMS\DataStorage\Cache\Connection\FileCache<extended>
|
||||
|
|
|
|||
|
|
@ -128,6 +128,28 @@ class MemCachedTest extends \PHPUnit\Framework\TestCase
|
|||
self::assertEquals('testValAdd', $this->cache->get('addKey'));
|
||||
}
|
||||
|
||||
public function testExists() : void
|
||||
{
|
||||
self::assertTrue($this->cache->add('addKey', 'testValAdd'));
|
||||
self::assertTrue($this->cache->exists('addKey'));
|
||||
}
|
||||
|
||||
public function testExpiredExists() : void
|
||||
{
|
||||
$this->cache->set('key2', 'testVal2', 2);
|
||||
\sleep(1);
|
||||
self::assertTrue($this->cache->exists('key2'));
|
||||
self::assertFalse($this->cache->exists('key2', 0));
|
||||
\sleep(3);
|
||||
self::assertFalse($this->cache->exists('key2'));
|
||||
}
|
||||
|
||||
public function testExistsInvalidStatus() : void
|
||||
{
|
||||
TestUtils::setMember($this->cache, 'status', CacheStatus::FAILURE);
|
||||
self::assertFalse($this->cache->exists('invalid'));
|
||||
}
|
||||
|
||||
public function testGetLike() : void
|
||||
{
|
||||
$this->cache->set('key1', 'testVal1');
|
||||
|
|
@ -135,20 +157,47 @@ class MemCachedTest extends \PHPUnit\Framework\TestCase
|
|||
self::assertEquals(['testVal1', 'testVal2'], $this->cache->getLike('key\d'));
|
||||
}
|
||||
|
||||
public function testExpiredGetLike() : void
|
||||
{
|
||||
$this->cache->set('key1', 'testVal1', 2);
|
||||
$this->cache->set('key2', 'testVal2', 2);
|
||||
\sleep(1);
|
||||
self::assertEquals([], \array_diff(['testVal1', 'testVal2'], $this->cache->getLike('key\d')));
|
||||
self::assertEquals([], $this->cache->getLike('key\d', 0));
|
||||
\sleep(3);
|
||||
self::assertEquals([], $this->cache->getLike('key\d'));
|
||||
}
|
||||
|
||||
public function testGetLikeInvalidStatus() : void
|
||||
{
|
||||
TestUtils::setMember($this->cache, 'status', CacheStatus::FAILURE);
|
||||
self::assertEquals([], $this->cache->getLike('key\d'));
|
||||
}
|
||||
|
||||
public function testIncrement() : void
|
||||
{
|
||||
$this->cache->set(1, 1);
|
||||
$this->cache->increment(1, 2);
|
||||
self::assertTrue($this->cache->increment(1, 2));
|
||||
self::assertEquals(3, $this->cache->get(1));
|
||||
}
|
||||
|
||||
public function testInvalidKeyIncrement() : void
|
||||
{
|
||||
self::assertFalse($this->cache->increment('invalid', 2));
|
||||
}
|
||||
|
||||
public function testDecrement() : void
|
||||
{
|
||||
$this->cache->set(1, 3);
|
||||
$this->cache->decrement(1, 2);
|
||||
self::assertTrue($this->cache->decrement(1, 2));
|
||||
self::assertEquals(1, $this->cache->get(1));
|
||||
}
|
||||
|
||||
public function testInvalidKeyDecrement() : void
|
||||
{
|
||||
self::assertFalse($this->cache->decrement('invalid', 2));
|
||||
}
|
||||
|
||||
public function testRename() : void
|
||||
{
|
||||
$this->cache->set('a', 'testVal1');
|
||||
|
|
@ -164,6 +213,12 @@ class MemCachedTest extends \PHPUnit\Framework\TestCase
|
|||
self::assertEquals([], $this->cache->getLike('key\d'));
|
||||
}
|
||||
|
||||
public function testDeleteLikeInvalidStatus() : void
|
||||
{
|
||||
TestUtils::setMember($this->cache, 'status', CacheStatus::FAILURE);
|
||||
self::assertFalse($this->cache->deleteLike('key\d'));
|
||||
}
|
||||
|
||||
public function testUpdateExpire() : void
|
||||
{
|
||||
$this->cache->set('key2', 'testVal2', 1);
|
||||
|
|
@ -223,6 +278,11 @@ class MemCachedTest extends \PHPUnit\Framework\TestCase
|
|||
self::assertNull($this->cache->get('key4'));
|
||||
}
|
||||
|
||||
public function testInvalidKeyDelete() : void
|
||||
{
|
||||
self::assertTrue($this->cache->delete('invalid'));
|
||||
}
|
||||
|
||||
/**
|
||||
* @testdox The cache correctly handles general cache information
|
||||
* @covers phpOMS\DataStorage\Cache\Connection\MemCached<extended>
|
||||
|
|
|
|||
|
|
@ -78,7 +78,7 @@ final class NullCacheTest extends \PHPUnit\Framework\TestCase
|
|||
|
||||
public function testDecrement() : void
|
||||
{
|
||||
$this->cache->increment(1, 1);
|
||||
$this->cache->decrement(1, 1);
|
||||
self::assertNull($this->cache->get(1));
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -124,6 +124,28 @@ class RedisCacheTest extends \PHPUnit\Framework\TestCase
|
|||
self::assertEquals('testValAdd', $this->cache->get('addKey'));
|
||||
}
|
||||
|
||||
public function testExists() : void
|
||||
{
|
||||
self::assertTrue($this->cache->add('addKey', 'testValAdd'));
|
||||
self::assertTrue($this->cache->exists('addKey'));
|
||||
}
|
||||
|
||||
public function testExpiredExists() : void
|
||||
{
|
||||
$this->cache->set('key2', 'testVal2', 2);
|
||||
\sleep(1);
|
||||
self::assertTrue($this->cache->exists('key2'));
|
||||
self::assertFalse($this->cache->exists('key2', 0));
|
||||
\sleep(3);
|
||||
self::assertFalse($this->cache->exists('key2'));
|
||||
}
|
||||
|
||||
public function testExistsInvalidStatus() : void
|
||||
{
|
||||
TestUtils::setMember($this->cache, 'status', CacheStatus::FAILURE);
|
||||
self::assertFalse($this->cache->exists('invalid'));
|
||||
}
|
||||
|
||||
public function testGetLike() : void
|
||||
{
|
||||
$this->cache->set('key1', 'testVal1');
|
||||
|
|
@ -131,20 +153,47 @@ class RedisCacheTest extends \PHPUnit\Framework\TestCase
|
|||
self::assertEquals(['testVal1', 'testVal2'], $this->cache->getLike('key\d'));
|
||||
}
|
||||
|
||||
public function testExpiredGetLike() : void
|
||||
{
|
||||
$this->cache->set('key1', 'testVal1', 2);
|
||||
$this->cache->set('key2', 'testVal2', 2);
|
||||
\sleep(1);
|
||||
self::assertEquals([], \array_diff(['testVal1', 'testVal2'], $this->cache->getLike('key\d')));
|
||||
self::assertEquals([], $this->cache->getLike('key\d', 0));
|
||||
\sleep(3);
|
||||
self::assertEquals([], $this->cache->getLike('key\d'));
|
||||
}
|
||||
|
||||
public function testGetLikeInvalidStatus() : void
|
||||
{
|
||||
TestUtils::setMember($this->cache, 'status', CacheStatus::FAILURE);
|
||||
self::assertEquals([], $this->cache->getLike('key\d'));
|
||||
}
|
||||
|
||||
public function testIncrement() : void
|
||||
{
|
||||
$this->cache->set(1, 1);
|
||||
$this->cache->increment(1, 2);
|
||||
self::assertTrue($this->cache->increment(1, 2));
|
||||
self::assertEquals(3, $this->cache->get(1));
|
||||
}
|
||||
|
||||
public function testInvalidKeyIncrement() : void
|
||||
{
|
||||
self::assertFalse($this->cache->increment('invalid', 2));
|
||||
}
|
||||
|
||||
public function testDecrement() : void
|
||||
{
|
||||
$this->cache->set(1, 3);
|
||||
$this->cache->decrement(1, 2);
|
||||
self::assertTrue($this->cache->decrement(1, 2));
|
||||
self::assertEquals(1, $this->cache->get(1));
|
||||
}
|
||||
|
||||
public function testInvalidKeyDecrement() : void
|
||||
{
|
||||
self::assertFalse($this->cache->decrement('invalid', 2));
|
||||
}
|
||||
|
||||
public function testRename() : void
|
||||
{
|
||||
$this->cache->set('a', 'testVal1');
|
||||
|
|
@ -160,6 +209,12 @@ class RedisCacheTest extends \PHPUnit\Framework\TestCase
|
|||
self::assertEquals([], $this->cache->getLike('key\d'));
|
||||
}
|
||||
|
||||
public function testDeleteLikeInvalidStatus() : void
|
||||
{
|
||||
TestUtils::setMember($this->cache, 'status', CacheStatus::FAILURE);
|
||||
self::assertFalse($this->cache->deleteLike('key\d'));
|
||||
}
|
||||
|
||||
public function testUpdateExpire() : void
|
||||
{
|
||||
$this->cache->set('key2', 'testVal2', 1);
|
||||
|
|
@ -219,6 +274,11 @@ class RedisCacheTest extends \PHPUnit\Framework\TestCase
|
|||
self::assertNull($this->cache->get('key4'));
|
||||
}
|
||||
|
||||
public function testInvalidKeyDelete() : void
|
||||
{
|
||||
self::assertTrue($this->cache->delete('invalid'));
|
||||
}
|
||||
|
||||
/**
|
||||
* @testdox The cache correctly handles general cache information
|
||||
* @covers phpOMS\DataStorage\Cache\Connection\RedisCache<extended>
|
||||
|
|
|
|||
|
|
@ -108,29 +108,19 @@ class BuilderTest extends \PHPUnit\Framework\TestCase
|
|||
);*/
|
||||
}
|
||||
|
||||
/**
|
||||
* @testdox The grammar correctly deletes a table
|
||||
* @covers phpOMS\DataStorage\Database\Schema\Grammar\MysqlGrammar<extended>
|
||||
* @group framework
|
||||
*/
|
||||
public function testMysqlCreateFromSchema() : void
|
||||
{
|
||||
Builder::createFromSchema(
|
||||
\json_decode(
|
||||
\file_get_contents(__DIR__ . '/Grammar/testSchema.json'), true
|
||||
)['test_foreign'],
|
||||
$this->con
|
||||
)->execute();
|
||||
$query = new Builder($this->con);
|
||||
$sql = 'DROP TABLE `test`, `test_foreign`;';
|
||||
|
||||
Builder::createFromSchema(
|
||||
\json_decode(
|
||||
\file_get_contents(__DIR__ . '/Grammar/testSchema.json'), true
|
||||
)['test'],
|
||||
$this->con
|
||||
)->execute();
|
||||
|
||||
$table = new Builder($this->con);
|
||||
$tables = $table->selectTables()->execute()->fetchAll(\PDO::FETCH_COLUMN);
|
||||
self::assertContains('test', $tables);
|
||||
self::assertContains('test_foreign', $tables);
|
||||
|
||||
$delete = new Builder($this->con);
|
||||
$delete->dropTable('test')->execute();
|
||||
$delete->dropTable('test_foreign')->execute();
|
||||
self::assertEquals(
|
||||
$sql,
|
||||
$query->dropTable('test')->dropTable('test_foreign')->toSql()
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@ declare(strict_types=1);
|
|||
namespace phpOMS\tests\DataStorage\Database\Schema\Grammar;
|
||||
|
||||
use phpOMS\DataStorage\Database\Connection\MysqlConnection;
|
||||
use phpOMS\DataStorage\Database\Schema\Builder as SchemaBuilder;
|
||||
use phpOMS\DataStorage\Database\Schema\Builder;
|
||||
use phpOMS\DataStorage\Database\Schema\Grammar\MysqlGrammar;
|
||||
use phpOMS\Utils\ArrayUtils;
|
||||
use phpOMS\Utils\TestUtils;
|
||||
|
|
@ -58,15 +58,15 @@ class MysqlGrammarTest extends \PHPUnit\Framework\TestCase
|
|||
{
|
||||
$definitions = \json_decode(\file_get_contents(__DIR__ . '/testSchema.json'), true);
|
||||
foreach ($definitions as $definition) {
|
||||
SchemaBuilder::createFromSchema($definition, $this->con)->execute();
|
||||
Builder::createFromSchema($definition, $this->con)->execute();
|
||||
}
|
||||
|
||||
$table = new SchemaBuilder($this->con);
|
||||
$table = new Builder($this->con);
|
||||
$tables = $table->selectTables()->execute()->fetchAll(\PDO::FETCH_COLUMN);
|
||||
self::assertContains('test', $tables);
|
||||
self::assertContains('test_foreign', $tables);
|
||||
|
||||
$field = new SchemaBuilder($this->con);
|
||||
$field = new Builder($this->con);
|
||||
$fields = $field->selectFields('test')->execute()->fetchAll();
|
||||
|
||||
foreach ($definitions['test']['fields'] as $key => $field) {
|
||||
|
|
@ -75,6 +75,11 @@ class MysqlGrammarTest extends \PHPUnit\Framework\TestCase
|
|||
'Couldn\'t find "' . $key . '" in array'
|
||||
);
|
||||
}
|
||||
|
||||
$delete = new Builder($this->con);
|
||||
$delete->dropTable('test')
|
||||
->dropTable('test_foreign')
|
||||
->execute();
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -84,13 +89,22 @@ class MysqlGrammarTest extends \PHPUnit\Framework\TestCase
|
|||
*/
|
||||
public function testDelete() : void
|
||||
{
|
||||
$table = new SchemaBuilder($this->con);
|
||||
$definitions = \json_decode(\file_get_contents(__DIR__ . '/testSchema.json'), true);
|
||||
foreach ($definitions as $definition) {
|
||||
Builder::createFromSchema($definition, $this->con)->execute();
|
||||
}
|
||||
|
||||
$table = new Builder($this->con);
|
||||
$tables = $table->selectTables()->execute()->fetchAll(\PDO::FETCH_COLUMN);
|
||||
self::assertContains('test', $tables);
|
||||
self::assertContains('test_foreign', $tables);
|
||||
|
||||
$delete = new SchemaBuilder($this->con);
|
||||
$delete->dropTable('test')->execute();
|
||||
$delete->dropTable('test_foreign')->execute();
|
||||
$delete = new Builder($this->con);
|
||||
$delete->dropTable('test')
|
||||
->dropTable('test_foreign')
|
||||
->execute();
|
||||
|
||||
$table = new Builder($this->con);
|
||||
$tables = $table->selectTables()->execute()->fetchAll();
|
||||
self::assertNotContains('test', $tables);
|
||||
self::assertNotContains('test_foreign', $tables);
|
||||
|
|
|
|||
|
|
@ -91,6 +91,16 @@ class L11nManagerTest extends \PHPUnit\Framework\TestCase
|
|||
self::assertEquals('Test strin&g2', $this->l11nManager->getHtml('en', 'Admin', 'RandomThemeDoesNotMatterAlreadyLoaded', 'Test2'));
|
||||
}
|
||||
|
||||
/**
|
||||
* @testdox An invalid localization source returns an error string
|
||||
* @covers phpOMS\Localization\L11nManager
|
||||
* @group framework
|
||||
*/
|
||||
public function testInvalidControllerSource() : void
|
||||
{
|
||||
self::assertEquals('ERROR-Key', $this->l11nManager->getText('en', 'InvalidSource', 'RandomThemeDoesNotMatterAlreadyLoaded', 'Key'));
|
||||
}
|
||||
|
||||
/**
|
||||
* @testdox Language data can be loaded from a file
|
||||
* @covers phpOMS\Localization\L11nManager
|
||||
|
|
|
|||
32
tests/Math/Statistic/Forecast/ForecastsTest.php
Normal file
32
tests/Math/Statistic/Forecast/ForecastsTest.php
Normal file
|
|
@ -0,0 +1,32 @@
|
|||
<?php
|
||||
/**
|
||||
* Orange Management
|
||||
*
|
||||
* PHP Version 8.0
|
||||
*
|
||||
* @package tests
|
||||
* @copyright Dennis Eichhorn
|
||||
* @license OMS License 1.0
|
||||
* @version 1.0.0
|
||||
* @link https://orange-management.org
|
||||
*/
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace phpOMS\tests\Math\Statistic\Forecast;
|
||||
|
||||
use phpOMS\Math\Statistic\Forecast\Forecasts;
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
class ForecastsTest extends \PHPUnit\Framework\TestCase
|
||||
{
|
||||
public function testForecastInterval() : void
|
||||
{
|
||||
self::assertEqualsWithDelta(
|
||||
[519.3, 543.6],
|
||||
Forecasts::getForecastInteval(531.48, 6.21, 1.96),
|
||||
0.1
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
@ -43,7 +43,7 @@ class ModuleAbstractTest extends \PHPUnit\Framework\TestCase
|
|||
{
|
||||
$this->module = new class() extends ModuleAbstract
|
||||
{
|
||||
public const PATH = __DIR__ . '/';
|
||||
public const PATH = __DIR__ . '/Test';
|
||||
|
||||
const VERSION = '1.2.3';
|
||||
|
||||
|
|
|
|||
|
|
@ -211,6 +211,18 @@ class ModuleManagerTest extends \PHPUnit\Framework\TestCase
|
|||
/**
|
||||
* @testdox A module can be re-initialized
|
||||
* @covers phpOMS\Module\ModuleManager
|
||||
* @group framework
|
||||
*/
|
||||
public function testInvalidModuleReInit() : void
|
||||
{
|
||||
$this->moduleManager->reInit('Invalid');
|
||||
self::assertFalse($this->moduleManager->isActive('Invalid'));
|
||||
}
|
||||
|
||||
/**
|
||||
* @testdox A module can be re-initialized
|
||||
* @covers phpOMS\Module\ModuleManager
|
||||
* @covers phpOMS\Module\InstallerAbstract
|
||||
* @covers phpOMS\Module\StatusAbstract
|
||||
* @group framework
|
||||
*/
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user