diff --git a/.travis.yml b/.travis.yml
index eff6130..f1bd310 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -11,7 +11,7 @@ before_install:
- composer global require hirak/prestissimo
install:
-- travis_wait 30 composer install
+ - travis_wait 30 composer install -v
script:
- php ./vendor/bin/phpunit
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 65d5b3c..7dca1b4 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -2,6 +2,13 @@
Common and useful classes, methods, exceptions etc.
+# 0.1.4
+
+1. Phing > update configuration
+2. Utilities > Date > update descriptions of methods
+3. Docker > docker-compose.yml > add "phpunit" service > used to run PHPUnit's tests
+4. Reflection > setPropertiesValues() method > sets values of properties in given object
+
# 0.1.3
1. Tests > refactoring & minor improvements
diff --git a/README.md b/README.md
index 94a0f44..bcc9fc0 100644
--- a/README.md
+++ b/README.md
@@ -2,7 +2,7 @@
Common and useful classes, methods, exceptions etc.
-[](https://travis-ci.org/meritoo/common-library) [](https://packagist.org/packages/meritoo/common-library) [](https://github.com/meritoo/common-library) [](https://github.com/meritoo/common-library) [](https://coveralls.io/github/meritoo/common-library?branch=master)
+[](https://img.shields.io/badge/php-%3E%3D5.6-blue.svg) [](https://travis-ci.org/meritoo/common-library) [](https://packagist.org/packages/meritoo/common-library) [](https://github.com/meritoo/common-library) [](https://github.com/meritoo/common-library) [](https://coveralls.io/github/meritoo/common-library?branch=master)
# Installation
diff --git a/VERSION b/VERSION
index b1e80bb..845639e 100644
--- a/VERSION
+++ b/VERSION
@@ -1 +1 @@
-0.1.3
+0.1.4
diff --git a/build.xml b/build.xml
index d65367b..594cf4b 100644
--- a/build.xml
+++ b/build.xml
@@ -1,46 +1,30 @@
+
-
+
-
+
-
+
+ depends="build:app,
+ build:tests"
+ />
-
-
+
+
-
-
-
-
+
+
diff --git a/docker-compose.yml b/docker-compose.yml
index e13bca3..6224f02 100644
--- a/docker-compose.yml
+++ b/docker-compose.yml
@@ -1,6 +1,9 @@
version: '3'
services:
+ #
+ # Required to run project
+ #
php:
image: ${DOCKER_CONTAINER_OWNER}/${DOCKER_CONTAINER_PROJECT}-php
container_name: ${DOCKER_CONTAINER_OWNER}-${DOCKER_CONTAINER_PROJECT}-php
@@ -9,12 +12,22 @@ services:
build:
context: ./docker/config
args:
- - TIMEZONE=${TIMEZONE}
+ - TIMEZONE=${TIMEZONE}
volumes:
- - .:/project:cached
+ - .:/project:cached
composer:
image: ${DOCKER_CONTAINER_OWNER}/${DOCKER_CONTAINER_PROJECT}-php
container_name: ${DOCKER_CONTAINER_OWNER}-${DOCKER_CONTAINER_PROJECT}-composer
- entrypoint: composer
+ entrypoint: php -d memory_limit=-1 /usr/local/bin/composer
volumes:
- - .:/project:cached
+ - .:/project:cached
+ #
+ # Required to run PHPUnit's tests
+ #
+ phpunit:
+ image: ${DOCKER_CONTAINER_OWNER}/${DOCKER_CONTAINER_PROJECT}-php
+ container_name: ${DOCKER_CONTAINER_OWNER}-${DOCKER_CONTAINER_PROJECT}-phpunit
+ entrypoint: ./vendor/bin/phpunit
+ command: --version
+ volumes:
+ - .:/project:cached
diff --git a/docker/config/Dockerfile b/docker/config/Dockerfile
index df4b0f8..277e672 100644
--- a/docker/config/Dockerfile
+++ b/docker/config/Dockerfile
@@ -98,7 +98,7 @@ ENV COMPOSER_ALLOW_SUPERUSER 1
#
RUN php -r "copy('https://getcomposer.org/installer', 'composer-setup.php');" \
&& php -r "if (hash_file('SHA384', 'composer-setup.php') === \
- '544e09ee996cdf60ece3804abc52599c22b1f40f4323403c44d44fdfdd586475ca9813a858088ffbc1f233e9b180f061') { echo \
+ '93b54496392c062774670ac18b134c3b3a95e5a5e5c8f1a9f115f203b75bf9a129d5daa8ba6a13e2cc8a1da0806388a8') { echo \
'Installer verified'; } else { echo 'Installer corrupt'; unlink('composer-setup.php'); } echo PHP_EOL;" \
&& php composer-setup.php --install-dir=/usr/local/bin --filename=composer \
&& php -r "unlink('composer-setup.php');" \
diff --git a/docs/Development.md b/docs/Development.md
index f8165a8..7f60fb0 100644
--- a/docs/Development.md
+++ b/docs/Development.md
@@ -15,11 +15,11 @@ Development-related information
docker-compose up -d
```
-2. Install packages by running command:
+2. Rebuild project by running command (installs packages, prepares required directories and runs tests):
- ```bash
- docker-compose run composer install
- ```
+ ```bash
+ docker-compose exec php phing
+ ```
> [What is Docker?](https://www.docker.com/what-docker)
@@ -28,7 +28,7 @@ Development-related information
Available as `composer` service. You can run any Composer's command using the `composer` service:
```bash
-docker-compose run composer
+docker-compose run --rm composer [command]
```
Examples below.
@@ -36,25 +36,25 @@ Examples below.
##### Install packages
```bash
-docker-compose run composer install
+docker-compose run --rm composer install
```
##### Update packages
```bash
-docker-compose run composer update
+docker-compose run --rm composer update
```
##### Add package
```bash
-docker-compose run composer require /
+docker-compose run --rm composer require [vendor]/[package]
```
##### Remove package
```bash
-docker-compose run composer remove /
+docker-compose run --rm composer remove [vendor]/[package]
```
# Coding Standards Fixer
@@ -65,6 +65,12 @@ Fix coding standard by running command:
docker-compose exec php php-cs-fixer fix
```
+or
+
+```bash
+docker-compose exec php phing -f phing/tests.xml build:fix-coding-standards
+```
+
Omit cache and run the Fixer from scratch by running command:
```bash
@@ -77,37 +83,35 @@ docker-compose exec php rm .php_cs.cache && docker-compose exec php php-cs-fixer
### Prerequisites
-Install required packages by running command: `docker-compose run composer install`.
+Install required packages by running command: `docker-compose run --rm composer install`.
-### Running tests
+### Running [PHPUnit](https://phpunit.de) tests
-#### Simply & quick, without code coverage
-
-Tests are running using Docker and `php` service defined in `docker-compose.yml`. Example:
+##### Easy (with code coverage)
```bash
-docker-compose exec php phpunit --no-coverage
+docker-compose run --rm phpunit --verbose
```
-You can also run them in container. In this case you have to run 2 commands:
-1. Enter container:
-
- ```bash
- docker-compose exec php bash
- ```
-
-2. Run tests:
-
- ```bash
- phpunit --no-coverage
- ```
-
-#### With code coverage
+or
```bash
-docker-compose exec php phpunit
+docker-compose exec php phing -f phing/tests.xml test:phpunit
```
+##### Quick (without code coverage)
+
+```bash
+docker-compose run --rm phpunit --verbose --no-coverage
+```
+
+# Versions of packages
+
+### squizlabs/php_codesniffer
+
+I have to use [squizlabs/php_codesniffer](https://packagist.org/packages/squizlabs/php_codesniffer) `^2.9` instead of
+`^3.3`, because [Phing doesn't support 3.x PHP_CodeSniffer](https://github.com/phingofficial/phing/issues/716).
+
# Other
Rebuild project and run tests by running command:
diff --git a/phing/app.xml b/phing/app.xml
index 23852ba..5688569 100644
--- a/phing/app.xml
+++ b/phing/app.xml
@@ -1,98 +1,184 @@
-
+
+
-
+
-
+
-
+
+
+
+
+ />
-
-
-
-
+ depends="app:clean,
+ app:composer:self-update,
+ app:composer:install,
+ app:composer:validate,
+ app:checkout"
+ />
+
+
-
+
+
+
-
-
-
-
+
-
+
-
+
-
+
-
-
-
-
-
+
+
-
-
-
+
+
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
-
-
-
+
+
+
diff --git a/phing/composer-install.sh b/phing/composer-install.sh
new file mode 100644
index 0000000..1a951a2
--- /dev/null
+++ b/phing/composer-install.sh
@@ -0,0 +1,20 @@
+#!/bin/sh
+
+EXPECTED_SIGNATURE="$(curl -L https://composer.github.io/installer.sig)"
+# Original line (with wget):
+# EXPECTED_SIGNATURE="$(wget -q -O - https://composer.github.io/installer.sig)"
+
+php -r "copy('https://getcomposer.org/installer', 'composer-setup.php');"
+ACTUAL_SIGNATURE="$(php -r "echo hash_file('SHA384', 'composer-setup.php');")"
+
+if [ "$EXPECTED_SIGNATURE" != "$ACTUAL_SIGNATURE" ]
+then
+ >&2 echo 'ERROR: Invalid installer signature'
+ rm composer-setup.php
+ exit 1
+fi
+
+php composer-setup.php --quiet
+RESULT=$?
+rm composer-setup.php
+exit $RESULT
diff --git a/phing/filesets.xml b/phing/filesets.xml
new file mode 100644
index 0000000..c3aea0c
--- /dev/null
+++ b/phing/filesets.xml
@@ -0,0 +1,36 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/phing/properties.dist b/phing/properties.dist
index dc0463c..bcb2fb5 100644
--- a/phing/properties.dist
+++ b/phing/properties.dist
@@ -1,19 +1,3 @@
-# --------------------------------------------------------------------------------
-# Information
-# --------------------------------------------------------------------------------
-
-# Property files contain key/value pairs
-# key = value
-#
-# Property keys may contain alphanumeric chars and colons, but
-# not special chars. This way you can create pseudo-namespaces
-#
-# You can refer to values of other properties by enclosing their keys in "${}".
-# Example: dir.js = ${dir.web}/js
-#
-# Everything behind the equal sign is the value, you do
-# not have to enclose strings: text=This is some text, Your OS is ${php.os}
-
# --------------------------------------------------------------------------------
# Common, e.g. default environment
# --------------------------------------------------------------------------------
@@ -22,10 +6,6 @@
#
env = dev
-# Install assets using symlinks
-#
-assets.installWithSymlink = true
-
# Clear cache with the "warmup" option
#
# The cache:clear command should always be called with the --no-warmup option. Warmup should be done via the cache:warmup command.
@@ -40,67 +20,63 @@ cache.clearWithWarmup = false
# Composer
# --------------------------------------------------------------------------------
-composer.download_command = php -r "eval('?>'.file_get_contents('https://getcomposer.org/installer'));"
-
-# Path to composer executable or composer.phar file
+# Command used to download Composer
#
-composer.path = composer.phar
-#composer.path = /usr/local/bin/composer
+composer.download_command = bash ${project.basedir}/phing/composer-install.sh
+
+# Path to composer executable or downloaded composer.phar file
+#
+composer.path = ${project.basedir}/composer.phar
# Path to php executable used by composer
#
composer.php = php
-# Self update of the composer
-#
-composer.self-update = false
-
-# Validate the composer.json file
-#
-composer.validate = false
-
# --------------------------------------------------------------------------------
# Directories
# --------------------------------------------------------------------------------
# System directories
#
-dir.data = ${project.basedir}/data
dir.src = ${project.basedir}/src
+dir.var = ${project.basedir}/tests/Resources/var
+dir.cache = ${dir.var}/cache
+dir.logs = ${dir.var}/log
+dir.sessions = ${dir.var}/sessions
+dir.data = ${project.basedir}/data
dir.tests = ${project.basedir}/tests
-# --------------------------------------------------------------------------------
# Build directories
-# --------------------------------------------------------------------------------
-
+#
dir.build = ${project.basedir}/build
-dir.reports = ${dir.build}/logs
+dir.reports = ${dir.build}/reports
dir.reports.pdepend = ${dir.reports}/pdepend
dir.reports.coverage = ${dir.reports}/phpunit_coverage
-#
-# Disabled, because unnecessary right now
-# phpdocumentor/phpdocumentor cannot be installed via Composer
-#
-# Meritoo
-# 2017-02-22
-#
-#dir.docs = ${dir.build}/docs
-#dir.docs.phpdoc2 = ${dir.docs}/phpdoc2
-# --------------------------------------------------------------------------------
# Data directories
-# --------------------------------------------------------------------------------
-
+#
+dir.data.tests = ${dir.data}/tests
dir.data.temporary = ${dir.data}/tmp
+# Docker directories
+#
+dir.docker = ${project.basedir}/docker
+dir.docker.data = ${dir.docker}/data/db
+dir.docker.logs = ${dir.docker}/logs/nginx
+
# --------------------------------------------------------------------------------
# Testing
# --------------------------------------------------------------------------------
-# Path of the framework used to run unit tests
-#
-tests.framework.path = ./vendor/bin/phpunit --verbose --no-coverage --testdox
-
# Path of the PHP Coding Standards Fixer (http://cs.sensiolabs.org)
#
-phpCsFixer.path = ./vendor/bin/php-cs-fixer
+tests.cs_fixer.command = ./vendor/bin/php-cs-fixer fix --verbose
+
+# Test database path
+#
+tests.database = ${dir.data.temporary}/database.sqlite
+
+# Paths of frameworks used to run tests:
+# - PHPUnit (unit tests)
+#
+tests.phpunit.command = ./vendor/bin/phpunit --verbose
diff --git a/phing/tests.xml b/phing/tests.xml
index edd288b..92f6190 100644
--- a/phing/tests.xml
+++ b/phing/tests.xml
@@ -1,230 +1,133 @@
-
-
-
+
+
-
+
-
+
-
+
-
-
-
-
-
-
+
+
+
+
+
+
-
+
-
+ depends="build:fix-coding-standards,
+ build:check,
+ build:test,
+ app:checkout"
+ />
-
-
-
-
-
-
+
+
-
-
-
-
-
-
+ depends="check:cs,
+ check:md,
+ check:cpd,
+ check:depend,
+ check:loc"
+ />
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+ depends="test:phpunit"
+ />
-
-
-
+
-
-
-
-
+
+
+
+
-
-
+
-
-
+
+
-
-
-
-
+
-
-
-
+
+
+
-
-
+
-
-
-
-
+
+
+
+
-
-
+
-
+
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
-
-
-
+
+
+
diff --git a/phpunit.xml.dist b/phpunit.xml.dist
index b6d38e5..f54393f 100644
--- a/phpunit.xml.dist
+++ b/phpunit.xml.dist
@@ -1,28 +1,11 @@
+
@@ -31,23 +14,17 @@
- ./tests/
+ tests/
- ./src/
+ src/
-
-
- performance
-
-
-
-
+
diff --git a/src/Exception/Base/UnknownTypeException.php b/src/Exception/Base/UnknownTypeException.php
index ea860ca..43abda2 100644
--- a/src/Exception/Base/UnknownTypeException.php
+++ b/src/Exception/Base/UnknownTypeException.php
@@ -23,9 +23,9 @@ abstract class UnknownTypeException extends Exception
/**
* Creates exception
*
- * @param string|int $unknownType The unknown type of something (value of constant)
- * @param BaseType $typeInstance An instance of class that contains type of the something
- * @param string $typeName Name of the something
+ * @param mixed $unknownType The unknown type of something (value of constant)
+ * @param BaseType $typeInstance An instance of class that contains type of the something
+ * @param string $typeName Name of the something
* @return UnknownTypeException
*/
public static function create($unknownType, BaseType $typeInstance, $typeName)
@@ -35,7 +35,7 @@ abstract class UnknownTypeException extends Exception
$allTypes = $typeInstance->getAll();
$types = Arrays::values2string($allTypes, '', ', ');
- $message = sprintf(sprintf($template, $unknownType, $typeName, $types));
+ $message = sprintf($template, $unknownType, $typeName, $types);
return new static($message);
}
diff --git a/src/Traits/Test/Base/BaseTestCaseTrait.php b/src/Traits/Test/Base/BaseTestCaseTrait.php
index 2ca9539..74eea20 100644
--- a/src/Traits/Test/Base/BaseTestCaseTrait.php
+++ b/src/Traits/Test/Base/BaseTestCaseTrait.php
@@ -14,13 +14,11 @@ use Meritoo\Common\Exception\Type\UnknownOopVisibilityTypeException;
use Meritoo\Common\Type\OopVisibilityType;
use Meritoo\Common\Utilities\Miscellaneous;
use ReflectionClass;
-use ReflectionException;
use ReflectionMethod;
use stdClass;
/**
- * BaseTestCaseTrait
- * Created on 2017-11-02
+ * Trait for the base test case
*
* @author Meritoo
* @copyright Meritoo
@@ -173,7 +171,6 @@ trait BaseTestCaseTrait
* @param int $requiredArgumentsCount (optional) Expected count/amount of required arguments
* of the verified method
* @throws UnknownOopVisibilityTypeException
- * @throws ReflectionException
*
* Attention. 2nd argument, the $method, may be:
* - string - name of the method
@@ -230,8 +227,6 @@ trait BaseTestCaseTrait
* @param int $argumentsCount (optional) Expected count/amount of arguments of the verified method
* @param int $requiredArgumentsCount (optional) Expected count/amount of required arguments of the verified
* method
- * @throws ReflectionException
- * @throws UnknownOopVisibilityTypeException
*/
protected static function assertConstructorVisibilityAndArguments(
$classNamespace,
@@ -245,14 +240,19 @@ trait BaseTestCaseTrait
$reflection = new ReflectionClass($classNamespace);
$method = $reflection->getConstructor();
- static::assertMethodVisibilityAndArguments($classNamespace, $method, $visibilityType, $argumentsCount, $requiredArgumentsCount);
+ static::assertMethodVisibilityAndArguments(
+ $classNamespace,
+ $method,
+ $visibilityType,
+ $argumentsCount,
+ $requiredArgumentsCount
+ );
}
/**
* Asserts that class with given namespace has no constructor
*
* @param string $classNamespace Namespace of class that contains constructor to verify
- * @throws ReflectionException
*/
protected static function assertHasNoConstructor($classNamespace)
{
diff --git a/src/Type/Base/BaseType.php b/src/Type/Base/BaseType.php
index 73ec524..ec8dafa 100644
--- a/src/Type/Base/BaseType.php
+++ b/src/Type/Base/BaseType.php
@@ -43,7 +43,7 @@ abstract class BaseType
/**
* Returns information if given type is correct
*
- * @param string $type The type to check
+ * @param mixed $type The type to check
* @return bool
*/
public function isCorrectType($type)
diff --git a/src/Utilities/Date.php b/src/Utilities/Date.php
index 40b76db..99293eb 100644
--- a/src/Utilities/Date.php
+++ b/src/Utilities/Date.php
@@ -64,8 +64,7 @@ class Date
const DATE_DIFFERENCE_UNIT_YEARS = 'years';
/**
- * Returns start and end date for given period.
- * The dates are returned in an array with indexes 'start' and 'end'.
+ * Returns date's period (that contains start and end date) for given period
*
* @param int $period The period, type of period. One of DatePeriod class constants, e.g. DatePeriod::LAST_WEEK.
* @throws Exception
@@ -531,11 +530,15 @@ class Date
/**
* Returns random date based on given start date
*
- * @param DateTime $startDate The start date. Start of the random date.
- * @param int $start (optional) Start of random partition
- * @param int $end (optional) End of random partition
+ * @param DateTime $startDate (optional) Beginning of the random date. If not provided, current date will
+ * be used (default behaviour).
+ * @param int $start (optional) Start of random partition. If not provided, 1 will be used
+ * (default behaviour).
+ * @param int $end (optional) End of random partition. If not provided, 100 will be used
+ * (default behaviour).
* @param string $intervalTemplate (optional) Template used to build date interval. The placeholder is replaced
- * with next, iterated value.
+ * with next, iterated value. If not provided, "P%sD" will be used (default
+ * behaviour).
* @throws Exception
* @return DateTime
*/
@@ -569,10 +572,11 @@ class Date
* @param mixed $value The value which maybe is a date
* @param bool $allowCompoundFormats (optional) If is set to true, the compound formats used to create an
* instance of DateTime class are allowed (e.g. "now", "last day of next
- * month", "yyyy"). Otherwise - not and every incorrect value is refused.
+ * month", "yyyy"). Otherwise - not and every incorrect value is refused
+ * (default behaviour).
* @param string $dateFormat (optional) Format of date used to verify if given value is actually a date.
* It should be format matched to the given value, e.g. "Y-m-d H:i" for
- * "2015-01-01 10:00" value.
+ * "2015-01-01 10:00" value. Default: "Y-m-d".
* @return DateTime|bool
*/
public static function getDateTime($value, $allowCompoundFormats = false, $dateFormat = 'Y-m-d')
diff --git a/src/Utilities/Reflection.php b/src/Utilities/Reflection.php
index b03a0bd..c3fbafe 100644
--- a/src/Utilities/Reflection.php
+++ b/src/Utilities/Reflection.php
@@ -662,7 +662,7 @@ class Reflection
}
/**
- * Sets value of given property
+ * Sets value of given property in given object
*
* @param mixed $object Object that should contains given property
* @param string $property Name of the property
@@ -692,4 +692,25 @@ class Reflection
$reflectionProperty->setAccessible(false);
}
}
+
+ /**
+ * Sets values of properties in given object
+ *
+ * @param mixed $object Object that should contains given property
+ * @param array $propertiesValues Key-value pairs, where key - name of the property, value - value of the property
+ */
+ public static function setPropertiesValues($object, array $propertiesValues)
+ {
+ /*
+ * No properties?
+ * Nothing to do
+ */
+ if (empty($propertiesValues)) {
+ return;
+ }
+
+ foreach ($propertiesValues as $property => $value) {
+ static::setPropertyValue($object, $property, $value);
+ }
+ }
}
diff --git a/src/Utilities/Repository.php b/src/Utilities/Repository.php
index fbc8d12..32dc95c 100644
--- a/src/Utilities/Repository.php
+++ b/src/Utilities/Repository.php
@@ -177,10 +177,13 @@ class Repository
$direction = 'ASC'
) {
$alias = 'qb';
+ $queryBuilder = $repository->createQueryBuilder($alias);
- return $repository
- ->createQueryBuilder($alias)
- ->orderBy(sprintf('%s.%s', $alias, $property), $direction);
+ if (empty($property)) {
+ return $queryBuilder;
+ }
+
+ return $queryBuilder->orderBy(sprintf('%s.%s', $alias, $property), $direction);
}
/**
diff --git a/tests/Resources/var/cache/.gitkeep b/tests/Resources/var/cache/.gitkeep
new file mode 100644
index 0000000..e69de29
diff --git a/tests/Resources/var/log/.gitkeep b/tests/Resources/var/log/.gitkeep
new file mode 100644
index 0000000..e69de29
diff --git a/tests/Resources/var/sessions/.gitkeep b/tests/Resources/var/sessions/.gitkeep
new file mode 100644
index 0000000..e69de29
diff --git a/tests/Utilities/ReflectionTest.php b/tests/Utilities/ReflectionTest.php
index 69ce170..8763716 100644
--- a/tests/Utilities/ReflectionTest.php
+++ b/tests/Utilities/ReflectionTest.php
@@ -82,8 +82,15 @@ class ReflectionTest extends BaseTestCase
* Class with namespace containing name of class (duplicated string)
*/
if (class_exists('Symfony\Bundle\SecurityBundle\SecurityBundle')) {
- self::assertEquals('Symfony\Bundle\SecurityBundle\SecurityBundle', Reflection::getClassName('Symfony\Bundle\SecurityBundle\SecurityBundle'));
- self::assertEquals('SecurityBundle', Reflection::getClassName('Symfony\Bundle\SecurityBundle\SecurityBundle', true));
+ self::assertEquals(
+ 'Symfony\Bundle\SecurityBundle\SecurityBundle',
+ Reflection::getClassName('Symfony\Bundle\SecurityBundle\SecurityBundle')
+ );
+
+ self::assertEquals(
+ 'SecurityBundle',
+ Reflection::getClassName('Symfony\Bundle\SecurityBundle\SecurityBundle', true)
+ );
}
}
@@ -115,7 +122,10 @@ class ReflectionTest extends BaseTestCase
* Class with namespace containing name of class (duplicated string)
*/
if (class_exists('Symfony\Bundle\SecurityBundle\SecurityBundle')) {
- self::assertEquals('Symfony\Bundle\SecurityBundle', Reflection::getClassNamespace('Symfony\Bundle\SecurityBundle\SecurityBundle'));
+ self::assertEquals(
+ 'Symfony\Bundle\SecurityBundle',
+ Reflection::getClassNamespace('Symfony\Bundle\SecurityBundle\SecurityBundle')
+ );
}
}
@@ -183,11 +193,11 @@ class ReflectionTest extends BaseTestCase
public function testGetMethods()
{
- self::assertEquals(1, count(Reflection::getMethods(B::class, true)));
- self::assertEquals(3, count(Reflection::getMethods(B::class)));
- self::assertEquals(2, count(Reflection::getMethods(A::class)));
- self::assertEquals(2, count(Reflection::getMethods(C::class, true)));
- self::assertEquals(5, count(Reflection::getMethods(C::class)));
+ self::assertCount(1, Reflection::getMethods(B::class, true));
+ self::assertCount(3, Reflection::getMethods(B::class));
+ self::assertCount(2, Reflection::getMethods(A::class));
+ self::assertCount(2, Reflection::getMethods(C::class, true));
+ self::assertCount(5, Reflection::getMethods(C::class));
}
/**
@@ -235,9 +245,20 @@ class ReflectionTest extends BaseTestCase
public function testGetPropertiesUsingFilter()
{
- self::assertCount(1, Reflection::getProperties(B::class, ReflectionProperty::IS_PROTECTED));
- self::assertCount(0, Reflection::getProperties(B::class, ReflectionProperty::IS_PRIVATE));
- self::assertCount(1, Reflection::getProperties(B::class, ReflectionProperty::IS_PRIVATE, true));
+ self::assertCount(
+ 1,
+ Reflection::getProperties(B::class, ReflectionProperty::IS_PROTECTED)
+ );
+
+ self::assertCount(
+ 0,
+ Reflection::getProperties(B::class, ReflectionProperty::IS_PRIVATE)
+ );
+
+ self::assertCount(
+ 1,
+ Reflection::getProperties(B::class, ReflectionProperty::IS_PRIVATE, true)
+ );
}
public function testGetPropertiesWithParents()
@@ -484,9 +505,7 @@ class ReflectionTest extends BaseTestCase
public function testSetPropertyValueUsingNotExistingProperty($object, $property)
{
$this->setExpectedException(NotExistingPropertyException::class);
-
- $object = new \stdClass();
- Reflection::setPropertyValue($object, 'test', 'test test test');
+ Reflection::setPropertyValue($object, $property, 'test test test');
}
/**
@@ -506,6 +525,43 @@ class ReflectionTest extends BaseTestCase
static::assertSame($newValue, $value);
}
+ public function testSetPropertiesValuesWithoutProperties()
+ {
+ $object = new G();
+ Reflection::setPropertiesValues($object, []);
+
+ static::assertSame($object->getFirstName(), 'John');
+ static::assertSame($object->getLastName(), 'Scott');
+ }
+
+ /**
+ * @param mixed $object Object that should contains given property
+ * @param array $propertiesValues Key-value pairs, where key - name of the property, value - value of the property
+ *
+ * @dataProvider provideObjectAndNotExistingProperties
+ */
+ public function testSetPropertiesValuesUsingNotExistingProperties($object, array $propertiesValues)
+ {
+ $this->setExpectedException(NotExistingPropertyException::class);
+ Reflection::setPropertiesValues($object, $propertiesValues);
+ }
+
+ /**
+ * @param mixed $object Object that should contains given property
+ * @param array $propertiesValues Key-value pairs, where key - name of the property, value - value of the property
+ *
+ * @dataProvider provideObjectAndPropertiesValues
+ */
+ public function testSetPropertiesValues($object, array $propertiesValues)
+ {
+ Reflection::setPropertiesValues($object, $propertiesValues);
+
+ foreach ($propertiesValues as $property => $value) {
+ $realValue = Reflection::getPropertyValue($object, $property);
+ static::assertSame($value, $realValue);
+ }
+ }
+
/**
* Provides invalid class and trait
*
@@ -588,4 +644,104 @@ class ReflectionTest extends BaseTestCase
'Smith',
];
}
+
+ /**
+ * Provides object and not existing properties
+ *
+ * @return Generator
+ */
+ public function provideObjectAndNotExistingProperties()
+ {
+ yield[
+ new \stdClass(),
+ [
+ 'test' => 1,
+ ],
+ ];
+
+ yield[
+ new A(),
+ [
+ 'test' => 2,
+ ],
+ ];
+
+ yield[
+ new B(),
+ [
+ 'firstName' => '',
+ ],
+ ];
+ }
+
+ /**
+ * Provides object and its new values of properties
+ *
+ * @return Generator
+ */
+ public function provideObjectAndPropertiesValues()
+ {
+ yield[
+ new A(),
+ [
+ 'count' => 123,
+ ],
+ ];
+
+ yield[
+ new B(),
+ [
+ 'name' => 'test test',
+ ],
+ ];
+
+ yield[
+ new G(),
+ [
+ 'firstName' => 'Jane',
+ ],
+ ];
+
+ yield[
+ new G(),
+ [
+ 'lastName' => 'Smith',
+ ],
+ ];
+
+ yield[
+ new G(),
+ [
+ 'firstName' => 'Jane',
+ 'lastName' => 'Brown',
+ ],
+ ];
+
+ yield[
+ new F(
+ 123,
+ 'New York',
+ 'USA',
+ 'UnKnown'
+ ),
+ [
+ 'gInstance' => new G(),
+ ],
+ ];
+
+ yield[
+ new F(
+ 123,
+ 'New York',
+ 'USA',
+ 'UnKnown',
+ 'Mary',
+ 'Brown'
+ ),
+ [
+ 'country' => 'Canada',
+ 'accountBalance' => 456,
+ ],
+ ];
+ }
}
diff --git a/tests/Utilities/RepositoryTest.php b/tests/Utilities/RepositoryTest.php
index aafeadb..0ccedd4 100644
--- a/tests/Utilities/RepositoryTest.php
+++ b/tests/Utilities/RepositoryTest.php
@@ -8,6 +8,10 @@
namespace Meritoo\Common\Test\Utilities;
+use Doctrine\ORM\EntityManagerInterface;
+use Doctrine\ORM\EntityRepository;
+use Doctrine\ORM\Query\Expr\OrderBy;
+use Doctrine\ORM\QueryBuilder;
use Generator;
use Meritoo\Common\Test\Base\BaseTestCase;
use Meritoo\Common\Test\Utilities\Repository\Sortable;
@@ -160,7 +164,7 @@ class RepositoryTest extends BaseTestCase
/**
* @param array $items Objects who have "getPosition()" and "setPosition()" methods or arrays
- * @param bool $max (optional) If is set to true, maximum value is returned. Otherwise - minimum.
+ * @param bool $max If is set to true, maximum value is returned. Otherwise - minimum.
* @param int $expected Extreme position (max or min) of given items
*
* @dataProvider provideArraysWithoutExtremePositionToGetExtremePosition
@@ -170,12 +174,122 @@ class RepositoryTest extends BaseTestCase
static::assertEquals($expected, Repository::getExtremePosition($items, $max));
}
- public function testGetExtremePositionUsingObjects()
+ /**
+ * @param array $items Objects who have "getPosition()" and "setPosition()" methods or arrays
+ * @param bool $max If is set to true, maximum value is returned. Otherwise - minimum.
+ * @param int $expected Extreme position (max or min) of given items
+ *
+ * @dataProvider provideArraysWithExtremePositionToGetExtremePosition
+ */
+ public function testGetExtremePositionUsingArraysWithExtremePosition(array $items, $max, $expected)
{
+ static::assertEquals($expected, Repository::getExtremePosition($items, $max));
}
- public function testGetEntityOrderedQueryBuilder()
+ /**
+ * @param array $items Objects who have "getPosition()" and "setPosition()" methods or arrays
+ * @param bool $max If is set to true, maximum value is returned. Otherwise - minimum.
+ * @param int $expected Extreme position (max or min) of given items
+ *
+ * @dataProvider provideObjectsWithoutExtremePositionToGetExtremePosition
+ */
+ public function testGetExtremePositionUsingObjectsWithoutExtremePosition(array $items, $max, $expected)
{
+ static::assertEquals($expected, Repository::getExtremePosition($items, $max));
+ }
+
+ /**
+ * @param array $items Objects who have "getPosition()" and "setPosition()" methods or arrays
+ * @param bool $max If is set to true, maximum value is returned. Otherwise - minimum.
+ * @param int $expected Extreme position (max or min) of given items
+ *
+ * @dataProvider provideObjectsWithExtremePositionToGetExtremePosition
+ */
+ public function testGetExtremePositionUsingObjectsWithExtremePosition(array $items, $max, $expected)
+ {
+ static::assertEquals($expected, Repository::getExtremePosition($items, $max));
+ }
+
+ public function testGetEntityOrderedQueryBuilderUsingDefaults()
+ {
+ $entityManager = $this->getMock(EntityManagerInterface::class);
+
+ $entityRepository = $this
+ ->getMockBuilder(EntityRepository::class)
+ ->disableOriginalConstructor()
+ ->setMethods([
+ 'createQueryBuilder',
+ ])
+ ->getMock();
+
+ $expectedQueryBuilder = new QueryBuilder($entityManager);
+ $expectedQueryBuilder->from('any_table_name', 'qb');
+
+ $entityRepository
+ ->expects(static::once())
+ ->method('createQueryBuilder')
+ ->willReturn($expectedQueryBuilder);
+
+ $queryBuilder = Repository::getEntityOrderedQueryBuilder($entityRepository);
+ $selectDQLPart = $queryBuilder->getDQLPart('select');
+ $whereDQLPart = $queryBuilder->getDQLPart('where');
+ $orderDQLPart = $queryBuilder->getDQLPart('orderBy');
+
+ /* @var OrderBy $orderBy */
+ $orderBy = $orderDQLPart[0];
+
+ static::assertInstanceOf(QueryBuilder::class, $queryBuilder);
+ static::assertArraySubset(['qb'], $queryBuilder->getRootAliases());
+ static::assertSame([], $selectDQLPart);
+ static::assertNull($whereDQLPart);
+ static::assertSame(['qb.name ASC'], $orderBy->getParts());
+ }
+
+ /**
+ * @param string $property Name of property used by the ORDER BY clause
+ * @param string $direction Direction used by the ORDER BY clause ("ASC" or "DESC")
+ * @param string $expectedOrderBy Expected ORDER BY clause
+ *
+ * @dataProvider providePropertyAndDirectionToGetEntityOrderedQueryBuilder
+ */
+ public function testGetEntityOrderedQueryBuilder($property, $direction, $expectedOrderBy)
+ {
+ $entityManager = $this->getMock(EntityManagerInterface::class);
+
+ $entityRepository = $this
+ ->getMockBuilder(EntityRepository::class)
+ ->disableOriginalConstructor()
+ ->setMethods([
+ 'createQueryBuilder',
+ ])
+ ->getMock();
+
+ $expectedQueryBuilder = new QueryBuilder($entityManager);
+ $expectedQueryBuilder->from('any_table_name', 'qb');
+
+ $entityRepository
+ ->expects(static::once())
+ ->method('createQueryBuilder')
+ ->willReturn($expectedQueryBuilder);
+
+ $queryBuilder = Repository::getEntityOrderedQueryBuilder($entityRepository, $property, $direction);
+ $selectDQLPart = $queryBuilder->getDQLPart('select');
+ $whereDQLPart = $queryBuilder->getDQLPart('where');
+ $orderDQLPart = $queryBuilder->getDQLPart('orderBy');
+
+ static::assertInstanceOf(QueryBuilder::class, $queryBuilder);
+ static::assertArraySubset(['qb'], $queryBuilder->getRootAliases());
+ static::assertSame([], $selectDQLPart);
+ static::assertNull($whereDQLPart);
+
+ if (empty($property)) {
+ static::assertSame([], $orderDQLPart);
+ } else {
+ /* @var OrderBy $orderBy */
+ $orderBy = $orderDQLPart[0];
+
+ static::assertSame([$expectedOrderBy], $orderBy->getParts());
+ }
}
/**
@@ -581,7 +695,7 @@ class RepositoryTest extends BaseTestCase
[],
],
true,
- 1,
+ 2,
];
yield[
@@ -596,7 +710,125 @@ class RepositoryTest extends BaseTestCase
[],
],
false,
- 2,
+ 1,
+ ];
+ }
+
+ /**
+ * Provides objects without extreme position used to get extreme position
+ *
+ * @return Generator
+ */
+ public function provideObjectsWithoutExtremePositionToGetExtremePosition()
+ {
+ yield[
+ [],
+ false,
+ null,
+ ];
+
+ yield[
+ [],
+ true,
+ null,
+ ];
+
+ yield[
+ [
+ new Sortable(),
+ new Sortable(),
+ new Sortable(),
+ ],
+ true,
+ null,
+ ];
+
+ yield[
+ [
+ new Sortable(),
+ new Sortable(),
+ new Sortable(),
+ ],
+ false,
+ null,
+ ];
+ }
+
+ /**
+ * Provides objects with extreme position used to get extreme position
+ *
+ * @return Generator
+ */
+ public function provideObjectsWithExtremePositionToGetExtremePosition()
+ {
+ yield[
+ [
+ new Sortable(1),
+ new Sortable(2),
+ new Sortable(3),
+ ],
+ true,
+ 3,
+ ];
+
+ yield[
+ [
+ new Sortable(1),
+ new Sortable(2),
+ new Sortable(3),
+ ],
+ false,
+ 1,
+ ];
+ }
+
+ /**
+ * Provide name of property, direction and expected ORDER BY clause used to get query builder
+ *
+ * @return Generator
+ */
+ public function providePropertyAndDirectionToGetEntityOrderedQueryBuilder()
+ {
+ yield[
+ null,
+ null,
+ '',
+ ];
+
+ yield[
+ '',
+ '',
+ '',
+ ];
+
+ yield[
+ 'first_name',
+ '',
+ 'qb.first_name ASC',
+ ];
+
+ yield[
+ 'first_name',
+ 'asc',
+ 'qb.first_name asc',
+ ];
+
+ yield[
+ 'first_name',
+ 'ASC',
+ 'qb.first_name ASC',
+ ];
+
+ yield[
+ 'first_name',
+ 'desc',
+ 'qb.first_name desc',
+ ];
+
+ yield[
+ 'first_name',
+ 'DESC',
+ 'qb.first_name DESC',
];
}
}