Improve tests

This commit is contained in:
Dennis Eichhorn 2018-09-01 16:28:00 +02:00
parent a748d50b0a
commit f1326f4a75
69 changed files with 633 additions and 1588 deletions

View File

@ -1,19 +0,0 @@
<?php
/**
* Orange Management
*
* PHP Version 7.2
*
* @package TBD
* @copyright Dennis Eichhorn
* @license OMS License 1.0
* @version 1.0.0
* @link http://website.orange-management.de
*/
declare(strict_types=1);
namespace phpOMS\Business\Finance\Forecasting;
class AR
{
}

View File

@ -1,19 +0,0 @@
<?php
/**
* Orange Management
*
* PHP Version 7.2
*
* @package TBD
* @copyright Dennis Eichhorn
* @license OMS License 1.0
* @version 1.0.0
* @link http://website.orange-management.de
*/
declare(strict_types=1);
namespace phpOMS\Business\Finance\Forecasting;
class ARCH
{
}

View File

@ -1,19 +0,0 @@
<?php
/**
* Orange Management
*
* PHP Version 7.2
*
* @package TBD
* @copyright Dennis Eichhorn
* @license OMS License 1.0
* @version 1.0.0
* @link http://website.orange-management.de
*/
declare(strict_types=1);
namespace phpOMS\Business\Finance\Forecasting;
class ARFIMA
{
}

View File

@ -1,200 +0,0 @@
<?php
/**
* Orange Management
*
* PHP Version 7.2
*
* @package phpOMS\Business\Finance\Forecasting
* @copyright Dennis Eichhorn
* @license OMS License 1.0
* @version 1.0.0
* @link http://website.orange-management.de
*/
declare(strict_types=1);
namespace phpOMS\Business\Finance\Forecasting;
use phpOMS\Math\Statistic\Average;
/**
* Arima forecasting class.
*
* @package phpOMS\Business\Finance\Forecasting
* @license OMS License 1.0
* @link http://website.orange-management.de
* @since 1.0.0
*/
class ARIMA
{
/**
* Data points
*
* @var array
* @since 1.0.0
*/
private $data = [];
/**
* Intervals of the time series
*
* @var array
* @since 1.0.0
*/
private $order = 0;
/**
* Constructor.
*
* @param array $data Data points
* @param int $order Data intervals (only 12 and 4 are valid).
*
* @since 1.0.0
*/
public function __construct(array $data, int $order = 12)
{
$this->data = $data;
$this->order = $order;
if ($order !== 12 && $order !== 4) {
throw new \Exception('ARIMA only supports quarterly and monthly decomposition');
}
}
/**
* Return data decomposition.
*
* @return array
*
* @since 1.0.0
*/
public function getDecomposition() : array
{
$iteration1 = $this->getIteration($this->data);
$iteration2 = $this->getIteration($iteration1);
$iteration3 = $this->getIteration($iteration2);
return $iteration3;
}
private function getIteration(array $data) : array
{
$multiplicativeDecomposition = new ClassicalDecomposition($data, $this->order, ClassicalDecomposition::MULTIPLICATIVE);
$tempDecomposition = $multiplicativeDecomposition->getDecomposition();
// 1
$trendCycleComponent = ClassicalDecomposition::computeTrendCycle($data, $this->order);
$centeredRatios = ClassicalDecomposition::computeDetrendedSeries($this->data, $trendCycleComponent, ClassicalDecomposition::MULTIPLICATIVE);
$prelimSeasonalComponent = Average::totalMovingAverage(Average::totalMovingAverage($centeredRatios, 3, null, true), 3, null, true);
$prelimRemainder = $this->getPrelimRemainder($centeredRatios, $prelimSeasonalComponent);
$modifiedRemainder = $this->removeOutliers($prelimRemainder, 0.5);
$modifiedCenteredRatios = $this->getModifiedCenteredRatios($prelimSeasonalComponent, $modifiedRemainder);
$revisedSeasonalComponent = Average::totalMovingAverage(Average::totalMovingAverage($modifiedCenteredRatios, 3, null, true), 3, null, true);
$prelimSeasonalAdjustedSeries = $this->getPrelimSeasonalAdjustedSeries($revisedSeasonalComponent);
$trendCycleComponent = $this->getTrendCycleEstimation($prelimSeasonalAdjustedSeries);
// 2
$centeredRatios = ClassicalDecomposition::computeDetrendedSeries($this->data, $trendCycleComponent, ClassicalDecomposition::MULTIPLICATIVE);
$prelimSeasonalComponent = Average::totalMovingAverage(Average::totalMovingAverage($centeredRatios, 5, null, true), 3, null, true);
$prelimRemainder = $this->getPrelimRemainder($centeredRatios, $prelimSeasonalComponent);
$modifiedRemainder = $this->removeOutliers($prelimRemainder, 0.5);
$modifiedCenteredRatios = $this->getModifiedCenteredRatios($prelimSeasonalComponent, $modifiedRemainder);
$revisedSeasonalComponent = Average::totalMovingAverage(Average::totalMovingAverage($modifiedCenteredRatios, 5, null, true), 3, null, true);
$seasonalAdjustedSeries = $this->getSeasonalAdjustedSeries($revisedSeasonalComponent);
$remainder = $this->getRemainder($seasonalAdjustedSeries, $trendCycleComponent);
$modifiedRemainder = $this->removeOutliers($remainder, 0.5);
$modifiedData = $this->getModifiedData($trendCycleComponent, $seasonalAdjustedSeries, $modifiedRemainder);
return $modifiedData;
}
private function getPrelimRemainder(array $centeredRatios, array $prelimSeasonalComponent) : array
{
$remainder = [];
$count = \count($prelimSeasonalComponent);
for ($i = 0; $i < $count; ++$i) {
// +1 since 3x3 MA
$remainder[] = $centeredRatios[$i + 1] / $prelimSeasonalComponent[$i];
}
return $remainder;
}
private function removeOutliers(array $data, float $deviation = 0.5) : array
{
$avg = Average::arithmeticMean($data);
foreach ($data as $key => $value) {
if ($value / $avg - 1 > $deviation) {
$data[$key] = $avg;
}
}
return $data;
}
private function getModifiedCenteredRatios(array $seasonal, array $remainder) : array
{
$centeredRatio = [];
$count = \count($seasonal);
for ($i = 0; $i < $count; ++$i) {
// +1 since 3x3 MA
$centeredRatio[] = $remainder[$i + 1] * $seasonal[$i];
}
return $centeredRatio;
}
private function getTrendCycleEstimation(array $seasonal) : array
{
$count = \count($seasonal);
if ($count >= 12) {
$weight = Average::MAH23;
} elseif ($count >= 6) {
$weight = Average::MAH13;
} else {
$weight = Average::MAH9;
}
// todo: implement
return $seasonal;
}
private function getSeasonalAdjustedSeries(array $seasonal) : array
{
$adjusted = [];
$count = \count($seasonal);
$start = ClassicalDecomposition::getStartOfDecomposition(\count($this->data), $count);
for ($i = 0; $i < $count; ++$i) {
$adjusted[] = $this->data[$start + $i] / $seasonal[$i];
}
return $adjusted;
}
private function getRemainder(array $seasonal, array $trendCycle) : array
{
$remainder = [];
foreach ($seasonal as $key => $e) {
$remainder = $e / $trendCycle[$key];
}
return $remainder;
}
private function getModifiedData(array $trendCycleComponent, array $seasonalAdjustedSeries, array $remainder) : array
{
$data = [];
$count = \count($trendCycleComponent);
for ($i = 0; $i < $count; ++$i) {
$data[] = $trendCycleComponent[$i] * $seasonalAdjustedSeries[$i] * $remainder[$i];
}
return $data;
}
}

View File

@ -1,19 +0,0 @@
<?php
/**
* Orange Management
*
* PHP Version 7.2
*
* @package TBD
* @copyright Dennis Eichhorn
* @license OMS License 1.0
* @version 1.0.0
* @link http://website.orange-management.de
*/
declare(strict_types=1);
namespace phpOMS\Business\Finance\Forecasting;
class ARMA
{
}

View File

@ -1,234 +0,0 @@
<?php
/**
* Orange Management
*
* PHP Version 7.2
*
* @package Framework
* @copyright Dennis Eichhorn
* @license OMS License 1.0
* @version 1.0.0
* @link http://website.orange-management.de
*/
declare(strict_types=1);
namespace phpOMS\Business\Finance\Forecasting;
use phpOMS\Math\Statistic\Average;
/**
* Classical decomposition class.
*
* This can be used to simplify time series patterns for forecasts.
*
* @package Framework
* @license OMS License 1.0
* @link http://website.orange-management.de
* @see https://www.otexts.org/fpp/6/1
* @since 1.0.0
*/
class ClassicalDecomposition
{
/**
* Decomposition mode.
*
* @var int
* @since 1.0.0
*/
public const ADDITIVE = 0;
/**
* Decomposition mode.
*
* @var int
* @since 1.0.0
*/
public const MULTIPLICATIVE = 1;
/**
* Decomposition mode.
*
* @var int
* @since 1.0.0
*/
private $mode = self::ADDITIVE;
/**
* Raw data.
*
* @var array
* @since 1.0.0
*/
private $data = [];
/**
* Order or seasonal period.
*
* @var int
* @since 1.0.0
*/
private $order = 0;
/**
* Raw data size.
*
* @var int
* @since 1.0.0
*/
private $dataSize = 0;
/**
* Constructor.
*
* @param array $data Historic data
* @param int $order Seasonal period (e.g. 4 = quarterly, 12 = monthly, 7 = weekly pattern in daily data)
* @param int $mode Decomposition mode
*
* @since 1.0.0
*/
public function __construct(array $data, int $order, int $mode = self::ADDITIVE)
{
$this->mode = $mode;
$this->data = $data;
$this->order = $order;
$this->dataSize = \count($data);
}
/**
* Get decomposition.
*
* @return array Returns an array containing the trend cycle component, detrended series, seasonal component and remainder component.
*
* @since 1.0.0
*/
public function getDecomposition() : array
{
$trendCycleComponent = self::computeTrendCycle($this->data, $this->order);
$detrendedSeries = self::computeDetrendedSeries($this->data, $trendCycleComponent, $this->mode);
$seasonalComponent = $this->computeSeasonalComponent($detrendedSeries, $this->order);
$remainderComponent = self::computeRemainderComponent($this->data, $trendCycleComponent, $seasonalComponent, $this->mode);
return [
'trendCycleComponent' => $trendCycleComponent,
'detrendedSeries' => $detrendedSeries,
'seasonalComponent' => $seasonalComponent,
'remainderComponent' => $remainderComponent,
];
}
/**
* Calculate trend cycle
*
* @param array $data Data to analyze
* @param int $order Seasonal period (e.g. 4 = quarterly, 12 = monthly, 7 = weekly pattern in daily data)
*
* @return array Total moving average 2 x m-MA
*
* @since 1.0.0
*/
public static function computeTrendCycle(array $data, int $order) : array
{
$mMA = Average::totalMovingAverage($data, $order, null, true);
return $order % 2 === 0 ? Average::totalMovingAverage($mMA, $order, null, true) : $mMA;
}
/**
* Calculate detrended series
*
* @param array $data Data to analyze
* @param array $trendCycleComponent Trend cycle component
* @param int $mode Detrend mode
*
* @return array Detrended series / seasonal normalized data
*
* @since 1.0.0
*/
public static function computeDetrendedSeries(array $data, array $trendCycleComponent, int $mode) : array
{
$detrended = [];
$count = \count($trendCycleComponent);
$start = self::getStartOfDecomposition(\count($data), $count);
for ($i = 0; $i < $count; ++$i) {
$detrended[] = $mode === self::ADDITIVE ? $data[$start + $i] - $trendCycleComponent[$i] : $data[$start + $i] / $trendCycleComponent[$i];
}
return $detrended;
}
/**
* Calculate the data start point for the decomposition
*
* By using averaging methods some initial data get's incorporated into the average which reduces the data points.
*
* @param int $dataSize Original data size
* @param int $trendCycleComponents Trend cycle component size
*
* @return int New data start index
*
* @since 1.0.0
*/
public static function getStartOfDecomposition(int $dataSize, int $trendCycleComponents) : int
{
return (int) (($dataSize - $trendCycleComponents) / 2);
}
/**
* Calculate the seasonal component
*
* Average of the detrended values for every month, quarter, day etc.
*
* @param array $detrendedSeries Detrended series
* @param int $order Seasonal period (e.g. 4 = quarterly, 12 = monthly, 7 = weekly pattern in daily data)
*
* @return array
*
* @since 1.0.0
*/
private function computeSeasonalComponent(array $detrendedSeries, int $order) : array
{
$seasonalComponent = [];
$count = \count($detrendedSeries);
for ($i = 0; $i < $order; ++$i) {
$temp = [];
for ($j = $i; $j < $count; $j += $order) {
$temp[] = $detrendedSeries[$j];
}
$seasonalComponent[] = Average::arithmeticMean($temp);
}
return $seasonalComponent;
}
/**
* Calculate the remainder component or error
*
* @param array $data Raw data
* @param array $trendCycleComponent Trend cycle component
* @param array $seasonalComponent Seasonal component
* @param int $mode Detrend mode
*
* @return array All remainders or absolute errors
*
* @since 1.0.0
*/
public static function computeRemainderComponent(array $data, array $trendCycleComponent, array $seasonalComponent, int $mode = self::ADDITIVE) : array
{
$dataSize = \count($data);
$remainderComponent = [];
$count = \count($trendCycleComponent);
$start = self::getStartOfDecomposition($dataSize, $count);
$seasons = \count($seasonalComponent);
for ($i = 0; $i < $count; ++$i) {
$remainderComponent[] = $mode === self::ADDITIVE ? $data[$start + $i] - $trendCycleComponent[$i] - $seasonalComponent[$i % $seasons] : $data[$start + $i] / ($trendCycleComponent[$i] * $seasonalComponent[$i % $seasons]);
}
return $remainderComponent;
}
}

View File

@ -1,33 +0,0 @@
<?php
/**
* Orange Management
*
* PHP Version 7.2
*
* @package Framework
* @copyright Dennis Eichhorn
* @license OMS License 1.0
* @version 1.0.0
* @link http://website.orange-management.de
*/
declare(strict_types=1);
namespace phpOMS\Business\Finance\Forecasting\ExponentialSmoothing;
use phpOMS\Stdlib\Base\Enum;
/**
* Smoothing enum.
*
* @package Framework
* @license OMS License 1.0
* @link http://website.orange-management.de
* @since 1.0.0
*/
abstract class ErrorType extends Enum
{
public const ALL = 0;
public const NONE = 1;
public const ADDITIVE = 2;
public const MULTIPLICATIVE = 4;
}

View File

@ -1,112 +0,0 @@
<?php
/**
* Orange Management
*
* PHP Version 7.2
*
* @package Framework
* @copyright Dennis Eichhorn
* @license OMS License 1.0
* @version 1.0.0
* @link http://website.orange-management.de
* @see https://www.otexts.org/fpp/7/7
*/
declare(strict_types=1);
namespace phpOMS\Business\Finance\Forecasting\ExponentialSmoothing;
use phpOMS\Business\Finance\Forecasting\SmoothingType;
use phpOMS\Math\Statistic\Average;
use phpOMS\Math\Statistic\Forecast\Error;
class ExponentialSmoothing
{
private $data = [];
private $errors = [];
private $rmse = 0.0;
private $mse = 0.0;
private $mae = 0.0;
private $sse = 0.0;
public function __construct(array $data)
{
$this->data = $data;
}
public function getANN()
{
}
public function getANA()
{
}
public function getANM()
{
}
public function getAAN()
{
}
public function getAAA()
{
}
public function getAAM()
{
}
public function getAMN()
{
}
public function getAMA()
{
}
public function getAMM()
{
}
public function getMNN()
{
}
public function getMNA()
{
}
public function getMNM()
{
}
public function getMAN()
{
}
public function getMAA()
{
}
public function getMAM()
{
}
public function getMMN()
{
}
public function getMMA()
{
}
public function getMMM()
{
}
}

View File

@ -1,33 +0,0 @@
<?php
/**
* Orange Management
*
* PHP Version 7.2
*
* @package Framework
* @copyright Dennis Eichhorn
* @license OMS License 1.0
* @version 1.0.0
* @link http://website.orange-management.de
*/
declare(strict_types=1);
namespace phpOMS\Business\Finance\Forecasting\ExponentialSmoothing;
use phpOMS\Stdlib\Base\Enum;
/**
* Smoothing enum.
*
* @package Framework
* @license OMS License 1.0
* @link http://website.orange-management.de
* @since 1.0.0
*/
abstract class SeasonalType extends Enum
{
public const ALL = 0;
public const NONE = 1;
public const ADDITIVE = 2;
public const MULTIPLICATIVE = 4;
}

View File

@ -1,33 +0,0 @@
<?php
/**
* Orange Management
*
* PHP Version 7.2
*
* @package Framework
* @copyright Dennis Eichhorn
* @license OMS License 1.0
* @version 1.0.0
* @link http://website.orange-management.de
*/
declare(strict_types=1);
namespace phpOMS\Business\Finance\Forecasting\ExponentialSmoothing;
use phpOMS\Stdlib\Base\Enum;
/**
* Smoothing enum.
*
* @package Framework
* @license OMS License 1.0
* @link http://website.orange-management.de
* @since 1.0.0
*/
abstract class TrendType extends Enum
{
public const ALL = 0;
public const NONE = 1;
public const ADDITIVE = 2;
public const MULTIPLICATIVE = 4;
}

View File

@ -1,19 +0,0 @@
<?php
/**
* Orange Management
*
* PHP Version 7.2
*
* @package TBD
* @copyright Dennis Eichhorn
* @license OMS License 1.0
* @version 1.0.0
* @link http://website.orange-management.de
*/
declare(strict_types=1);
namespace phpOMS\Business\Finance\Forecasting;
class GARCH
{
}

View File

@ -1,19 +0,0 @@
<?php
/**
* Orange Management
*
* PHP Version 7.2
*
* @package TBD
* @copyright Dennis Eichhorn
* @license OMS License 1.0
* @version 1.0.0
* @link http://website.orange-management.de
*/
declare(strict_types=1);
namespace phpOMS\Business\Finance\Forecasting;
class MA
{
}

View File

@ -1,19 +0,0 @@
<?php
/**
* Orange Management
*
* PHP Version 7.2
*
* @package TBD
* @copyright Dennis Eichhorn
* @license OMS License 1.0
* @version 1.0.0
* @link http://website.orange-management.de
*/
declare(strict_types=1);
namespace phpOMS\Business\Finance\Forecasting;
class NAR
{
}

View File

@ -1,19 +0,0 @@
<?php
/**
* Orange Management
*
* PHP Version 7.2
*
* @package TBD
* @copyright Dennis Eichhorn
* @license OMS License 1.0
* @version 1.0.0
* @link http://website.orange-management.de
*/
declare(strict_types=1);
namespace phpOMS\Business\Finance\Forecasting;
class NMA
{
}

View File

@ -1,19 +0,0 @@
<?php
/**
* Orange Management
*
* PHP Version 7.2
*
* @package TBD
* @copyright Dennis Eichhorn
* @license OMS License 1.0
* @version 1.0.0
* @link http://website.orange-management.de
*/
declare(strict_types=1);
namespace phpOMS\Business\Finance\Forecasting;
class SARIMA
{
}

View File

@ -1,30 +0,0 @@
<?php
/**
* Orange Management
*
* PHP Version 7.2
*
* @package phpOMS\Business\Finance\Forecasting
* @copyright Dennis Eichhorn
* @license OMS License 1.0
* @version 1.0.0
* @link http://website.orange-management.de
*/
declare(strict_types=1);
namespace phpOMS\Business\Finance\Forecasting;
use phpOMS\Stdlib\Base\Enum;
/**
* Smoothing enum.
*
* @package phpOMS\Business\Finance\Forecasting
* @license OMS License 1.0
* @link http://website.orange-management.de
* @since 1.0.0
*/
abstract class SmoothingType extends Enum
{
public const CENTERED_MOVING_AVERAGE = 1;
}

View File

@ -111,10 +111,12 @@ abstract class SettingsAbstract implements OptionsInterface
return \count($options) > 1 ? $options : \reset($options);
} catch (\PDOException $e) {
// @codeCoverageIgnoreStart
$exception = DatabaseExceptionFactory::createException($e);
$message = DatabaseExceptionFactory::createExceptionMessage($e);
throw new $exception($message);
// @codeCoverageIgnoreEnd
}
}

View File

@ -59,6 +59,7 @@ final class MysqlConnection extends ConnectionAbstract
$this->dbdata = isset($dbdata) ? $dbdata : $this->dbdata;
if (!isset($this->dbdata['db'], $this->dbdata['host'], $this->dbdata['port'], $this->dbdata['database'], $this->dbdata['login'], $this->dbdata['password'])) {
$this->status = DatabaseStatus::FAILURE;
throw new InvalidConnectionConfigException((string) \json_encode($this->dbdata));
}
@ -73,7 +74,7 @@ final class MysqlConnection extends ConnectionAbstract
$this->status = DatabaseStatus::OK;
} catch (\PDOException $e) {
$this->status = DatabaseStatus::MISSING_DATABASE;
$this->con = null;
throw new InvalidConnectionConfigException((string) \json_encode($this->dbdata));
} finally {
$this->dbdata['password'] = '****';
}

View File

@ -146,6 +146,14 @@ class DataMapperAbstract implements DataMapperInterface
*/
protected static $initObjects = [];
/**
* Initialized arrays for cross reference to reduce initialization costs
*
* @var array[]
* @since 1.0.0
*/
protected static $initArrays = [];
/**
* Highest mapper to know when to clear initialized objects
*
@ -304,6 +312,7 @@ class DataMapperAbstract implements DataMapperInterface
// clear parent and objects
if (static::class === self::$parentMapper) {
//self::$initObjects = []; // todo: now all objects are cached for the whole request
//self::$initArrays = []; // todo: now all objects are cached for the whole request
self::$parentMapper = null;
}
}
@ -462,15 +471,13 @@ class DataMapperAbstract implements DataMapperInterface
*
* @since 1.0.0
*/
private static function createModelArray(array $obj)
private static function createModelArray(array &$obj)
{
$query = new Builder(self::$db);
$query->prefix(self::$db->getPrefix())->into(static::$table);
foreach (static::$columns as $key => $column) {
if (isset(static::$hasMany[$key])
|| isset(static::$hasOne[$key])
) {
if (isset(static::$hasMany[$key]) || isset(static::$hasOne[$key])) {
continue;
}
@ -478,7 +485,7 @@ class DataMapperAbstract implements DataMapperInterface
if (\stripos($column['internal'], '/') !== false) {
$path = \explode('/', $column['internal']);
\array_shift($path);
\array_shift($path); // todo: why am I doing this?
$path = \implode('/', $path);
}
@ -489,19 +496,21 @@ class DataMapperAbstract implements DataMapperInterface
$value = self::parseValue($column['type'], $id);
$query->insert($column['name'])->value($value, $column['type']);
break;
} elseif (isset(static::$belongsTo[$path])) {
$id = self::createBelongsToArray($column['internal'], $property);
$value = self::parseValue($column['type'], $id);
$query->insert($column['name'])->value($value, $column['type']);
break;
} elseif ($column['internal'] === $path) {
} elseif ($column['internal'] === $path && $column['name'] !== static::$primaryField) {
$value = self::parseValue($column['type'], $property);
$query->insert($column['name'])->value($value, $column['type']);
break;
}
}
// if a table only has a single column = primary key column. This must be done otherwise the query is empty
if ($query->getType() === QueryType::NONE) {
$query->insert(static::$primaryField)->value(0, static::$columns[static::$primaryField]['type']);
}
self::$db->con->prepare($query->toSql())->execute();
@ -679,7 +688,7 @@ class DataMapperAbstract implements DataMapperInterface
continue;
}
$primaryKey = $obj[static::$columns[static::$primaryField]['internal']];
$primaryKey = $value[$mapper::$columns[$mapper::$primaryField]['internal']];
// already in db
if (!empty($primaryKey)) {
@ -1628,7 +1637,7 @@ class DataMapperAbstract implements DataMapperInterface
foreach (static::$hasOne as $member => $one) {
/** @var string $mapper */
$mapper = static::$hasOne[$member]['mapper'];
$obj[$member] = self::getInitialized($mapper, $obj['member']) ?? $mapper::getArray($obj[$member], RelationType::ALL, $depth);
$obj[$member] = self::getInitializedArray($mapper, $obj['member']) ?? $mapper::getArray($obj[$member], RelationType::ALL, $depth);
}
}
@ -1694,7 +1703,7 @@ class DataMapperAbstract implements DataMapperInterface
foreach (static::$ownsOne as $member => $one) {
/** @var string $mapper */
$mapper = static::$ownsOne[$member]['mapper'];
$obj[$member] = self::getInitialized($mapper, $obj[$member]) ?? $mapper::getArray($obj[$member], RelationType::ALL, $depth);
$obj[$member] = self::getInitializedArray($mapper, $obj[$member]) ?? $mapper::getArray($obj[$member], RelationType::ALL, $depth);
}
}
@ -1760,7 +1769,7 @@ class DataMapperAbstract implements DataMapperInterface
foreach (static::$belongsTo as $member => $one) {
/** @var string $mapper */
$mapper = static::$belongsTo[$member]['mapper'];
$obj[$member] = self::getInitialized($mapper, $obj[$member]) ?? $mapper::get($obj[$member], RelationType::ALL, null, $depth);
$obj[$member] = self::getInitializedArray($mapper, $obj[$member]) ?? $mapper::getArray($obj[$member], RelationType::ALL, $depth);
}
}
@ -1997,14 +2006,14 @@ class DataMapperAbstract implements DataMapperInterface
$obj = [];
foreach ($primaryKey as $key => $value) {
if (self::isInitialized(static::class, $value)) {
$obj[$value] = self::$initObjects[static::class][$value];
if (self::isInitializedArray(static::class, $value)) {
$obj[$value] = self::$initArrays[static::class][$value];
continue;
}
$obj[$value] = self::populateAbstractArray(self::getRaw($value));
self::addInitialized(static::class, $value, $obj[$value]);
self::addInitializedArray(static::class, $value, $obj[$value]);
}
self::fillRelationsArray($obj, $relations, --$depth);
@ -2070,13 +2079,13 @@ class DataMapperAbstract implements DataMapperInterface
* @param mixed $refKey Key
* @param string $ref The field that defines the for
* @param int $relations Load relations
* @param mixed $fill Object to fill
* @param int $depth Relation depth
*
* @return mixed
*
* @since 1.0.0
*/
public static function getForArray($refKey, string $ref, int $relations = RelationType::ALL, $fill = null)
public static function getForArray($refKey, string $ref, int $relations = RelationType::ALL, int $depth = 3)
{
if (!isset(self::$parentMapper)) {
self::$parentMapper = static::class;
@ -2096,7 +2105,7 @@ class DataMapperAbstract implements DataMapperInterface
$toLoad = self::getPrimaryKeysBy($value, self::getColumnByMember($ref));
}
$obj[$value] = self::get($toLoad, $relations, $fill);
$obj[$value] = self::getArray($toLoad, $relations, $depth);
}
return \count($obj) === 1 ? \reset($obj) : $obj;
@ -2356,7 +2365,7 @@ class DataMapperAbstract implements DataMapperInterface
return;
}
if ($relations !== RelationType::NONE) {
if ($relations === RelationType::NONE) {
return;
}
@ -2640,6 +2649,26 @@ class DataMapperAbstract implements DataMapperInterface
self::$initObjects[$mapper][$id] = $obj;
}
/**
* Add initialized object to local cache
*
* @param string $mapper Mapper name
* @param mixed $id Object id
* @param array $obj Model to cache locally
*
* @return void
*
* @since 1.0.0
*/
private static function addInitializedArray(string $mapper, $id, array $obj = null) : void
{
if (!isset(self::$initArrays[$mapper])) {
self::$initArrays[$mapper] = [];
}
self::$initArrays[$mapper][$id] = $obj;
}
/**
* Check if a object is initialized
*
@ -2655,6 +2684,21 @@ class DataMapperAbstract implements DataMapperInterface
return isset(self::$initObjects[$mapper]) && isset(self::$initObjects[$mapper][$id]);
}
/**
* Check if a object is initialized
*
* @param string $mapper Mapper name
* @param mixed $id Object id
*
* @return bool
*
* @since 1.0.0
*/
private static function isInitializedArray(string $mapper, $id) : bool
{
return isset(self::$initArrays[$mapper]) && isset(self::$initArrays[$mapper][$id]);
}
/**
* Get initialized object
*
@ -2670,6 +2714,21 @@ class DataMapperAbstract implements DataMapperInterface
return self::$initObjects[$mapper][$id] ?? null;
}
/**
* Get initialized object
*
* @param string $mapper Mapper name
* @param mixed $id Object id
*
* @return mixed
*
* @since 1.0.0
*/
private static function getInitializedArray(string $mapper, $id)
{
return self::$initArrays[$mapper][$id] ?? null;
}
/**
* Remove initialized object
*
@ -2685,6 +2744,10 @@ class DataMapperAbstract implements DataMapperInterface
if (self::isInitialized($mapper, $id)) {
unset(self::$initObjects[$mapper][$id]);
}
if (self::isInitializedArray($mapper, $id)) {
unset(self::$initArrays[$mapper][$id]);
}
}
/**

View File

@ -383,14 +383,12 @@ final class Builder extends BuilderAbstract
return true;
}
$test = \strtolower($raw);
if (\strpos($test, 'insert') !== false
|| \strpos($test, 'update') !== false
|| \strpos($test, 'drop') !== false
|| \strpos($test, 'delete') !== false
|| \strpos($test, 'create') !== false
|| \strpos($test, 'alter') !== false
if (\stripos($raw, 'insert') !== false
|| \stripos($raw, 'update') !== false
|| \stripos($raw, 'drop') !== false
|| \stripos($raw, 'delete') !== false
|| \stripos($raw, 'create') !== false
|| \stripos($raw, 'alter') !== false
) {
return false;
}
@ -482,10 +480,6 @@ final class Builder extends BuilderAbstract
*/
public function where($columns, $operator = null, $values = null, $boolean = 'and') : Builder
{
if ($operator !== null && !\is_array($operator) && !\in_array(\strtolower($operator), self::OPERATORS)) {
throw new \InvalidArgumentException('Unknown operator.');
}
if (!\is_array($columns)) {
$columns = [$columns];
$operator = [$operator];
@ -1075,10 +1069,10 @@ final class Builder extends BuilderAbstract
*
* @since 1.0.0
*/
public function join($column, string $type = JoinType::JOIN) : Builder
public function join($table, string $type = JoinType::JOIN) : Builder
{
if (\is_string($column) || $column instanceof \Closure) {
$this->joins[] = ['type' => $type, 'column' => $column];
if (\is_string($table) || $table instanceof \Closure) {
$this->joins[] = ['type' => $type, 'table' => $table];
} else {
throw new \InvalidArgumentException();
}
@ -1250,7 +1244,7 @@ final class Builder extends BuilderAbstract
$boolean = [$boolean];
}
$joinCount = \count($this->joins);
$joinCount = \count($this->joins) - 1;
$i = 0;
foreach ($columns as $key => $column) {
@ -1271,6 +1265,30 @@ final class Builder extends BuilderAbstract
return $this;
}
/**
* On.
*
* @return Builder
*
* @since 1.0.0
*/
public function orOn($columns, $operator = null, $values = null) : Builder
{
return $this->on($columns, $operator, $values, 'or');
}
/**
* On.
*
* @return Builder
*
* @since 1.0.0
*/
public function andOn($columns, $operator = null, $values = null) : Builder
{
return $this->on($columns, $operator, $values, 'and');
}
/**
* Merging query.
*

View File

@ -407,7 +407,7 @@ class Grammar extends GrammarAbstract
foreach ($joins as $key => $join) {
$expression .= $join['type'] . ' ';
$expression .= $this->compileSystem($join, $prefix);
$expression .= $this->compileSystem($join['table'], $query->getPrefix());
$expression .= $this->compileOn($query, $query->ons[$key]);
}
@ -431,7 +431,7 @@ class Grammar extends GrammarAbstract
$expression = '';
foreach ($ons as $key => $on) {
$expression .= $this->compileWhereElement($on, $query, $first);
$expression .= $this->compileOnElement($on, $query, $first);
$first = false;
}
@ -439,7 +439,48 @@ class Grammar extends GrammarAbstract
return '';
}
return 'ON ' . $expression;
return ' ON ' . $expression;
}
/**
* Compile where element.
*
* @param array $element Element data
* @param Builder $query Query builder
* @param bool $first Is first element (usefull for nesting)
*
* @return string
*
* @since 1.0.0
*/
protected function compileOnElement(array $element, Builder $query, bool $first = true) : string
{
$expression = '';
if (!$first) {
$expression = ' ' . \strtoupper($element['boolean']) . ' ';
}
if (\is_string($element['column'])) {
// handle bug when no table is specified in the where column
if (\count($query->from) === 1 && \stripos($element['column'], '.') === false) {
$element['column'] = $query->from[0] . '.' . $element['column'];
}
$expression .= $this->compileSystem($element['column'], $query->getPrefix());
} elseif ($element['column'] instanceof \Closure) {
$expression .= $element['column']();
} elseif ($element['column'] instanceof Builder) {
$expression .= '(' . $element['column']->toSql() . ')';
} elseif ($element['column'] instanceof Where) {
$expression .= '(' . $this->compileWhere($element['column'], $query->getPrefix()) . ')';
}
if (isset($element['value'])) {
$expression .= ' ' . \strtoupper($element['operator']) . ' ' . $this->compileSystem($element['value'], $query->getPrefix());
}
return $expression;
}
/**

View File

@ -159,11 +159,13 @@ final class L11nManager
return 'ERROR';
}
} catch (\Throwable $e) {
// @codeCoverageIgnoreStart
FileLogger::getInstance()->warning(FileLogger::MSG_FULL, [
'message' => 'Undefined translation for \'' . $code . '/' . $module . '/' . $translation . '\'.',
]);
return 'ERROR';
// @codeCoverageIgnoreEnd
}
}

View File

@ -189,8 +189,8 @@ class Matrix implements \ArrayAccess, \Iterator
$rlength = \count($rows);
$clength = \count($cols);
for ($i = 0; $i <= $rlength; ++$i) {
for ($j = 0; $j <= $clength; ++$j) {
for ($i = 0; $i < $rlength; ++$i) {
for ($j = 0; $j < $clength; ++$j) {
$X[$i][$j] = $this->matrix[$rows[$i]][$cols[$j]];
}
}
@ -218,7 +218,7 @@ class Matrix implements \ArrayAccess, \Iterator
$length = \count($cols);
for ($i = $iRow; $i <= $lRow; ++$i) {
for ($j = 0; $j <= $length; ++$j) {
for ($j = 0; $j < $length; ++$j) {
$X[$i - $iRow][$j] = $this->matrix[$i][$cols[$j]];
}
}

View File

@ -264,6 +264,28 @@ abstract class C128Abstract
\imagedestroy($res);
}
/**
* Validate the barcode string
*
* @param string $code Barcode string
*
* @return void
*
* @since 1.0.0
*/
public function isValidString(string $barcode) : bool
{
$length = \strlen($barcode);
for ($i = 0; $i < $length; ++$i) {
if (!isset(static::$CODEARRAY[$barcode[$i]]) && !\in_array($barcode[$i], static::$CODEARRAY)) {
return false;
}
}
return true;
}
/**
* Generate weighted code string
*

View File

@ -67,14 +67,16 @@ class ArrayParser
return ArrayParser::serializeArray($value, $depth);
} elseif (\is_string($value)) {
return '\'' . \str_replace('\'', '\\\'', $value) . '\'';
} elseif (\is_scalar($value)) {
return (string) $value;
} elseif ($value === null) {
return 'null';
} elseif (\is_bool($value)) {
return $value ? 'true' : 'false';
} elseif ($value === null) {
return 'null';
} elseif (\is_scalar($value)) {
return (string) $value;
} elseif ($value instanceOf \Serializable) {
return self::parseVariable($value->serialize());
} elseif ($value instanceOf \jsonSerializable) {
return self::parseVariable($value->jsonSerialize());
} else {
throw new \UnexpectedValueException();
}

View File

@ -78,14 +78,14 @@ final class TestUtils
/**
* Get private object member
*
* @param object|string $obj Object to read
* @param string $name Member name to read
* @param object $obj Object to read
* @param string $name Member name to read
*
* @return mixed Returns the member variable value
*
* @since 1.0.0
*/
public static function getMember($obj, string $name)
public static function getMember(object $obj, string $name)
{
$reflectionClass = new \ReflectionClass(\is_string($obj) ? $obj : \get_class($obj));
@ -99,12 +99,7 @@ final class TestUtils
$reflectionProperty->setAccessible(true);
}
$value = null;
if (\is_string($obj)) {
$value = $reflectionProperty->getValue();
} elseif (\is_object($obj)) {
$value = $reflectionProperty->getValue($obj);
}
$value = $reflectionProperty->getValue($obj);
if (!$accessible) {
$reflectionProperty->setAccessible(false);

View File

@ -1,28 +0,0 @@
<?php
/**
* Orange Management
*
* PHP Version 7.2
*
* @package TBD
* @copyright Dennis Eichhorn
* @license OMS License 1.0
* @version 1.0.0
* @link http://website.orange-management.de
*/
declare(strict_types=1);
namespace phpOMS\Validation\Barcode;
use phpOMS\Validation\ValidatorAbstract;
class Barcode extends ValidatorAbstract
{
/**
* {@inheritdoc}
*/
public static function isValid($value, array $constraints = null)
{
}
}

View File

@ -1,28 +0,0 @@
<?php
/**
* Orange Management
*
* PHP Version 7.2
*
* @package TBD
* @copyright Dennis Eichhorn
* @license OMS License 1.0
* @version 1.0.0
* @link http://website.orange-management.de
*/
declare(strict_types=1);
namespace phpOMS\Validation\Barcode;
use phpOMS\Validation\ValidatorAbstract;
class Barcode11 extends ValidatorAbstract
{
/**
* {@inheritdoc}
*/
public static function isValid($value, array $constraints = null)
{
}
}

View File

@ -1,28 +0,0 @@
<?php
/**
* Orange Management
*
* PHP Version 7.2
*
* @package TBD
* @copyright Dennis Eichhorn
* @license OMS License 1.0
* @version 1.0.0
* @link http://website.orange-management.de
*/
declare(strict_types=1);
namespace phpOMS\Validation\Barcode;
use phpOMS\Validation\ValidatorAbstract;
class Barcode128 extends ValidatorAbstract
{
/**
* {@inheritdoc}
*/
public static function isValid($value, array $constraints = null)
{
}
}

View File

@ -1,28 +0,0 @@
<?php
/**
* Orange Management
*
* PHP Version 7.2
*
* @package TBD
* @copyright Dennis Eichhorn
* @license OMS License 1.0
* @version 1.0.0
* @link http://website.orange-management.de
*/
declare(strict_types=1);
namespace phpOMS\Validation\Barcode;
use phpOMS\Validation\ValidatorAbstract;
class Barcode25 extends ValidatorAbstract
{
/**
* {@inheritdoc}
*/
public static function isValid($value, array $constraints = null)
{
}
}

View File

@ -1,28 +0,0 @@
<?php
/**
* Orange Management
*
* PHP Version 7.2
*
* @package TBD
* @copyright Dennis Eichhorn
* @license OMS License 1.0
* @version 1.0.0
* @link http://website.orange-management.de
*/
declare(strict_types=1);
namespace phpOMS\Validation\Barcode;
use phpOMS\Validation\ValidatorAbstract;
class Barcode39 extends ValidatorAbstract
{
/**
* {@inheritdoc}
*/
public static function isValid($value, array $constraints = null)
{
}
}

View File

@ -1,28 +0,0 @@
<?php
/**
* Orange Management
*
* PHP Version 7.2
*
* @package TBD
* @copyright Dennis Eichhorn
* @license OMS License 1.0
* @version 1.0.0
* @link http://website.orange-management.de
*/
declare(strict_types=1);
namespace phpOMS\Validation\Barcode;
use phpOMS\Validation\ValidatorAbstract;
class Barcode93 extends ValidatorAbstract
{
/**
* {@inheritdoc}
*/
public static function isValid($value, array $constraints = null)
{
}
}

View File

@ -1,28 +0,0 @@
<?php
/**
* Orange Management
*
* PHP Version 7.2
*
* @package TBD
* @copyright Dennis Eichhorn
* @license OMS License 1.0
* @version 1.0.0
* @link http://website.orange-management.de
*/
declare(strict_types=1);
namespace phpOMS\Validation\Barcode;
use phpOMS\Validation\ValidatorAbstract;
class BarcodeCodebar extends ValidatorAbstract
{
/**
* {@inheritdoc}
*/
public static function isValid($value, array $constraints = null)
{
}
}

View File

@ -1,28 +0,0 @@
<?php
/**
* Orange Management
*
* PHP Version 7.2
*
* @package TBD
* @copyright Dennis Eichhorn
* @license OMS License 1.0
* @version 1.0.0
* @link http://website.orange-management.de
*/
declare(strict_types=1);
namespace phpOMS\Validation\Barcode;
use phpOMS\Validation\ValidatorAbstract;
class BarcodeDatamatrix extends ValidatorAbstract
{
/**
* {@inheritdoc}
*/
public static function isValid($value, array $constraints = null)
{
}
}

View File

@ -1,28 +0,0 @@
<?php
/**
* Orange Management
*
* PHP Version 7.2
*
* @package TBD
* @copyright Dennis Eichhorn
* @license OMS License 1.0
* @version 1.0.0
* @link http://website.orange-management.de
*/
declare(strict_types=1);
namespace phpOMS\Validation\Barcode;
use phpOMS\Validation\ValidatorAbstract;
class BarcodeEAN extends ValidatorAbstract
{
/**
* {@inheritdoc}
*/
public static function isValid($value, array $constraints = null)
{
}
}

View File

@ -1,28 +0,0 @@
<?php
/**
* Orange Management
*
* PHP Version 7.2
*
* @package TBD
* @copyright Dennis Eichhorn
* @license OMS License 1.0
* @version 1.0.0
* @link http://website.orange-management.de
*/
declare(strict_types=1);
namespace phpOMS\Validation\Barcode;
use phpOMS\Validation\ValidatorAbstract;
class BarcodeMSI extends ValidatorAbstract
{
/**
* {@inheritdoc}
*/
public static function isValid($value, array $constraints = null)
{
}
}

View File

@ -1,28 +0,0 @@
<?php
/**
* Orange Management
*
* PHP Version 7.2
*
* @package TBD
* @copyright Dennis Eichhorn
* @license OMS License 1.0
* @version 1.0.0
* @link http://website.orange-management.de
*/
declare(strict_types=1);
namespace phpOMS\Validation\Barcode;
use phpOMS\Validation\ValidatorAbstract;
class QrCode extends ValidatorAbstract
{
/**
* {@inheritdoc}
*/
public static function isValid($value, array $constraints = null)
{
}
}

View File

@ -1,24 +0,0 @@
<?php
/**
* Orange Management
*
* PHP Version 7.2
*
* @package TBD
* @copyright Dennis Eichhorn
* @license OMS License 1.0
* @version 1.0.0
* @link http://website.orange-management.de
*/
namespace phpOMS\tests\Business\Finance\Forecasting;
use phpOMS\Business\Finance\Forecasting\ARCH;
class ARCHTest extends \PHPUnit\Framework\TestCase
{
public function testPlaceholder()
{
self::markTestIncomplete();
}
}

View File

@ -1,24 +0,0 @@
<?php
/**
* Orange Management
*
* PHP Version 7.2
*
* @package TBD
* @copyright Dennis Eichhorn
* @license OMS License 1.0
* @version 1.0.0
* @link http://website.orange-management.de
*/
namespace phpOMS\tests\Business\Finance\Forecasting;
use phpOMS\Business\Finance\Forecasting\ARFIMA;
class ARFIMATest extends \PHPUnit\Framework\TestCase
{
public function testPlaceholder()
{
self::markTestIncomplete();
}
}

View File

@ -1,24 +0,0 @@
<?php
/**
* Orange Management
*
* PHP Version 7.2
*
* @package TBD
* @copyright Dennis Eichhorn
* @license OMS License 1.0
* @version 1.0.0
* @link http://website.orange-management.de
*/
namespace phpOMS\tests\Business\Finance\Forecasting;
use phpOMS\Business\Finance\Forecasting\ARIMA;
class ARIMATest extends \PHPUnit\Framework\TestCase
{
public function testPlaceholder()
{
self::markTestIncomplete();
}
}

View File

@ -1,24 +0,0 @@
<?php
/**
* Orange Management
*
* PHP Version 7.2
*
* @package TBD
* @copyright Dennis Eichhorn
* @license OMS License 1.0
* @version 1.0.0
* @link http://website.orange-management.de
*/
namespace phpOMS\tests\Business\Finance\Forecasting;
use phpOMS\Business\Finance\Forecasting\ARMA;
class ARMATest extends \PHPUnit\Framework\TestCase
{
public function testPlaceholder()
{
self::markTestIncomplete();
}
}

View File

@ -1,24 +0,0 @@
<?php
/**
* Orange Management
*
* PHP Version 7.2
*
* @package TBD
* @copyright Dennis Eichhorn
* @license OMS License 1.0
* @version 1.0.0
* @link http://website.orange-management.de
*/
namespace phpOMS\tests\Business\Finance\Forecasting;
use phpOMS\Business\Finance\Forecasting\AR;
class ARTest extends \PHPUnit\Framework\TestCase
{
public function testPlaceholder()
{
self::markTestIncomplete();
}
}

View File

@ -1,24 +0,0 @@
<?php
/**
* Orange Management
*
* PHP Version 7.2
*
* @package TBD
* @copyright Dennis Eichhorn
* @license OMS License 1.0
* @version 1.0.0
* @link http://website.orange-management.de
*/
namespace phpOMS\tests\Business\Finance\Forecasting;
use phpOMS\Business\Finance\Forecasting\ClassicalDecomposition;
class ClassicalDecompositionTest extends \PHPUnit\Framework\TestCase
{
public function testPlaceholder()
{
self::markTestIncomplete();
}
}

View File

@ -1,24 +0,0 @@
<?php
/**
* Orange Management
*
* PHP Version 7.2
*
* @package TBD
* @copyright Dennis Eichhorn
* @license OMS License 1.0
* @version 1.0.0
* @link http://website.orange-management.de
*/
namespace phpOMS\tests\Business\Finance\Forecasting\ExponentialSmoothing;
use phpOMS\Business\Finance\Forecasting\ExponentialSmoothing\ExponentialSmoothing;
class ExponentialSmoothingTest extends \PHPUnit\Framework\TestCase
{
public function testPlaceholder()
{
self::markTestIncomplete();
}
}

View File

@ -1,30 +0,0 @@
<?php
/**
* Orange Management
*
* PHP Version 7.2
*
* @package TBD
* @copyright Dennis Eichhorn
* @license OMS License 1.0
* @version 1.0.0
* @link http://website.orange-management.de
*/
namespace phpOMS\tests\Business\Finance\Forecasting\ExponentialSmoothing;
use phpOMS\Business\Finance\Forecasting\ExponentialSmoothing\SeasonalType;
class SeasonalTypeTest extends \PHPUnit\Framework\TestCase
{
public function testEnums()
{
self::assertEquals(4, \count(SeasonalType::getConstants()));
self::assertEquals(SeasonalType::getConstants(), array_unique(SeasonalType::getConstants()));
self::assertEquals(0, SeasonalType::ALL);
self::assertEquals(1, SeasonalType::NONE);
self::assertEquals(2, SeasonalType::ADDITIVE);
self::assertEquals(4, SeasonalType::MULTIPLICATIVE);
}
}

View File

@ -1,30 +0,0 @@
<?php
/**
* Orange Management
*
* PHP Version 7.2
*
* @package TBD
* @copyright Dennis Eichhorn
* @license OMS License 1.0
* @version 1.0.0
* @link http://website.orange-management.de
*/
namespace phpOMS\tests\Business\Finance\Forecasting\ExponentialSmoothing;
use phpOMS\Business\Finance\Forecasting\ExponentialSmoothing\TrendType;
class TrendTypeTest extends \PHPUnit\Framework\TestCase
{
public function testEnums()
{
self::assertEquals(4, \count(TrendType::getConstants()));
self::assertEquals(TrendType::getConstants(), array_unique(TrendType::getConstants()));
self::assertEquals(0, TrendType::ALL);
self::assertEquals(1, TrendType::NONE);
self::assertEquals(2, TrendType::ADDITIVE);
self::assertEquals(4, TrendType::MULTIPLICATIVE);
}
}

View File

@ -1,24 +0,0 @@
<?php
/**
* Orange Management
*
* PHP Version 7.2
*
* @package TBD
* @copyright Dennis Eichhorn
* @license OMS License 1.0
* @version 1.0.0
* @link http://website.orange-management.de
*/
namespace phpOMS\tests\Business\Finance\Forecasting;
use phpOMS\Business\Finance\Forecasting\GARCH;
class GARCHTest extends \PHPUnit\Framework\TestCase
{
public function testPlaceholder()
{
self::markTestIncomplete();
}
}

View File

@ -1,24 +0,0 @@
<?php
/**
* Orange Management
*
* PHP Version 7.2
*
* @package TBD
* @copyright Dennis Eichhorn
* @license OMS License 1.0
* @version 1.0.0
* @link http://website.orange-management.de
*/
namespace phpOMS\tests\Business\Finance\Forecasting;
use phpOMS\Business\Finance\Forecasting\MA;
class MATest extends \PHPUnit\Framework\TestCase
{
public function testPlaceholder()
{
self::markTestIncomplete();
}
}

View File

@ -1,24 +0,0 @@
<?php
/**
* Orange Management
*
* PHP Version 7.2
*
* @package TBD
* @copyright Dennis Eichhorn
* @license OMS License 1.0
* @version 1.0.0
* @link http://website.orange-management.de
*/
namespace phpOMS\tests\Business\Finance\Forecasting;
use phpOMS\Business\Finance\Forecasting\NAR;
class NARTest extends \PHPUnit\Framework\TestCase
{
public function testPlaceholder()
{
self::markTestIncomplete();
}
}

View File

@ -1,24 +0,0 @@
<?php
/**
* Orange Management
*
* PHP Version 7.2
*
* @package TBD
* @copyright Dennis Eichhorn
* @license OMS License 1.0
* @version 1.0.0
* @link http://website.orange-management.de
*/
namespace phpOMS\tests\Business\Finance\Forecasting;
use phpOMS\Business\Finance\Forecasting\NMA;
class NMATest extends \PHPUnit\Framework\TestCase
{
public function testPlaceholder()
{
self::markTestIncomplete();
}
}

View File

@ -1,24 +0,0 @@
<?php
/**
* Orange Management
*
* PHP Version 7.2
*
* @package TBD
* @copyright Dennis Eichhorn
* @license OMS License 1.0
* @version 1.0.0
* @link http://website.orange-management.de
*/
namespace phpOMS\tests\Business\Finance\Forecasting;
use phpOMS\Business\Finance\Forecasting\SARIMA;
class SARIMATest extends \PHPUnit\Framework\TestCase
{
public function testPlaceholder()
{
self::markTestIncomplete();
}
}

View File

@ -1,27 +0,0 @@
<?php
/**
* Orange Management
*
* PHP Version 7.2
*
* @package TBD
* @copyright Dennis Eichhorn
* @license OMS License 1.0
* @version 1.0.0
* @link http://website.orange-management.de
*/
namespace phpOMS\tests\Business\Finance\Forecasting;
use phpOMS\Business\Finance\Forecasting\SmoothingType;
class SmoothingTypeTest extends \PHPUnit\Framework\TestCase
{
public function testEnums()
{
self::assertEquals(1, \count(SmoothingType::getConstants()));
self::assertEquals(SmoothingType::getConstants(), array_unique(SmoothingType::getConstants()));
self::assertEquals(1, SmoothingType::CENTERED_MOVING_AVERAGE);
}
}

View File

@ -95,4 +95,15 @@ class MysqlConnectionTest extends \PHPUnit\Framework\TestCase
$mysql = new MysqlConnection($db);
}
/**
* @expectedException \phpOMS\DataStorage\Database\Exception\InvalidConnectionConfigException
*/
public function testInvalidDatabaseName()
{
$db = $GLOBALS['CONFIG']['db']['core']['masters']['admin'];
$db['db'] = 'invalid';
$mysql = new MysqlConnection($db);
}
}

View File

@ -19,14 +19,62 @@ use phpOMS\DataStorage\Database\DatabasePool;
use phpOMS\tests\DataStorage\Database\TestModel\BaseModel;
use phpOMS\tests\DataStorage\Database\TestModel\BaseModelMapper;
use phpOMS\tests\DataStorage\Database\TestModel\ManyToManyDirectModelMapper;
class DataMapperAbstractTest extends \PHPUnit\Framework\TestCase
{
protected $model = null;
protected $model = null;
protected $modelArray = null;
protected function setUp()
{
$this->model = new BaseModel();
$this->model = new BaseModel();
$this->modelArray = [
'id' => 0,
'string' => 'Base',
'int' => 11,
'bool' => false,
'null' => null,
'float' => 1.3,
'json' => [1, 2, 3],
'jsonSerializable' => new class implements \JsonSerializable {
public function jsonSerialize()
{
return [1, 2, 3];
}
},
'datetime' => new \DateTime('2005-10-11'),
'ownsOneSelf' => [
'id' => 0,
'string' => 'OwnsOne',
],
'belongsToOne' => [
'id' => 0,
'string' => 'BelongsTo',
],
'hasManyDirect' => [
[
'id' => 0,
'string' => 'ManyToManyDirect',
'to' => 0,
],
[
'id' => 0,
'string' => 'ManyToManyDirect',
'to' => 0,
]
],
'hasManyRelations' => [
[
'id' => 0,
'string' => 'ManyToManyRel',
],
[
'id' => 0,
'string' => 'ManyToManyRel',
]
],
];
$GLOBALS['dbpool']->get()->con->prepare(
'CREATE TABLE `oms_test_base` (
@ -104,6 +152,12 @@ class DataMapperAbstractTest extends \PHPUnit\Framework\TestCase
self::assertGreaterThan(0, $this->model->id);
}
public function testCreateArray()
{
self::assertGreaterThan(0, BaseModelMapper::createArray($this->modelArray));
self::assertGreaterThan(0, $this->modelArray['id']);
}
public function testRead()
{
$id = BaseModelMapper::create($this->model);
@ -128,6 +182,37 @@ class DataMapperAbstractTest extends \PHPUnit\Framework\TestCase
self::assertEquals(\reset($this->model->hasManyRelations)->string, \reset($modelR->hasManyRelations)->string);
self::assertEquals($this->model->ownsOneSelf->string, $modelR->ownsOneSelf->string);
self::assertEquals($this->model->belongsToOne->string, $modelR->belongsToOne->string);
$for = ManyToManyDirectModelMapper::getFor($id, 'to');
self::assertEquals(\reset($this->model->hasManyDirect)->string, \reset($for)->string);
self::assertEquals(1, count(BaseModelMapper::getAll()));
}
public function testReadArray()
{
$id = BaseModelMapper::createArray($this->modelArray);
$modelR = BaseModelMapper::getArray($id);
self::assertEquals($this->modelArray['id'], $modelR['id']);
self::assertEquals($this->modelArray['string'], $modelR['string']);
self::assertEquals($this->modelArray['int'], $modelR['int']);
self::assertEquals($this->modelArray['bool'], $modelR['bool']);
self::assertEquals($this->modelArray['float'], $modelR['float']);
self::assertEquals($this->modelArray['null'], $modelR['null']);
self::assertEquals($this->modelArray['datetime']->format('Y-m-d'), $modelR['datetime']->format('Y-m-d'));
self::assertEquals(2, \count($modelR['hasManyDirect']));
self::assertEquals(2, \count($modelR['hasManyRelations']));
self::assertEquals(\reset($this->modelArray['hasManyDirect'])['string'], \reset($modelR['hasManyDirect'])['string']);
self::assertEquals(\reset($this->modelArray['hasManyRelations'])['string'], \reset($modelR['hasManyRelations'])['string']);
self::assertEquals($this->modelArray['ownsOneSelf']['string'], $modelR['ownsOneSelf']['string']);
self::assertEquals($this->modelArray['belongsToOne']['string'], $modelR['belongsToOne']['string']);
$for = ManyToManyDirectModelMapper::getForArray($id, 'to');
self::assertEquals(\reset($this->modelArray['hasManyDirect'])['string'], \reset($for)['string']);
self::assertEquals(1, count(BaseModelMapper::getAllArray()));
}
public function testUpdate()
@ -155,6 +240,31 @@ class DataMapperAbstractTest extends \PHPUnit\Framework\TestCase
// todo test update relations
}
/*public function testUpdateArray()
{
$id = BaseModelMapper::createArray($this->modelArray);
$modelR = BaseModelMapper::getArray($id);
$modelR['string'] = 'Update';
$modelR['int'] = '321';
$modelR['bool'] = true;
$modelR['float'] = 3.15;
$modelR['null'] = null;
$modelR['datetime'] = new \DateTime('now');
$id2 = BaseModelMapper::updateArray($modelR);
$modelR2 = BaseModelMapper::getArray($id2);
self::assertEquals($modelR['string'], $modelR2['string']);
self::assertEquals($modelR['int'], $modelR2['int']);
self::assertEquals($modelR['bool'], $modelR2['bool']);
self::assertEquals($modelR['float'], $modelR2['float']);
self::assertEquals($modelR['null'], $modelR2['null']);
self::assertEquals($modelR['datetime']->format('Y-m-d'), $modelR2['datetime']->format('Y-m-d'));
// todo test update relations
}*/
public function testDelete()
{
$id = BaseModelMapper::create($this->model);

View File

@ -189,6 +189,65 @@ class BuilderTest extends \PHPUnit\Framework\TestCase
self::assertEquals($sql, $query->select('a.test')->from('a')->where('a.test', '=', ':testWhere')->whereIn('a.test2', ['a', ':bValue', 'c'], 'or')->toSql());
}
public function testMysqlJoins()
{
$query = new Builder($this->con);
$sql = 'SELECT `a`.`test` FROM `a` JOIN `b` ON `a`.`id` = `b`.`id` WHERE `a`.`test` = 1;';
self::assertEquals($sql, $query->select('a.test')->from('a')->join('b')->on('a.id', '=', 'b.id')->where('a.test', '=', 1)->toSql());
$query = new Builder($this->con);
$sql = 'SELECT `a`.`test` FROM `a` JOIN `b` ON `a`.`id` = `b`.`id` OR `a`.`id2` = `b`.`id2` WHERE `a`.`test` = 1;';
self::assertEquals($sql, $query->select('a.test')->from('a')->join('b')->on('a.id', '=', 'b.id')->orOn('a.id2', '=', 'b.id2')->where('a.test', '=', 1)->toSql());
$query = new Builder($this->con);
$sql = 'SELECT `a`.`test` FROM `a` JOIN `b` ON `a`.`id` = `b`.`id` AND `a`.`id2` = `b`.`id2` WHERE `a`.`test` = 1;';
self::assertEquals($sql, $query->select('a.test')->from('a')->join('b')->on('a.id', '=', 'b.id')->andOn('a.id2', '=', 'b.id2')->where('a.test', '=', 1)->toSql());
$query = new Builder($this->con);
$sql = 'SELECT `a`.`test` FROM `a` LEFT JOIN `b` ON `a`.`id` = `b`.`id` WHERE `a`.`test` = 1;';
self::assertEquals($sql, $query->select('a.test')->from('a')->leftJoin('b')->on('a.id', '=', 'b.id')->where('a.test', '=', 1)->toSql());
$query = new Builder($this->con);
$sql = 'SELECT `a`.`test` FROM `a` LEFT OUTER JOIN `b` ON `a`.`id` = `b`.`id` WHERE `a`.`test` = 1;';
self::assertEquals($sql, $query->select('a.test')->from('a')->leftOuterJoin('b')->on('a.id', '=', 'b.id')->where('a.test', '=', 1)->toSql());
$query = new Builder($this->con);
$sql = 'SELECT `a`.`test` FROM `a` LEFT INNER JOIN `b` ON `a`.`id` = `b`.`id` WHERE `a`.`test` = 1;';
self::assertEquals($sql, $query->select('a.test')->from('a')->leftInnerJoin('b')->on('a.id', '=', 'b.id')->where('a.test', '=', 1)->toSql());
$query = new Builder($this->con);
$sql = 'SELECT `a`.`test` FROM `a` RIGHT JOIN `b` ON `a`.`id` = `b`.`id` WHERE `a`.`test` = 1;';
self::assertEquals($sql, $query->select('a.test')->from('a')->rightJoin('b')->on('a.id', '=', 'b.id')->where('a.test', '=', 1)->toSql());
$query = new Builder($this->con);
$sql = 'SELECT `a`.`test` FROM `a` RIGHT OUTER JOIN `b` ON `a`.`id` = `b`.`id` WHERE `a`.`test` = 1;';
self::assertEquals($sql, $query->select('a.test')->from('a')->rightOuterJoin('b')->on('a.id', '=', 'b.id')->where('a.test', '=', 1)->toSql());
$query = new Builder($this->con);
$sql = 'SELECT `a`.`test` FROM `a` RIGHT INNER JOIN `b` ON `a`.`id` = `b`.`id` WHERE `a`.`test` = 1;';
self::assertEquals($sql, $query->select('a.test')->from('a')->rightInnerJoin('b')->on('a.id', '=', 'b.id')->where('a.test', '=', 1)->toSql());
$query = new Builder($this->con);
$sql = 'SELECT `a`.`test` FROM `a` OUTER JOIN `b` ON `a`.`id` = `b`.`id` WHERE `a`.`test` = 1;';
self::assertEquals($sql, $query->select('a.test')->from('a')->outerJoin('b')->on('a.id', '=', 'b.id')->where('a.test', '=', 1)->toSql());
$query = new Builder($this->con);
$sql = 'SELECT `a`.`test` FROM `a` INNER JOIN `b` ON `a`.`id` = `b`.`id` WHERE `a`.`test` = 1;';
self::assertEquals($sql, $query->select('a.test')->from('a')->innerJoin('b')->on('a.id', '=', 'b.id')->where('a.test', '=', 1)->toSql());
$query = new Builder($this->con);
$sql = 'SELECT `a`.`test` FROM `a` CROSS JOIN `b` ON `a`.`id` = `b`.`id` WHERE `a`.`test` = 1;';
self::assertEquals($sql, $query->select('a.test')->from('a')->crossJoin('b')->on('a.id', '=', 'b.id')->where('a.test', '=', 1)->toSql());
$query = new Builder($this->con);
$sql = 'SELECT `a`.`test` FROM `a` FULL JOIN `b` ON `a`.`id` = `b`.`id` WHERE `a`.`test` = 1;';
self::assertEquals($sql, $query->select('a.test')->from('a')->fullJoin('b')->on('a.id', '=', 'b.id')->where('a.test', '=', 1)->toSql());
$query = new Builder($this->con);
$sql = 'SELECT `a`.`test` FROM `a` FULL OUTER JOIN `b` ON `a`.`id` = `b`.`id` WHERE `a`.`test` = 1;';
self::assertEquals($sql, $query->select('a.test')->from('a')->fullOuterJoin('b')->on('a.id', '=', 'b.id')->where('a.test', '=', 1)->toSql());
}
public function testMysqlInsert()
{
$query = new Builder($this->con);
@ -198,6 +257,7 @@ class BuilderTest extends \PHPUnit\Framework\TestCase
$query = new Builder($this->con);
$sql = 'INSERT INTO `a` (`test`, `test2`) VALUES (1, \'test\');';
self::assertEquals($sql, $query->insert('test', 'test2')->into('a')->values(1, 'test')->toSql());
self::assertEquals([[1, 'test']], $query->getValues());
$query = new Builder($this->con);
$sql = 'INSERT INTO `a` (`test`, `test2`) VALUES (:test, :test2);';
@ -267,4 +327,49 @@ class BuilderTest extends \PHPUnit\Framework\TestCase
$query = new Builder($this->con, true);
$query->delete();
}
/**
* @expectedException \InvalidArgumentException
*/
public function testInvalidWhereOperator()
{
$query = new Builder($this->con, true);
$query->where('a', 'invalid', 'b');
}
/**
* @expectedException \InvalidArgumentException
*/
public function testInvalidJoinTable()
{
$query = new Builder($this->con, true);
$query->join(null);
}
/**
* @expectedException \InvalidArgumentException
*/
public function testInvalidJoinOperator()
{
$query = new Builder($this->con, true);
$query->join('b')->on('a', 'invalid', 'b');
}
/**
* @expectedException \InvalidArgumentException
*/
public function testInvalidOrOrderType()
{
$query = new Builder($this->con, true);
$query->orderBy('a', 1);
}
/**
* @expectedException \InvalidArgumentException
*/
public function testInvalidOrColumnType()
{
$query = new Builder($this->con, true);
$query->orderBy(null, 'DESC');
}
}

View File

@ -74,6 +74,22 @@ class DispatcherTest extends \PHPUnit\Framework\TestCase
);
}
public function testPathMethodInArray()
{
$l11nManager = new L11nManager();
$localization = new Localization($l11nManager);
self::assertTrue(
!empty(
$this->app->dispatcher->dispatch(
['dest' => 'phpOMS\tests\Dispatcher\TestController:testFunction'],
new Request(new Http(''), $localization),
new Response($localization)
)
)
);
}
public function testPathStatic()
{
$l11nManager = new L11nManager();
@ -126,6 +142,14 @@ class DispatcherTest extends \PHPUnit\Framework\TestCase
$this->app->dispatcher->dispatch('phpOMS\tests\Dispatcher\TestControllers::testFunctionStatic');
}
/**
* @expectedException \Exception
*/
public function testInvalidControllerFunction()
{
$this->app->dispatcher->dispatch('phpOMS\tests\Dispatcher\TestController::testFunctionStaticINVALID');
}
/**
* @expectedException \UnexpectedValueException
*/

View File

@ -70,6 +70,8 @@ class EventManagerTest extends \PHPUnit\Framework\TestCase
self::assertTrue($event->detach('group'));
self::assertEquals(0, $event->count());
self::assertFalse($event->trigger('group'));
self::assertFalse($event->detach('group'));
}
public function testRemove()

View File

@ -131,5 +131,35 @@ class LocalizationTest extends \PHPUnit\Framework\TestCase
$localization->setTemperature(TemperatureType::FAHRENHEIT);
self::assertEquals(TemperatureType::FAHRENHEIT, $localization->getTemperature());
$localization->setWeight([1]);
$localization->setLength([1]);
$localization->setArea([1]);
$localization->setVolume([1]);
$localization->setSpeed([1]);
self::assertEquals([1], $localization->getWeight());
self::assertEquals([1], $localization->getLength());
self::assertEquals([1], $localization->getArea());
self::assertEquals([1], $localization->getVolume());
self::assertEquals([1], $localization->getSpeed());
}
public function testLocalizationLoading()
{
$localization = new Localization();
$localization->loadFromLanguage(ISO639x1Enum::_EN);
self::assertEquals(ISO4217CharEnum::_USD, $localization->getCurrency());
$localization->loadFromLanguage(ISO639x1Enum::_AA);
self::assertEquals(ISO4217CharEnum::_USD, $localization->getCurrency());
}
/**
* @expectedException \phpOMS\Stdlib\Base\Exception\InvalidEnumValue
*/
public function testInvalidLocalizationLoading()
{
$localization = new Localization();
$localization->loadFromLanguage('INVALID');
}
}

View File

@ -14,6 +14,7 @@
namespace phpOMS\tests\Math\Matrix;
use phpOMS\Math\Matrix\Matrix;
use phpOMS\Math\Matrix\Vector;
class MatrixTest extends \PHPUnit\Framework\TestCase
{
@ -79,6 +80,27 @@ class MatrixTest extends \PHPUnit\Framework\TestCase
self::assertEquals(-306, $B->det());
}
public function testSymmetry()
{
$B = new Matrix();
$B->setMatrix([
[1, 7, 3],
[7, -2, -5],
[3, -5, 6],
]);
self::assertTrue($B->isSymmetric());
$C = new Matrix();
$C->setMatrix([
[1, 7, 4],
[7, -2, -5],
[3, -5, 6],
]);
self::assertFalse($C->isSymmetric());
}
public function testTranspose()
{
$B = new Matrix();
@ -90,6 +112,21 @@ class MatrixTest extends \PHPUnit\Framework\TestCase
self::assertEquals([[6, 4], [1, -2], [1, 5],], $B->transpose()->toArray());
}
public function testSolve()
{
$A = new Matrix();
$A->setMatrix([
[25, 15, -5],
[15, 17, 0],
[-5, 0, 11],
]);
$vec = new Vector();
$vec->setMatrix([[40], [49], [28]]);
self::assertEquals([[1], [2], [3]], $A->solve($vec)->toArray(), '', 0.2);
}
public function testRank()
{
$B = new Matrix();
@ -201,6 +238,37 @@ class MatrixTest extends \PHPUnit\Framework\TestCase
self::assertFalse(isset($A[6]));
}
public function testSubMatrix()
{
$A = new Matrix();
$A->setMatrix([
[0, 1, 2, 3],
[4, 5, 6, 7],
[8, 9, 10, 11],
[12, 13, 14, 15],
]);
self::assertEquals(
[[1, 2], [5, 6], [9, 10]],
$A->getSubMatrix(0, 2, 1, 2)->toArray()
);
self::assertEquals(
[[1, 2], [5, 6], [9, 10]],
$A->getSubMatrixByColumnsRows([0, 1, 2], [1, 2])->toArray()
);
self::assertEquals(
[[1, 2], [5, 6], [9, 10]],
$A->getSubMatrixByColumns(0, 2, [1, 2])->toArray()
);
self::assertEquals(
[[1, 2], [5, 6], [9, 10]],
$A->getSubMatrixByRows([0, 1, 2], 1, 2)->toArray()
);
}
/**
* @expectedException \phpOMS\Math\Matrix\Exception\InvalidDimensionException
*/

View File

@ -31,5 +31,6 @@ class ModuleAbstractTest extends \PHPUnit\Framework\TestCase
self::assertEquals([1, 2], $moduleClass->getDependencies());
self::assertEquals(2, $moduleClass::MODULE_ID);
self::assertEquals('1.2.3', $moduleClass::MODULE_VERSION);
self::assertEquals([], $moduleClass::getLocalization('invalid', 'invalid'));
}
}

View File

@ -62,4 +62,16 @@ class RouteVerbTest extends \PHPUnit\Framework\TestCase
)
);
}
public function testFileIntegrity()
{
self::assertTrue(PhpCode::validateFileIntegrity(__DIR__ . '/Sample/hasDeprecated.php', \md5_file(__DIR__ . '/Sample/hasDeprecated.php')));
self::assertFalse(PhpCode::validateFileIntegrity(__DIR__ . '/Sample/hasUnicode.php', \md5_file(__DIR__ . '/Sample/hasDeprecated.php')));
}
public function testStringIntegrity()
{
self::assertTrue(PhpCode::validateStringIntegrity('aa', 'aa'));
self::assertFalse(PhpCode::validateStringIntegrity('aa', 'aA'));
}
}

View File

@ -29,4 +29,10 @@ class C128aTest extends \PHPUnit\Framework\TestCase
self::assertTrue(\file_exists($path));
}
public function testValidString()
{
self::assertTrue(C128a::isValidString('ABCDEFG0123+-'));
self::assertFalse(C128a::isValidString('ABCDE~FG0123+-'));
}
}

View File

@ -29,4 +29,9 @@ class C128bTest extends \PHPUnit\Framework\TestCase
self::assertTrue(\file_exists($path));
}
public function testValidString()
{
self::assertTrue(C128b::isValidString('ABCDE~FG0123+-'));
}
}

View File

@ -29,4 +29,10 @@ class C25Test extends \PHPUnit\Framework\TestCase
self::assertTrue(\file_exists($path));
}
public function testValidString()
{
self::assertTrue(C25::isValidString('1234567890'));
self::assertFalse(C25::isValidString('1234567A890'));
}
}

View File

@ -29,4 +29,10 @@ class C39Test extends \PHPUnit\Framework\TestCase
self::assertTrue(\file_exists($path));
}
public function testValidString()
{
self::assertTrue(C39::isValidString('ABCDEFG0123+-'));
self::assertFalse(C39::isValidString('ABC(DEFG0123+-'));
}
}

View File

@ -29,4 +29,10 @@ class CodebarTest extends \PHPUnit\Framework\TestCase
self::assertTrue(\file_exists($path));
}
public function testValidString()
{
self::assertTrue(Codebar::isValidString('412163'));
self::assertFalse(Codebar::isValidString('412163F'));
}
}

View File

@ -48,5 +48,7 @@ class NumericTest extends \PHPUnit\Framework\TestCase
self::assertEquals('123', Numeric::convertBase('443', '01234', '0123456789'));
self::assertEquals('123', Numeric::convertBase('7B', '0123456789ABCDEF', '0123456789'));
self::assertEquals('123', Numeric::convertBase('173', '01234567', '0123456789'));
self::assertEquals('173', Numeric::convertBase('173', '01234567', '01234567'));
}
}

View File

@ -19,6 +19,15 @@ class ArrayParserTest extends \PHPUnit\Framework\TestCase
{
public function testParser()
{
$serializable = new class implements \Serializable {
public function serialize() { return 2; }
public function unserialize($raw) {}
};
$jsonSerialize = new class implements \jsonSerializable {
public function jsonSerialize() { return [6, 7]; }
};
$array = [
'string' => 'test',
0 => 1,
@ -29,8 +38,32 @@ class ArrayParserTest extends \PHPUnit\Framework\TestCase
0 => 'a',
1 => 'b',
],
5 => $serializable,
6 => $jsonSerialize,
];
self::assertEquals($array, eval('return '. ArrayParser::serializeArray($array) . ';'));
$expected = [
'string' => 'test',
0 => 1,
2 => true,
'string2' => 1.3,
3 => null,
4 => [
0 => 'a',
1 => 'b',
],
5 => $serializable->serialize(),
6 => $jsonSerialize->jsonSerialize(),
];
self::assertEquals($expected, eval('return '. ArrayParser::serializeArray($array) . ';'));
}
/**
* @expectedException \UnexpectedValueException
*/
public function testInvalidValueType()
{
ArrayParser::parseVariable(new class {});
}
}

View File

@ -42,6 +42,7 @@ class TaskAbstractTest extends \PHPUnit\Framework\TestCase
self::assertInstanceOf('\DateTime', $this->class->getNextRunTime());
self::assertInstanceOf('\DateTime', $this->class->getLastRuntime());
self::assertEquals('', $this->class->getComment());
self::assertEquals('', $this->class->getInterval());
}
public function testGetSet()