Merge remote-tracking branch 'meritoo/master'

This commit is contained in:
Krzysztof Nizioł
2019-02-23 13:29:37 +01:00
56 changed files with 2545 additions and 676 deletions

48
.gitignore vendored
View File

@@ -1,5 +1,5 @@
# ------------------------------------------------------------------------------ # ------------------------------------------------------------------------------
# Environment-related parameters ### Environment-related parameters
# ------------------------------------------------------------------------------ # ------------------------------------------------------------------------------
.env .env
@@ -51,42 +51,15 @@
# ------------------------------------------------------------------------------ # ------------------------------------------------------------------------------
### Compiled source ### JetBrains template
# ------------------------------------------------------------------------------
*.com
*.class
*.dll
*.exe
*.o
*.so
# ------------------------------------------------------------------------------
### Shell scripts
# ------------------------------------------------------------------------------
/*.sh
# ------------------------------------------------------------------------------
### JetBrains
# ------------------------------------------------------------------------------ # ------------------------------------------------------------------------------
/.idea /.idea
# ------------------------------------------------------------------------------ # ------------------------------------------------------------------------------
### NetBeans template ### macOS template
# ------------------------------------------------------------------------------
nbproject/private/
nbbuild/
dist/
nbdist/
nbactions.xml
.nb-gradle/
# ------------------------------------------------------------------------------
### OSX template
# ------------------------------------------------------------------------------ # ------------------------------------------------------------------------------
# General
.DS_Store .DS_Store
.AppleDouble .AppleDouble
.LSOverride .LSOverride
@@ -104,6 +77,7 @@ Icon
.TemporaryItems .TemporaryItems
.Trashes .Trashes
.VolumeIcon.icns .VolumeIcon.icns
.com.apple.timemachine.donotpresent
# Directories potentially created on remote AFP share # Directories potentially created on remote AFP share
.AppleDB .AppleDB
@@ -127,16 +101,23 @@ Temporary Items
# Linux trash folder which might appear on any partition or disk # Linux trash folder which might appear on any partition or disk
.Trash-* .Trash-*
# .nfs files are created when an open file is removed but is still being accessed
.nfs*
# ------------------------------------------------------------------------------ # ------------------------------------------------------------------------------
### Windows template ### Windows template
# ------------------------------------------------------------------------------ # ------------------------------------------------------------------------------
# Windows image file caches # Windows thumbnail cache files
Thumbs.db Thumbs.db
ehthumbs.db ehthumbs.db
ehthumbs_vista.db
# Dump file
*.stackdump
# Folder config file # Folder config file
Desktop.ini [Dd]esktop.ini
# Recycle Bin used on file shares # Recycle Bin used on file shares
$RECYCLE.BIN/ $RECYCLE.BIN/
@@ -144,6 +125,7 @@ $RECYCLE.BIN/
# Windows Installer files # Windows Installer files
*.cab *.cab
*.msi *.msi
*.msix
*.msm *.msm
*.msp *.msp

View File

@@ -11,7 +11,7 @@ before_install:
- composer global require hirak/prestissimo - composer global require hirak/prestissimo
install: install:
- travis_wait 30 composer install - travis_wait 30 composer install -v
script: script:
- php ./vendor/bin/phpunit - php ./vendor/bin/phpunit

View File

@@ -2,6 +2,25 @@
Common and useful classes, methods, exceptions etc. Common and useful classes, methods, exceptions etc.
# 0.1.5
1. Tests > Date > one more test case
2. Phing > update configuration
3. Miscellaneous > variableDump() method > remove, because unnecessary
4. Regex > createSlug() method > returns slug for given value
5. Arrays > getNonEmptyValues() method > returns non-empty values, e.g. without "" (empty string), null or []
6. Arrays > getNonEmptyValuesAsString() method > returns non-empty values concatenated by given separator
7. ValueObject > Company > represents a company
8. ValueObject > BankAccount > represents bank account
9. ValueObject > Address > represents address of company, institution, user 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 # 0.1.3
1. Tests > refactoring & minor improvements 1. Tests > refactoring & minor improvements

View File

@@ -2,7 +2,7 @@
Common and useful classes, methods, exceptions etc. Common and useful classes, methods, exceptions etc.
[![Travis](https://img.shields.io/travis/rust-lang/rust.svg?style=flat-square)](https://travis-ci.org/meritoo/common-library) [![Packagist](https://img.shields.io/packagist/v/meritoo/common-library.svg?style=flat-square)](https://packagist.org/packages/meritoo/common-library) [![license](https://img.shields.io/github/license/meritoo/common-library.svg?style=flat-square)](https://github.com/meritoo/common-library) [![GitHub commits](https://img.shields.io/github/commits-since/meritoo/common-library/0.0.1.svg?style=flat-square)](https://github.com/meritoo/common-library) [![Coverage Status](https://coveralls.io/repos/github/meritoo/common-library/badge.svg?branch=master)](https://coveralls.io/github/meritoo/common-library?branch=master) [![PHP Version](https://img.shields.io/badge/php-%3E%3D5.6-blue.svg)](https://img.shields.io/badge/php-%3E%3D5.6-blue.svg) [![Travis](https://img.shields.io/travis/rust-lang/rust.svg?style=flat-square)](https://travis-ci.org/meritoo/common-library) [![Packagist](https://img.shields.io/packagist/v/meritoo/common-library.svg?style=flat-square)](https://packagist.org/packages/meritoo/common-library) [![license](https://img.shields.io/github/license/meritoo/common-library.svg?style=flat-square)](https://github.com/meritoo/common-library) [![GitHub commits](https://img.shields.io/github/commits-since/meritoo/common-library/0.0.1.svg?style=flat-square)](https://github.com/meritoo/common-library) [![Coverage Status](https://coveralls.io/repos/github/meritoo/common-library/badge.svg?branch=master)](https://coveralls.io/github/meritoo/common-library?branch=master)
# Installation # Installation
@@ -32,6 +32,8 @@ composer require wiosna-dev/common-library
2. [Collection of elements](docs/Collection-of-elements.md) 2. [Collection of elements](docs/Collection-of-elements.md)
3. [Exceptions](docs/Static-methods.md) 3. [Exceptions](docs/Static-methods.md)
4. [Static methods](docs/Static-methods.md) 4. [Static methods](docs/Static-methods.md)
1. [Arrays](docs/Static-methods/Arrays.md)
2. [Regex](docs/Static-methods/Regex.md)
5. [Value Objects](docs/Value-Objects.md) 5. [Value Objects](docs/Value-Objects.md)
# Development # Development

View File

@@ -1 +1 @@
0.1.3 0.1.5

View File

@@ -1,46 +1,30 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<project name="Meritoo Package" basedir="." default="build:main" phingVersion="2.14.0"> <project name="Meritoo Package" basedir="." default="build:main" phingVersion="2.14.0">
<!-- Properties --> <!-- Properties -->
<if> <if>
<available file="phing/properties" property="custom.properties.available"/> <available file="${project.basedir}/phing/properties" property="custom.properties.available"/>
<then> <then>
<property file="phing/properties"/> <property file="${project.basedir}/phing/properties"/>
</then> </then>
<else> <else>
<property file="phing/properties.dist"/> <property file="${project.basedir}/phing/properties.dist"/>
</else> </else>
</if> </if>
<!-- Default / main target --> <!-- Default / main target -->
<target name="build:main" <target name="build:main"
depends="build:app, build:tests" depends="build:app,
description="Builds everything and runs all tests" /> build:tests"
/>
<!-- Build app --> <!-- Build app -->
<target name="build:app" description="Prepares app to build and tests"> <target name="build:app">
<phing phingfile="phing/app.xml" haltonfailure="true"/> <phing phingfile="${project.basedir}/phing/app.xml" haltonfailure="true"/>
</target> </target>
<!-- Build tests --> <!-- Build tests -->
<target name="build:tests" description="Runs all tests, checks and creates docs"> <target name="build:tests">
<phing phingfile="phing/tests.xml" haltonfailure="true"/> <phing phingfile="${project.basedir}/phing/tests.xml" haltonfailure="true"/>
<!--
Conditional running of tests.
Disabled, because not required.
Meritoo <github@meritoo.pl>
2017-02-22
<if>
<equals arg1="${env}" arg2="test" />
<then>
<phing phingfile="phing/tests.xml" haltonfailure="true" />
</then>
<else>
<echo message="[Skipped] Running tests, checks and creating docs, because it's a not 'test' environment..." />
</else>
</if>
-->
</target> </target>
</project> </project>

View File

@@ -10,6 +10,10 @@
} }
], ],
"require": { "require": {
"ext-dom": "*",
"ext-fileinfo": "*",
"ext-json": "*",
"ext-simplexml": "*",
"php": ">=5.6", "php": ">=5.6",
"ext-intl": "*", "ext-intl": "*",
"ext-pcre": "*", "ext-pcre": "*",

View File

@@ -1,6 +1,9 @@
version: '3' version: '3'
services: services:
#
# Required to run project
#
php: php:
image: ${DOCKER_CONTAINER_OWNER}/${DOCKER_CONTAINER_PROJECT}-php image: ${DOCKER_CONTAINER_OWNER}/${DOCKER_CONTAINER_PROJECT}-php
container_name: ${DOCKER_CONTAINER_OWNER}-${DOCKER_CONTAINER_PROJECT}-php container_name: ${DOCKER_CONTAINER_OWNER}-${DOCKER_CONTAINER_PROJECT}-php
@@ -15,6 +18,16 @@ services:
composer: composer:
image: ${DOCKER_CONTAINER_OWNER}/${DOCKER_CONTAINER_PROJECT}-php image: ${DOCKER_CONTAINER_OWNER}/${DOCKER_CONTAINER_PROJECT}-php
container_name: ${DOCKER_CONTAINER_OWNER}-${DOCKER_CONTAINER_PROJECT}-composer container_name: ${DOCKER_CONTAINER_OWNER}-${DOCKER_CONTAINER_PROJECT}-composer
entrypoint: composer entrypoint: php -d memory_limit=-1 /usr/local/bin/composer
volumes:
- .:/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: volumes:
- .:/project:cached - .:/project:cached

View File

@@ -98,7 +98,7 @@ ENV COMPOSER_ALLOW_SUPERUSER 1
# #
RUN php -r "copy('https://getcomposer.org/installer', 'composer-setup.php');" \ RUN php -r "copy('https://getcomposer.org/installer', 'composer-setup.php');" \
&& php -r "if (hash_file('SHA384', '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;" \ '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 composer-setup.php --install-dir=/usr/local/bin --filename=composer \
&& php -r "unlink('composer-setup.php');" \ && php -r "unlink('composer-setup.php');" \

View File

@@ -48,6 +48,8 @@ class MimeTypesTest extends BaseTestCase
2. [Collection of elements](Collection-of-elements.md) 2. [Collection of elements](Collection-of-elements.md)
3. [Exceptions](Exceptions.md) 3. [Exceptions](Exceptions.md)
4. [Static methods](Static-methods.md) 4. [Static methods](Static-methods.md)
1. [Arrays](Static-methods/Arrays.md)
2. [Regex](Static-methods/Regex.md)
5. [Value Objects](Value-Objects.md) 5. [Value Objects](Value-Objects.md)
[&lsaquo; Back to `Readme`](../README.md) [&lsaquo; Back to `Readme`](../README.md)

View File

@@ -46,6 +46,8 @@ var_dump($simpleCollection->has('dolor')); // bool(true)
2. [**Collection of elements**](Collection-of-elements.md) 2. [**Collection of elements**](Collection-of-elements.md)
3. [Exceptions](Exceptions.md) 3. [Exceptions](Exceptions.md)
4. [Static methods](Static-methods.md) 4. [Static methods](Static-methods.md)
1. [Arrays](Static-methods/Arrays.md)
2. [Regex](Static-methods/Regex.md)
5. [Value Objects](Value-Objects.md) 5. [Value Objects](Value-Objects.md)
[&lsaquo; Back to `Readme`](../README.md) [&lsaquo; Back to `Readme`](../README.md)

View File

@@ -15,10 +15,10 @@ Development-related information
docker-compose up -d 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 ```bash
docker-compose run composer install docker-compose exec php phing
``` ```
> [What is Docker?](https://www.docker.com/what-docker) > [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: Available as `composer` service. You can run any Composer's command using the `composer` service:
```bash ```bash
docker-compose run composer <command> docker-compose run --rm composer [command]
``` ```
Examples below. Examples below.
@@ -36,25 +36,25 @@ Examples below.
##### Install packages ##### Install packages
```bash ```bash
docker-compose run composer install docker-compose run --rm composer install
``` ```
##### Update packages ##### Update packages
```bash ```bash
docker-compose run composer update docker-compose run --rm composer update
``` ```
##### Add package ##### Add package
```bash ```bash
docker-compose run composer require <vendor>/<package> docker-compose run --rm composer require [vendor]/[package]
``` ```
##### Remove package ##### Remove package
```bash ```bash
docker-compose run composer remove <vendor>/<package> docker-compose run --rm composer remove [vendor]/[package]
``` ```
# Coding Standards Fixer # Coding Standards Fixer
@@ -65,6 +65,12 @@ Fix coding standard by running command:
docker-compose exec php php-cs-fixer fix 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: Omit cache and run the Fixer from scratch by running command:
```bash ```bash
@@ -77,37 +83,35 @@ docker-compose exec php rm .php_cs.cache && docker-compose exec php php-cs-fixer
### Prerequisites ### 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 ##### Easy (with code coverage)
Tests are running using Docker and `php` service defined in `docker-compose.yml`. Example:
```bash ```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: or
1. Enter container:
```bash
docker-compose exec php bash
```
2. Run tests:
```bash
phpunit --no-coverage
```
#### With code coverage
```bash ```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 # Other
Rebuild project and run tests by running command: Rebuild project and run tests by running command:

View File

@@ -57,6 +57,8 @@ class UnknownSimpleTypeException extends UnknownTypeException
2. [Collection of elements](Collection-of-elements.md) 2. [Collection of elements](Collection-of-elements.md)
3. [**Exceptions**](Exceptions.md) 3. [**Exceptions**](Exceptions.md)
4. [Static methods](Static-methods.md) 4. [Static methods](Static-methods.md)
1. [Arrays](Static-methods/Arrays.md)
2. [Regex](Static-methods/Regex.md)
5. [Value Objects](Value-Objects.md) 5. [Value Objects](Value-Objects.md)
[&lsaquo; Back to `Readme`](../README.md) [&lsaquo; Back to `Readme`](../README.md)

View File

@@ -19,6 +19,8 @@ var_dump($firstElement); // string(5) "lorem"
2. [Collection of elements](Collection-of-elements.md) 2. [Collection of elements](Collection-of-elements.md)
3. [Exceptions](Exceptions.md) 3. [Exceptions](Exceptions.md)
4. [**Static methods**](Static-methods.md) 4. [**Static methods**](Static-methods.md)
1. [Arrays](Static-methods/Arrays.md)
2. [Regex](Static-methods/Regex.md)
5. [Value Objects](Value-Objects.md) 5. [Value Objects](Value-Objects.md)
[&lsaquo; Back to `Readme`](../README.md) [&lsaquo; Back to `Readme`](../README.md)

View File

@@ -0,0 +1,78 @@
# Meritoo Common Library
Common and useful classes, methods, exceptions etc.
# Arrays
> Useful methods related to arrays
Class: `Meritoo\Common\Utilities\Arrays`
File: `src/Utilities/Arrays.php`
### getNonEmptyValues(array $values)
> Returns non-empty values, e.g. without "" (empty string), null or []
##### Arguments
- `array $values` - The values to filter
##### Example 1
- values: `[]` (no values)
- result: `[]` (an empty array)
##### Example 2
- values: `[null, ""]` (all empty values)
- result: `[]` (an empty array)
##### Example 3
- values: `["test 1", "", 123, null, 0]`
- result: `["test 1", 123, 0]`
### getNonEmptyValuesAsString(array $values, $separator = ', ')
> Returns non-empty values concatenated by given separator
##### Arguments
- `array $values` - The values to filter
- `[string $separator]` - (optional) Separator used to implode the values. Default: ", ".
##### Example 1
- values: `[]` (no values)
- separator: default or any other string
- result: `""` (an empty string)
##### Example 2
- values: `[null, ""]` (all empty values)
- separator: default or any other string
- result: `""` (an empty string)
##### Example 3
- values: `["test 1", "", 123, null, 0]`
- separator: `", "` (default)
- result: `"test 1, 123, 0"`
##### Example 4
- values: `["test 1", "", 123, null, 0]`
- separator: `" | "`
- result: `"test 1 | 123 | 0"`
# More
1. [Base test case (with common methods and data providers)](../Base-test-case.md)
2. [Collection of elements](../Collection-of-elements.md)
3. [Exceptions](../Exceptions.md)
4. [Static methods](../Static-methods.md)
1. [**Arrays**](Arrays.md)
2. [Regex](Regex.md)
5. [Value Objects](../Value-Objects.md)
[&lsaquo; Back to `Readme`](../../README.md)

View File

@@ -0,0 +1,45 @@
# Meritoo Common Library
Common and useful classes, methods, exceptions etc.
# Regex
> Useful methods related to regular expressions
Class: `Meritoo\Common\Utilities\Regex`
File: `src/Utilities/Regex.php`
### createSlug($value)
> Returns slug for given value
##### Arguments
- `string $value` - Value that should be transformed to slug
##### Example 1
- value: non-scalar or `null`
- result: `false`
##### Example 2
- value: `""` (an empty string)
- result: `""` (an empty string)
##### Example 3
- value: `"Lorem ipsum. Dolor sit 12.34 amet."`
- result: `"lorem-ipsum-dolor-sit-1234-amet"`
# More
1. [Base test case (with common methods and data providers)](../Base-test-case.md)
2. [Collection of elements](../Collection-of-elements.md)
3. [Exceptions](../Exceptions.md)
4. [Static methods](../Static-methods.md)
1. [Arrays](../Static-methods/Arrays.md)
2. [**Regex**](Regex.md)
5. [Value Objects](../Value-Objects.md)
[&lsaquo; Back to `Readme`](../../README.md)

View File

@@ -4,7 +4,138 @@ Common and useful classes, methods, exceptions etc.
# Value Objects # Value Objects
Located in `Meritoo\Common\ValueObject` namespace. Located in `Meritoo\Common\ValueObject` namespace and in `src/ValueObject/` directory.
### Address
##### Namespace
`Meritoo\Common\ValueObject\Address`
##### Info
Represents address of company, institution, user etc. Contains properties:
1. `$street` - the street
2. `$buildingNumber` - the number of building
3. `$flatNumber` - the number of flat
4. `$zipCode` - the zip code
5. `$city` - the city, location
##### New instance
New instance can be created using constructor
```php
new Address('New York', '00123', '4th Avenue', '10', '200');
```
##### Methods
Has getters for each property, e.g. `getFlatNumber()` or `getZipCode()`, and 1 extra method:
```php
getFullStreet()
```
that returns name of street with related numbers (building & flat number).
Example:
```php
$address = new Address('New York', '00123', '4th Avenue', '10', '200');
$fullStreet = $address->getFullStreet(); // "4th Avenue 10/200"
```
##### Conversion to string (the `__toString()` method)
Instance of `Address` may be represented as string that contains all non-empty properties separated by `, `.
Example:
```php
$address = new Address('New York', '00123', '4th Avenue', '10', '200');
$asString = (string)$address; // "4th Avenue 10/200, 00123, New York"
```
### BankAccount
##### Namespace
`Meritoo\Common\ValueObject\BankAccount`
##### Info
Represents bank account. Contains properties:
1. `$bankName` - name of bank
2. $accountNumber` - number of bank's account
##### New instance
New instance can be created using constructor
```php
new BankAccount('Bank of America', '1234567890')
```
##### Methods
Has getters for each property `getBankName()` and `getAccountNumber()`.
##### Conversion to string (the `__toString()` method)
Instance of `BankAccount` may be represented as string that contains all non-empty properties separated by `, `.
Example:
```php
$bank = new BankAccount('Bank of America', '1234567890');
$asString = (string)$bank; // "Bank of America, 1234567890"
```
### Company
##### Namespace
`Meritoo\Common\ValueObject\Company`
##### Info
Represents a company. Contains properties:
1. `$name` - name of company
2. `$address` - address of company
3. `$bankAccount` - bank account of company
##### New instance
New instance can be created using constructor:
```php
new Company(
'Test 1',
new Address('New York', '00123', '4th Avenue', '10', '200'),
new BankAccount('Bank 1', '12345')
);
```
##### Methods
Has getters for each property `getName()`, `getAddress()` and `getBankAccount()`.
##### Conversion to string (the `__toString()` method)
Instance of `Company` may be represented as string that contains all non-empty properties separated by `, `.
Example:
```php
$company = new Company(
'Test 1',
new Address('New York', '00123', '4th Avenue', '10', '200'),
new BankAccount('Bank 1', '12345')
);
$asString = (string)$company; // "Test 1, 4th Avenue 10/200, 00123, New York, Bank 1, 12345"
```
### Version ### Version
@@ -14,7 +145,7 @@ Located in `Meritoo\Common\ValueObject` namespace.
##### Info ##### Info
Represents version of software. Contains 3 properties: Represents version of software. Contains properties:
1. `$majorPart` - the "major" part of version 1. `$majorPart` - the "major" part of version
2. `$minorPart` - the "minor" part of version 2. `$minorPart` - the "minor" part of version
3. `$patchPart` - the "patch" part of version 3. `$patchPart` - the "patch" part of version
@@ -48,6 +179,8 @@ New instance can be created using:
2. [Collection of elements](Collection-of-elements.md) 2. [Collection of elements](Collection-of-elements.md)
3. [Exceptions](Exceptions.md) 3. [Exceptions](Exceptions.md)
4. [Static methods](Static-methods.md) 4. [Static methods](Static-methods.md)
1. [Arrays](Static-methods/Arrays.md)
2. [Regex](Static-methods/Regex.md)
5. [**Value Objects**](Value-Objects.md) 5. [**Value Objects**](Value-Objects.md)
[&lsaquo; Back to `Readme`](../README.md) [&lsaquo; Back to `Readme`](../README.md)

View File

@@ -1,98 +1,184 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<project name="Meritoo Package" basedir="." default="build:main" phingVersion="2.14.0">
<project name="Meritoo Package" basedir="." default="build:main" phingVersion="2.16.0">
<!-- Properties --> <!-- Properties -->
<if> <if>
<available file="phing/properties" property="custom.properties.available"/> <available file="${project.basedir}/phing/properties" property="custom.properties.available"/>
<then> <then>
<property file="phing/properties"/> <property file="${project.basedir}/phing/properties"/>
</then> </then>
<else> <else>
<property file="phing/properties.dist"/> <property file="${project.basedir}/phing/properties.dist"/>
</else> </else>
</if> </if>
<!-- Filesets -->
<import file="${project.basedir}/phing/filesets.xml"/>
<!-- Default / main target --> <!-- Default / main target -->
<target name="build:main" <target name="build:main"
depends="build:app" depends="build:app"
description="Builds the application" /> />
<!-- App target --> <!-- App target -->
<target name="build:app" <target name="build:app"
depends="app:composer, app:vendors, app:checkout" depends="app:clean,
description="Prepares app to build." /> app:composer:self-update,
app:composer:install,
<!-- Updates Composer and validates composer.* files --> app:composer:validate,
<target name="app:composer" description="Updates Composer and validates composer.* files"> app:checkout"
<echo msg="Updating Composer and validating composer.* files..." /> />
<!-- Updates Composer -->
<target name="app:composer:self-update">
<if> <if>
<available file="composer.phar" /> <not>
<available file="${composer.path}" property="composer.local.unavailable"/>
</not>
<then> <then>
<echo msg="[Skipped] Downloading of Composer skipped, because exist in the project..." /> <if>
<os family="windows"/>
<then>
<fail message="Composer not found! Go to http://getcomposer.org/download and download the Composer."/>
</then> </then>
<else> <else>
<if> <exec command="${composer.download_command}" checkreturn="true" passthru="true"/>
<os family="windows" />
<then>
<fail message="Composer not found! Go to http://getcomposer.org/download and download the Composer." />
</then>
<else>
<exec command="${composer.download_command}" checkreturn="true" />
</else> </else>
</if> </if>
</else> </then>
</if> </if>
<!-- Update Composer --> <!-- Update Composer -->
<composer command="selfupdate" /> <composer php="${composer.php}" composer="${composer.path}" command="selfupdate">
<arg value="--ansi"/>
<!-- Validate Composer -->
<composer command="validate">
<arg line="--no-check-all --strict" />
</composer> </composer>
</target> </target>
<!-- Project Install/update vendors --> <!-- Validates composer.* files -->
<target name="app:vendors" description="Installs / updates vendors"> <target name="app:composer:validate" depends="app:composer:install">
<echo msg="Installing / updating vendors..." /> <composer php="${composer.php}" composer="${composer.path}" command="validate">
<arg value="--no-check-all"/>
<if> <arg value="--strict"/>
<istrue value="${composer.self-update}"/> <arg value="--ansi"/>
<then>
<composer php="${composer.php}" composer="${composer.path}" command="self-update"/>
</then>
</if>
<if>
<istrue value="${composer.validate}"/>
<then>
<composer php="${composer.php}" composer="${composer.path}" command="validate"/>
</then>
</if>
<if>
<equals arg1="${env}" arg2="prod" />
<then>
<composer php="${composer.php}" composer="${composer.path}" command="install">
<arg value="--optimize-autoloader" />
<arg value="--prefer-dist" />
<arg value="--classmap-authoritative" />
</composer> </composer>
</target>
<!-- Project clean -->
<target name="app:clean">
<if>
<equals arg1="${env}" arg2="prod"/>
<then>
<echo message="[Skipped] Cleaning project (and directories cleanup) -> 'prod' environment"/>
</then> </then>
<else> <else>
<composer php="${composer.php}" composer="${composer.path}" command="install" /> <foreach list="${directoriesToEmpty}" param="directory" target="app:clean:empty"/>
</else> </else>
</if> </if>
<foreach list="${directoriesToCheck}" param="directory" target="app:clean:check"/>
<touch file="${dir.cache}/.gitkeep"/>
<touch file="${dir.logs}/.gitkeep"/>
<touch file="${dir.sessions}/.gitkeep"/>
<foreach list="${directoriesToEmpty}" param="directory" target="app:permissions"/>
</target>
<!-- Cleaning directory (making empty) directory -->
<target name="app:clean:empty">
<if>
<available file="${directory}" type="dir" property="dir_is_available"/>
<then>
<delete includeemptydirs="true" dir="${directory}"/>
</then>
</if>
</target>
<!-- Checking if directory exists -->
<target name="app:clean:check">
<if>
<not>
<available file="${directory}" type="dir" property="dir_is_available"/>
</not>
<then>
<if>
<or>
<contains string="${directory}" substring="cache"/>
<contains string="${directory}" substring="logs"/>
<contains string="${directory}" substring="sessions"/>
</or>
<then>
<mkdir dir="${directory}" mode="0777"/>
</then>
<else>
<mkdir dir="${directory}" mode="0775"/>
</else>
</if>
</then>
</if>
</target>
<!-- Installs vendors -->
<target name="app:composer:install" depends="app:composer:self-update">
<composer php="${composer.php}" composer="${composer.path}" command="install">
<arg value="--optimize-autoloader"/>
<arg value="--ansi"/>
</composer>
</target>
<!-- Clearing cache -->
<target name="app:cache">
<if>
<istrue value="${cache.clearWithWarmup}"/>
<then>
<SymfonyConsole console="bin/console" command="cache:clear">
<arg name="env" value="${env}"/>
</SymfonyConsole>
</then>
<else>
<SymfonyConsole console="bin/console" command="cache:clear">
<arg name="env" value="${env}"/>
<arg name="no-warmup"/>
</SymfonyConsole>
</else>
</if>
</target>
<!-- Clearing cache (faster) -->
<target name="app:cache:faster">
<SymfonyConsole console="bin/console" command="cache:clear">
<arg name="env" value="${env}"/>
<arg name="no-optional-warmers"/>
</SymfonyConsole>
</target>
<!-- Warming up cache -->
<target name="app:cache:warmup">
<SymfonyConsole console="bin/console" command="cache:warmup">
<arg name="env" value="${env}"/>
</SymfonyConsole>
</target>
<!-- Setting permissions of given directory -->
<target name="app:permissions">
<if>
<not>
<os family="windows"/>
</not>
<then>
<exec command="chmod -R 777 ${directory}/*"/>
</then>
</if>
</target> </target>
<!-- Checkout and finalization --> <!-- Checkout and finalization -->
<target name="app:checkout"> <target name="app:checkout">
<tstamp> <tstamp>
<format property="date_end" pattern="%Y-%m-%d %H:%M" /> <format property="date_end" pattern="%Y-%m-%d %H:%M"/>
</tstamp> </tstamp>
<echo msg="------------------------------------" /> <echo msg="------------------------------------"/>
<echo msg="Build finished at: ${date_end}" /> <echo msg="Build finished at: ${date_end}"/>
<echo msg="------------------------------------" /> <echo msg="------------------------------------"/>
</target> </target>
</project> </project>

20
phing/composer-install.sh Normal file
View File

@@ -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}

36
phing/filesets.xml Normal file
View File

@@ -0,0 +1,36 @@
<?xml version="1.0" encoding="UTF-8"?>
<project name="Meritoo Package" basedir="." default="build:main" phingVersion="2.16.0">
<!-- Filesets -->
<fileset id="cache" dir="${dir.cache}">
<include name="**/*"/>
<exclude name=".gitkeep"/>
</fileset>
<fileset id="logs" dir="${dir.logs}">
<include name="**/*"/>
<exclude name=".gitkeep"/>
</fileset>
<fileset id="sessions" dir="${dir.sessions}">
<include name="**/*"/>
<exclude name=".gitkeep"/>
</fileset>
<!-- Directories to check -->
<property name="directoriesToCheck" value="
${dir.cache},
${dir.logs},
${dir.sessions},
${dir.data.tests},
${dir.data.temporary},
${dir.docker.data},
${dir.docker.logs}"
/>
<!-- Directories to empty -->
<property name="directoriesToEmpty" value="
${dir.cache},
${dir.logs},
${dir.sessions},
${dir.data.temporary}"
/>
</project>

View File

@@ -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 # Common, e.g. default environment
# -------------------------------------------------------------------------------- # --------------------------------------------------------------------------------
@@ -22,10 +6,6 @@
# #
env = dev env = dev
# Install assets using symlinks
#
assets.installWithSymlink = true
# Clear cache with the "warmup" option # 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. # 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
# -------------------------------------------------------------------------------- # --------------------------------------------------------------------------------
composer.download_command = php -r "eval('?>'.file_get_contents('https://getcomposer.org/installer'));" # Command used to download Composer
# Path to composer executable or composer.phar file
# #
composer.path = composer.phar composer.download_command = bash ${project.basedir}/phing/composer-install.sh
#composer.path = /usr/local/bin/composer
# Path to composer executable or downloaded composer.phar file
#
composer.path = ${project.basedir}/composer.phar
# Path to php executable used by composer # Path to php executable used by composer
# #
composer.php = php composer.php = php
# Self update of the composer
#
composer.self-update = false
# Validate the composer.json file
#
composer.validate = false
# -------------------------------------------------------------------------------- # --------------------------------------------------------------------------------
# Directories # Directories
# -------------------------------------------------------------------------------- # --------------------------------------------------------------------------------
# System directories # System directories
# #
dir.data = ${project.basedir}/data
dir.src = ${project.basedir}/src 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 dir.tests = ${project.basedir}/tests
# --------------------------------------------------------------------------------
# Build directories # Build directories
# -------------------------------------------------------------------------------- #
dir.build = ${project.basedir}/build dir.build = ${project.basedir}/build
dir.reports = ${dir.build}/logs dir.reports = ${dir.build}/reports
dir.reports.pdepend = ${dir.reports}/pdepend dir.reports.pdepend = ${dir.reports}/pdepend
dir.reports.coverage = ${dir.reports}/phpunit_coverage dir.reports.coverage = ${dir.reports}/phpunit_coverage
#
# Disabled, because unnecessary right now
# phpdocumentor/phpdocumentor cannot be installed via Composer
#
# Meritoo <github@meritoo.pl>
# 2017-02-22
#
#dir.docs = ${dir.build}/docs
#dir.docs.phpdoc2 = ${dir.docs}/phpdoc2
# --------------------------------------------------------------------------------
# Data directories # Data directories
# -------------------------------------------------------------------------------- #
dir.data.tests = ${dir.data}/tests
dir.data.temporary = ${dir.data}/tmp 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 # 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) # 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

View File

@@ -1,230 +1,133 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<project name="Meritoo Package" basedir="." default="build:main" phingVersion="2.14.0">
<!--
The AutoloaderTask is required to load binaries installed by Composer.
The "autoloaderpath" attribute of this task is not required, because it's default value is: vendor/autoload.php.
Meritoo <github@meritoo.pl> <project name="Meritoo Package" basedir="." default="build:main" phingVersion="2.16.0">
2017-02-23 <autoloader/>
-->
<autoloader />
<!-- Properties --> <!-- Properties -->
<if> <if>
<available file="phing/properties" property="custom.properties.available"/> <available file="${project.basedir}/phing/properties" property="custom.properties.available"/>
<then> <then>
<property file="phing/properties"/> <property file="${project.basedir}/phing/properties"/>
</then> </then>
<else> <else>
<property file="phing/properties.dist"/> <property file="${project.basedir}/phing/properties.dist"/>
</else> </else>
</if> </if>
<!-- Filesets --> <!-- Filesets -->
<fileset id="sourcecode" dir="${dir.src}"> <fileset id="sourcecode" dir="${dir.src}">
<include name="**/*.php" /> <include name="**/*.php"/>
<exclude name="*Test.php" /> <exclude name="*Test.php"/>
<exclude name="**/*Test.php" /> <exclude name="**/*Test.php"/>
<exclude name="**/Resources/**" /> <exclude name="**/Resources/**"/>
<exclude name="**/DataFixtures/**" /> <exclude name="**/DataFixtures/**"/>
<exclude name="**/Tests/**" /> <exclude name="**/Tests/**"/>
</fileset> </fileset>
<fileset id="tests" dir="${dir.tests}"> <fileset id="tests" dir="${dir.tests}">
<include name="**/*Test*.php" /> <include name="**/*Test*.php"/>
</fileset> </fileset>
<!-- Default / main target --> <!-- Default / main target -->
<target name="build:main" <target name="build:main"
depends="build:fix-coding-standards, build:clean, build:prepare, build:check, build:test, app:checkout" depends="build:fix-coding-standards,
description="Runs all tests and builds everything" /> build:check,
<!-- build:test,
Before: app:checkout"
depends="build:fix-coding-standards, build:clean, build:prepare, build:check, build:test, build:doc, app:checkout" />
After:
depends="build:fix-coding-standards, build:clean, build:prepare, build:check, build:test, app:checkout"
The "build:doc" task is disabled, because it cannot be installed via Composer:
a) phpdocumentor/phpdocumentor v2.9.0 requires symfony/validator ~2.2
b) symfony/validator ~2.2 causes to remove symfony/symfony 3.*
Meritoo <github@meritoo.pl>
2017-02-22
-->
<!-- Fixing coding standards using the PHP Coding Standards Fixer (http://cs.sensiolabs.org) --> <!-- Fixing coding standards using the PHP Coding Standards Fixer (http://cs.sensiolabs.org) -->
<target name="build:fix-coding-standards" description="Fixes coding standards using the PHP Coding Standards Fixer"> <target name="build:fix-coding-standards">
<echo msg="Fixing coding standards using the PHP Coding Standards Fixer (http://cs.sensiolabs.org)..." /> <exec command="${tests.cs_fixer.command}" passthru="true"/>
<!--
Attention.
Rules for formatting are defined in /.php_cs.dist file.
-->
<exec
passthru="true"
command="${phpCsFixer.path} fix --verbose"
/>
</target> </target>
<!-- Doc target -->
<!--
Disabled, because it cannot be installed via Composer:
a) phpdocumentor/phpdocumentor v2.9.0 requires symfony/validator ~2.2
b) symfony/validator ~2.2 causes to remove symfony/symfony 3.*
Meritoo <github@meritoo.pl>
2017-02-22
-->
<!--<target name="build:doc"-->
<!--depends="build:prepare, doc:phpdoc2"-->
<!--description="Generates API documentation" />-->
<!-- Check target --> <!-- Check target -->
<target name="build:check" <target name="build:check"
depends="check:cs, check:md, check:cpd, check:depend, check:loc" depends="check:cs,
description="Analyzes code" /> check:md,
check:cpd,
check:depend,
check:loc"
/>
<!-- Test target --> <!-- Test target -->
<target name="build:test" <target name="build:test"
depends="test:unit" depends="test:phpunit"
description="Executes all tests" /> />
<!-- Project build clean -->
<target name="build:clean" description="Cleans up build directories">
<echo msg="Cleaning docs and reports directories..." />
<!--<delete dir="${dir.docs}" />-->
<delete dir="${dir.reports}" />
</target>
<!-- Project build prepare -->
<target name="build:prepare" description="Create build directories">
<echo msg="Creating build directories..." />
<!--<mkdir dir="${dir.docs}" />-->
<!--<mkdir dir="${dir.docs.phpdoc2}" />-->
<mkdir dir="${dir.reports}" />
<mkdir dir="${dir.reports.pdepend}" />
<mkdir dir="${dir.reports.coverage}"/>
</target>
<!-- PHPDocumentor2 API documentation target -->
<!--
Disabled, because it cannot be installed via Composer:
a) phpdocumentor/phpdocumentor v2.9.0 requires symfony/validator ~2.2
b) symfony/validator ~2.2 causes to remove symfony/symfony 3.*
Meritoo <github@meritoo.pl>
2017-02-22
<target name="doc:phpdoc2" description="Generates API documentations">
<echo msg="Generating API Documentation with phpDocumentor 2..." />
<phpdoc2 title="${phing.project.name}"
destdir="${dir.docs.phpdoc2}"
template="responsive">
<fileset refid="sourcecode" />
</phpdoc2>
</target>
-->
<!-- Symfony2 code sniffer --> <!-- Symfony2 code sniffer -->
<!-- <target name="check:cs" depends="build:prepare">
Attention 1.
To use Symfony2 standards to check coding you have to:
copy, symlink or check out repo to a folder called Symfony2 inside the phpcs Standards directory.
Example:
$ pear config-show | grep php_dir
$ cd /path/to/pear/PHP/CodeSniffer/Standards
$ git clone git://github.com/opensky/Symfony2-coding-standard.git Symfony2
Attention 2.
PSR2 standard is used instead of Symfony2 standard, because after installation squizlabs/php_codesniffer package
via Composer the Symfony2 standard is not included / available in this package. In this case the PHP Coding
Standards Fixer (http://cs.sensiolabs.org) is used.
Meritoo <github@meritoo.pl>
2017-02-22
-->
<target name="check:cs" description="Checks coding standard">
<echo msg="Checking coding standard..." />
<phpcodesniffer standard="PSR2" showWarnings="true"> <phpcodesniffer standard="PSR2" showWarnings="true">
<fileset refid="sourcecode" /> <fileset refid="sourcecode"/>
<formatter type="checkstyle" outfile="${dir.reports}/checkstyle.xml" /> <formatter type="checkstyle" outfile="${dir.reports}/checkstyle.xml"/>
<formatter type="csv" outfile="${dir.reports}/checkstyle.csv" /> <formatter type="csv" outfile="${dir.reports}/checkstyle.csv"/>
<formatter type="summary" outfile="${dir.reports}/checkstyle_summary.txt" /> <formatter type="summary" outfile="${dir.reports}/checkstyle_summary.txt"/>
</phpcodesniffer> </phpcodesniffer>
</target> </target>
<!-- copy/paste detector --> <!-- copy/paste detector -->
<target name="check:cpd" description="Checks similar code blocks."> <target name="check:cpd" depends="build:prepare">
<echo msg="Checking similar code blocks..." />
<phpcpd> <phpcpd>
<fileset refid="sourcecode" /> <fileset refid="sourcecode"/>
<formatter type="pmd" outfile="${dir.reports}/pmd-cpd.xml" /> <formatter type="pmd" outfile="${dir.reports}/pmd-cpd.xml"/>
</phpcpd> </phpcpd>
<!--
Previous / old version
Meritoo <github@meritoo.pl>
2017-02-22
<exec command="phpcpd \-\-log-pmd=${dir.reports}/pmd-cpd.xml ${dir.src}" />
-->
</target> </target>
<!-- Mess detector --> <!-- Mess detector -->
<target name="check:md" description="Generate code metrics"> <target name="check:md" depends="build:prepare">
<echo msg="Generating code metrics..." />
<phpmd rulesets="codesize,controversial,design,naming,unusedcode"> <phpmd rulesets="codesize,controversial,design,naming,unusedcode">
<fileset refid="sourcecode" /> <fileset refid="sourcecode"/>
<formatter type="html" outfile="${dir.reports}/phpmd.html" /> <formatter type="html" outfile="${dir.reports}/phpmd.html"/>
<formatter type="text" outfile="${dir.reports}/phpmd.txt" /> <formatter type="text" outfile="${dir.reports}/phpmd.txt"/>
</phpmd> </phpmd>
</target> </target>
<!-- Code dependency --> <!-- Code dependency -->
<target name="check:depend" description="Checks coupling and dependency"> <target name="check:depend" depends="build:prepare">
<echo msg="Checking coupling and dependency..." />
<phpdepend> <phpdepend>
<fileset refid="sourcecode" /> <fileset refid="sourcecode"/>
<logger type="jdepend-xml" outfile="${dir.reports.pdepend}/jdepend.xml" /> <logger type="jdepend-xml" outfile="${dir.reports.pdepend}/jdepend.xml"/>
<logger type="jdepend-chart" outfile="${dir.reports.pdepend}/dependencies.svg" /> <logger type="jdepend-chart" outfile="${dir.reports.pdepend}/dependencies.svg"/>
<logger type="overview-pyramid" outfile="${dir.reports.pdepend}/overview-pyramid.svg" /> <logger type="overview-pyramid" outfile="${dir.reports.pdepend}/overview-pyramid.svg"/>
</phpdepend> </phpdepend>
</target> </target>
<!-- Measure the size and analyzing the structure of a project --> <!-- Measure the size and analyzing the structure of a project -->
<target name="check:loc" description="Measures the size and analyzes the structure of a project"> <target name="check:loc" depends="build:prepare">
<echo msg="Measuring the size and analyzing the structure of a project..." />
<phploc reportType="txt" reportName="phploc" reportDirectory="${dir.reports}"> <phploc reportType="txt" reportName="phploc" reportDirectory="${dir.reports}">
<fileset refid="sourcecode" /> <fileset refid="sourcecode"/>
</phploc> </phploc>
<!--
Previous / old version
Meritoo <github@meritoo.pl>
2017-02-22
<exec command="phploc \-\-log-csv=${dir.reports}/phploc.csv ${dir.src}" />
-->
</target> </target>
<!-- Unit tests --> <!-- PHPUnit tests -->
<target name="test:unit" description="Executes unit tests"> <target name="test:phpunit" depends="build:prepare">
<echo msg="Running unit tests..." /> <exec command="${tests.phpunit.command}" passthru="true"/>
<exec command="${tests.framework.path}" passthru="true"/> </target>
<!-- Project build clean -->
<target name="build:clean">
<if>
<available file="${dir.reports}" type="dir" property="dir_is_available"/>
<then>
<delete dir="${dir.reports}"/>
</then>
</if>
</target>
<!-- Project build prepare -->
<target name="build:prepare" depends="build:clean">
<mkdir dir="${dir.reports}"/>
<mkdir dir="${dir.reports.pdepend}"/>
<mkdir dir="${dir.reports.coverage}"/>
</target> </target>
<!-- Checkout and finalization --> <!-- Checkout and finalization -->
<target name="app:checkout"> <target name="app:checkout">
<tstamp> <tstamp>
<format property="date_end" pattern="%Y-%m-%d %H:%M" /> <format property="date_end" pattern="%Y-%m-%d %H:%M"/>
</tstamp> </tstamp>
<echo msg="--------------------------------------------" /> <echo msg="--------------------------------------------"/>
<echo msg="Build tests finished at: ${date_end}" /> <echo msg="Build tests finished at: ${date_end}"/>
<echo msg="--------------------------------------------" /> <echo msg="--------------------------------------------"/>
</target> </target>
</project> </project>

View File

@@ -1,28 +1,11 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<!-- https://phpunit.de/manual/4.8/en/appendixes.configuration.html -->
<phpunit <phpunit
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="https://schema.phpunit.de/4.8/phpunit.xsd" xsi:noNamespaceSchemaLocation="https://schema.phpunit.de/4.8/phpunit.xsd"
backupGlobals="true" bootstrap="vendor/autoload.php"
backupStaticAttributes="false"
bootstrap="./vendor/autoload.php"
cacheTokens="false"
colors="true" colors="true"
convertErrorsToExceptions="true"
convertNoticesToExceptions="true"
convertWarningsToExceptions="true"
forceCoversAnnotation="false"
mapTestClassNameToCoveredClassName="false"
processIsolation="false"
stopOnError="false"
stopOnFailure="false"
stopOnIncomplete="false"
stopOnSkipped="false"
stopOnRisky="false"
testSuiteLoaderClass="PHPUnit_Runner_StandardTestSuiteLoader"
timeoutForSmallTests="1"
timeoutForMediumTests="10"
timeoutForLargeTests="60"
verbose="true" verbose="true"
> >
<php> <php>
@@ -31,23 +14,17 @@
<testsuites> <testsuites>
<testsuite name="Meritoo Package - Main Test Suite"> <testsuite name="Meritoo Package - Main Test Suite">
<directory>./tests/</directory> <directory>tests/</directory>
</testsuite> </testsuite>
</testsuites> </testsuites>
<filter> <filter>
<whitelist> <whitelist>
<directory>./src/</directory> <directory>src/</directory>
</whitelist> </whitelist>
</filter> </filter>
<groups>
<exclude>
<group>performance</group>
</exclude>
</groups>
<logging> <logging>
<log type="coverage-html" target="./build/logs/phpunit_coverage/html"/> <log type="coverage-html" target="build/reports/phpunit_coverage/html"/>
</logging> </logging>
</phpunit> </phpunit>

View File

@@ -130,11 +130,12 @@ class Collection implements Countable, ArrayAccess, IteratorAggregate
{ {
if (!empty($elements)) { if (!empty($elements)) {
foreach ($elements as $index => $element) { foreach ($elements as $index => $element) {
if (!$useIndexes) { if ($useIndexes) {
$index = null; $this->add($element, $index);
continue;
} }
$this->add($element, $index); $this->add($element);
} }
} }

View File

@@ -23,7 +23,7 @@ abstract class UnknownTypeException extends Exception
/** /**
* Creates exception * Creates exception
* *
* @param string|int $unknownType The unknown type of something (value of constant) * @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 BaseType $typeInstance An instance of class that contains type of the something
* @param string $typeName Name of the something * @param string $typeName Name of the something
* @return UnknownTypeException * @return UnknownTypeException
@@ -35,7 +35,7 @@ abstract class UnknownTypeException extends Exception
$allTypes = $typeInstance->getAll(); $allTypes = $typeInstance->getAll();
$types = Arrays::values2string($allTypes, '', ', '); $types = Arrays::values2string($allTypes, '', ', ');
$message = sprintf(sprintf($template, $unknownType, $typeName, $types)); $message = sprintf($template, $unknownType, $typeName, $types);
return new static($message); return new static($message);
} }

View File

@@ -28,13 +28,13 @@ class DisabledMethodException extends Exception
public static function create($disabledMethod, $alternativeMethod = '') public static function create($disabledMethod, $alternativeMethod = '')
{ {
$template = 'Method %s() cannot be called, because is disabled.'; $template = 'Method %s() cannot be called, because is disabled.';
$message = sprintf($template, $disabledMethod);
if (!empty($alternativeMethod)) { if (!empty($alternativeMethod)) {
$template .= ' Use %s() instead.'; $template = '%s Use %s() instead.';
$message = sprintf($template, $message, $alternativeMethod);
} }
$message = sprintf($template, $disabledMethod, $alternativeMethod);
return new static($message); return new static($message);
} }
} }

View File

@@ -14,13 +14,11 @@ use Meritoo\Common\Exception\Type\UnknownOopVisibilityTypeException;
use Meritoo\Common\Type\OopVisibilityType; use Meritoo\Common\Type\OopVisibilityType;
use Meritoo\Common\Utilities\Miscellaneous; use Meritoo\Common\Utilities\Miscellaneous;
use ReflectionClass; use ReflectionClass;
use ReflectionException;
use ReflectionMethod; use ReflectionMethod;
use stdClass; use stdClass;
/** /**
* BaseTestCaseTrait * Trait for the base test case
* Created on 2017-11-02
* *
* @author Meritoo <github@meritoo.pl> * @author Meritoo <github@meritoo.pl>
* @copyright Meritoo <http://www.meritoo.pl> * @copyright Meritoo <http://www.meritoo.pl>
@@ -173,7 +171,6 @@ trait BaseTestCaseTrait
* @param int $requiredArgumentsCount (optional) Expected count/amount of required arguments * @param int $requiredArgumentsCount (optional) Expected count/amount of required arguments
* of the verified method * of the verified method
* @throws UnknownOopVisibilityTypeException * @throws UnknownOopVisibilityTypeException
* @throws ReflectionException
* *
* Attention. 2nd argument, the $method, may be: * Attention. 2nd argument, the $method, may be:
* - string - name of the method * - 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 $argumentsCount (optional) Expected count/amount of arguments of the verified method
* @param int $requiredArgumentsCount (optional) Expected count/amount of required arguments of the verified * @param int $requiredArgumentsCount (optional) Expected count/amount of required arguments of the verified
* method * method
* @throws ReflectionException
* @throws UnknownOopVisibilityTypeException
*/ */
protected static function assertConstructorVisibilityAndArguments( protected static function assertConstructorVisibilityAndArguments(
$classNamespace, $classNamespace,
@@ -245,14 +240,19 @@ trait BaseTestCaseTrait
$reflection = new ReflectionClass($classNamespace); $reflection = new ReflectionClass($classNamespace);
$method = $reflection->getConstructor(); $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 * Asserts that class with given namespace has no constructor
* *
* @param string $classNamespace Namespace of class that contains constructor to verify * @param string $classNamespace Namespace of class that contains constructor to verify
* @throws ReflectionException
*/ */
protected static function assertHasNoConstructor($classNamespace) protected static function assertHasNoConstructor($classNamespace)
{ {

View File

@@ -43,7 +43,7 @@ abstract class BaseType
/** /**
* Returns information if given type is correct * Returns information if given type is correct
* *
* @param string $type The type to check * @param mixed $type The type to check
* @return bool * @return bool
*/ */
public function isCorrectType($type) public function isCorrectType($type)

View File

@@ -9,7 +9,7 @@
namespace Meritoo\Common\Utilities; namespace Meritoo\Common\Utilities;
/** /**
* Useful arrays methods * Useful methods related to arrays
* *
* @author Meritoo <github@meritoo.pl> * @author Meritoo <github@meritoo.pl>
* @copyright Meritoo <http://www.meritoo.pl> * @copyright Meritoo <http://www.meritoo.pl>
@@ -48,15 +48,13 @@ class Arrays
if (is_array($value)) { if (is_array($value)) {
$effect .= self::values2string($value, $arrayColumnKey, $separator); $effect .= self::values2string($value, $arrayColumnKey, $separator);
} else { } elseif (empty($arrayColumnKey)) {
if (empty($arrayColumnKey)) {
$effect .= $value; $effect .= $value;
} elseif ($key === $arrayColumnKey) { } elseif ($key === $arrayColumnKey) {
$effect .= $array[$arrayColumnKey]; $effect .= $array[$arrayColumnKey];
} }
} }
} }
}
return $effect; return $effect;
} }
@@ -111,8 +109,8 @@ class Arrays
*/ */
if (is_array($row) && !empty($row)) { if (is_array($row) && !empty($row)) {
foreach ($row as &$value) { foreach ($row as $key => $value) {
$value = html_entity_decode($value); $row[$key] = html_entity_decode($value);
} }
$rows[] = implode($separator, $row); $rows[] = implode($separator, $row);
@@ -363,7 +361,7 @@ class Arrays
* Name of the variable was not provided and it's a multi dimensional array? * Name of the variable was not provided and it's a multi dimensional array?
* Let's create the name, because variable is required for later usage (related to multi dimensional array) * Let's create the name, because variable is required for later usage (related to multi dimensional array)
*/ */
if (self::isMultiDimensional($array) && empty($jsVariableName)) { if (empty($jsVariableName) && $isMultiDimensional) {
$jsVariableName = 'autoGeneratedVariable'; $jsVariableName = 'autoGeneratedVariable';
} }
@@ -384,13 +382,13 @@ class Arrays
if (is_array($value)) { if (is_array($value)) {
$variable = $index; $variable = $index;
if (is_integer($index)) { if (is_int($index)) {
$variable = 'value_' . $variable; $variable = 'value_' . $variable;
} }
$value = self::array2JavaScript($value, $variable, $preserveIndexes); $value = self::array2JavaScript($value, $variable, $preserveIndexes);
if (!empty($value)) { if (null !== $value && '' !== $value) {
/* /*
* Add an empty line for the 1st iteration only. Required to avoid missing empty line after * Add an empty line for the 1st iteration only. Required to avoid missing empty line after
* declaration of variable: * declaration of variable:
@@ -409,8 +407,7 @@ class Arrays
$effect .= "\n"; $effect .= "\n";
} }
} }
} else { } elseif ($preserveIndexes) {
if ($preserveIndexes) {
if (!empty($jsVariableName)) { if (!empty($jsVariableName)) {
$index = Miscellaneous::quoteValue($index); $index = Miscellaneous::quoteValue($index);
$effect .= sprintf("\n%s[%s] = %s;", $jsVariableName, $index, $value); $effect .= sprintf("\n%s[%s] = %s;", $jsVariableName, $index, $value);
@@ -425,7 +422,6 @@ class Arrays
$effect .= sprintf($format, $value); $effect .= sprintf($format, $value);
} }
} }
}
if (!$preserveIndexes && !$isMultiDimensional) { if (!$preserveIndexes && !$isMultiDimensional) {
$effect .= ');'; $effect .= ');';
@@ -474,7 +470,7 @@ class Arrays
{ {
if (is_string($item)) { if (is_string($item)) {
if ($last) { if ($last) {
$item = substr($item, 0, strlen($item) - 1); $item = substr($item, 0, -1);
} else { } else {
$item = substr($item, 1); $item = substr($item, 1);
} }
@@ -517,7 +513,7 @@ class Arrays
* No elements or the element does not exist? * No elements or the element does not exist?
* Nothing to do * Nothing to do
*/ */
if (empty($array) || !in_array($item, $array)) { if (empty($array) || !in_array($item, $array, true)) {
return false; return false;
} }
@@ -556,20 +552,19 @@ class Arrays
foreach ($array as $key => &$value) { foreach ($array as $key => &$value) {
$remove = false; $remove = false;
$isArray = is_array($value);
if (is_array($value)) { if ($isArray) {
self::removeElements($value, $needle, $before); self::removeElements($value, $needle, $before);
if (is_array($value) && empty($value)) { if ($isArray && empty($value)) {
$remove = true; $remove = true;
} }
} else { } elseif ($value === $needle) {
if ($value === $needle) {
break; break;
} else { } else {
$remove = true; $remove = true;
} }
}
if ($remove) { if ($remove) {
unset($array[$key]); unset($array[$key]);
@@ -749,7 +744,7 @@ class Arrays
foreach ($exploded as $item) { foreach ($exploded as $item) {
$exploded2 = explode($valuesKeysSeparator, $item); $exploded2 = explode($valuesKeysSeparator, $item);
if (2 == count($exploded2)) { if (2 === count($exploded2)) {
$key = trim($exploded2[0]); $key = trim($exploded2[0]);
$value = trim($exploded2[1]); $value = trim($exploded2[1]);
@@ -781,8 +776,7 @@ class Arrays
if ($firstKey) { if ($firstKey) {
$effect = $exists; $effect = $exists;
$firstKey = false; $firstKey = false;
} else { } elseif ($explicit) {
if ($explicit) {
$effect = $effect && $exists; $effect = $effect && $exists;
if (!$effect) { if (!$effect) {
@@ -797,7 +791,6 @@ class Arrays
} }
} }
} }
}
return $effect; return $effect;
} }
@@ -839,6 +832,7 @@ class Arrays
foreach ($array as $key => $value) { foreach ($array as $key => $value) {
$path = $key; $path = $key;
$stopRecursion = false; $stopRecursion = false;
$valueIsArray = is_array($value);
/* /*
* If the path of parent element is delivered, * If the path of parent element is delivered,
@@ -871,7 +865,7 @@ class Arrays
* or * or
* - the process is stopped, recursive is not used * - the process is stopped, recursive is not used
*/ */
if (!is_array($value) || (is_array($value) && empty($value)) || $stopRecursion) { if (!$valueIsArray || ($valueIsArray && empty($value)) || $stopRecursion) {
$paths[$path] = $value; $paths[$path] = $value;
continue; continue;
} }
@@ -879,7 +873,7 @@ class Arrays
/* /*
* Let's iterate through the next level, using recursive * Let's iterate through the next level, using recursive
*/ */
if (is_array($value)) { if ($valueIsArray) {
$recursivePaths = self::getLastElementsPaths($value, $separator, $path, $stopIfMatchedBy); $recursivePaths = self::getLastElementsPaths($value, $separator, $path, $stopIfMatchedBy);
$paths += $recursivePaths; $paths += $recursivePaths;
} }
@@ -1100,7 +1094,8 @@ class Arrays
$recursiveValues = self::getAllValuesOfKey($value, $key); $recursiveValues = self::getAllValuesOfKey($value, $key);
if (!empty($recursiveValues)) { if (!empty($recursiveValues)) {
$values = array_merge($values, $recursiveValues); $merged = array_merge($values, $recursiveValues);
$values = $merged;
} }
} }
} }
@@ -1282,7 +1277,7 @@ class Arrays
} }
if (Regex::endsWith($element, $separator)) { if (Regex::endsWith($element, $separator)) {
$element = substr($element, 0, strlen($element) - 1); $element = substr($element, 0, -1);
} }
} }
@@ -1354,7 +1349,7 @@ class Arrays
* Values should be compared only and both arrays are one-dimensional? * Values should be compared only and both arrays are one-dimensional?
* Let's find difference by using simple function * Let's find difference by using simple function
*/ */
if ($valuesOnly && 1 == self::getDimensionsCount($array1) && 1 == self::getDimensionsCount($array2)) { if ($valuesOnly && 1 === self::getDimensionsCount($array1) && 1 === self::getDimensionsCount($array2)) {
return array_diff($array1, $array2); return array_diff($array1, $array2);
} }
@@ -1371,25 +1366,24 @@ class Arrays
if ($array2HasKey && is_array($array2[$key])) { if ($array2HasKey && is_array($array2[$key])) {
$difference = self::arrayDiffRecursive($value, $array2[$key], $valuesOnly); $difference = self::arrayDiffRecursive($value, $array2[$key], $valuesOnly);
} }
} else { } elseif (!$array2HasKey || ($array2HasKey && $value !== $array2[$key])) {
/* /*
* 2nd array hasn't key from 1st array? * We are here, because:
* a) 2nd array hasn't key from 1st array
* OR * OR
* Key exists in both, 1st and 2nd array, but values are different? * b) key exists in both, 1st and 2nd array, but values are different
*/ */
if (!$array2HasKey || ($array2HasKey && $value != $array2[$key])) {
$difference = $value; $difference = $value;
} }
}
if (null !== $difference) { if (null !== $difference) {
$effect[] = $difference; $effect[] = $difference;
} }
} else {
/* /*
* The key exists in 2nd array? * The key exists in 2nd array?
*/ */
if ($array2HasKey) { } elseif ($array2HasKey) {
/* /*
* The value it's an array (it's a nested array)? * The value it's an array (it's a nested array)?
*/ */
@@ -1408,15 +1402,14 @@ class Arrays
} }
$effect[$key] = $diff; $effect[$key] = $diff;
} else {
/* /*
* Value is different than in 2nd array? * Value is different than in 2nd array?
* OKay, I've got difference * OKay, I've got difference
*/ */
if ($value != $array2[$key]) { } elseif ($value !== $array2[$key]) {
$effect[$key] = $value; $effect[$key] = $value;
} }
}
} else { } else {
/* /*
* OKay, I've got difference * OKay, I've got difference
@@ -1424,7 +1417,6 @@ class Arrays
$effect[$key] = $value; $effect[$key] = $value;
} }
} }
}
return $effect; return $effect;
} }
@@ -1581,6 +1573,52 @@ class Arrays
return $dimensionsCount; return $dimensionsCount;
} }
/**
* Returns non-empty values, e.g. without "" (empty string), null or []
*
* @param array $values The values to filter
* @return array
*/
public static function getNonEmptyValues(array $values)
{
/*
* No values?
* Nothing to do
*/
if (empty($values)) {
return [];
}
return array_filter($values, function ($value) {
$nonEmptyScalar = is_scalar($value) && '' !== $value;
$nonEmptyArray = is_array($value) && !empty($value);
return $nonEmptyScalar || $nonEmptyArray || is_object($value);
});
}
/**
* Returns non-empty values concatenated by given separator
*
* @param array $values The values to filter
* @param string $separator (optional) Separator used to implode the values. Default: ", ".
* @return string
*/
public static function getNonEmptyValuesAsString(array $values, $separator = ', ')
{
$nonEmpty = self::getNonEmptyValues($values);
/*
* No values?
* Nothing to do
*/
if (empty($nonEmpty)) {
return '';
}
return implode($separator, $nonEmpty);
}
/** /**
* Returns neighbour (next or previous element) for given element * Returns neighbour (next or previous element) for given element
* *
@@ -1595,17 +1633,17 @@ class Arrays
$noPrevious = !$next && self::isFirstElement($array, $element); $noPrevious = !$next && self::isFirstElement($array, $element);
/* /*
* No elements? * Previous neighbour should be returned and given element is first?
* OR
* Given element does not exist in given array?
* OR * OR
* Next neighbour should be returned and given element is last? * Next neighbour should be returned and given element is last?
* OR * OR
* Previous neighbour should be returned and given element is first? * No elements?
* OR
* Given element does not exist in given array?
* *
* Nothing to do * Nothing to do
*/ */
if (empty($array) || !in_array($element, $array) || $noNext || $noPrevious) { if ($noPrevious || $noNext || empty($array) || !in_array($element, $array, true)) {
return null; return null;
} }

View File

@@ -64,8 +64,7 @@ class Date
const DATE_DIFFERENCE_UNIT_YEARS = 'years'; const DATE_DIFFERENCE_UNIT_YEARS = 'years';
/** /**
* Returns start and end date for given period. * Returns date's period (that contains start and end date) for given period
* The dates are returned in an array with indexes 'start' and 'end'.
* *
* @param int $period The period, type of period. One of DatePeriod class constants, e.g. DatePeriod::LAST_WEEK. * @param int $period The period, type of period. One of DatePeriod class constants, e.g. DatePeriod::LAST_WEEK.
* @throws Exception * @throws Exception
@@ -141,7 +140,12 @@ class Date
$dateStart = new DateTime(); $dateStart = new DateTime();
$dateEnd = new DateTime(); $dateEnd = new DateTime();
if (DatePeriod::LAST_YEAR === $period || DatePeriod::NEXT_YEAR === $period) { $yearPeriod = [
DatePeriod::LAST_YEAR,
DatePeriod::NEXT_YEAR,
];
if (in_array($period, $yearPeriod, true)) {
$yearDifference = 1; $yearDifference = 1;
if (DatePeriod::LAST_YEAR === $period) { if (DatePeriod::LAST_YEAR === $period) {
@@ -168,7 +172,7 @@ class Date
return null; return null;
} }
$dateStart->setTime(0, 0, 0); $dateStart->setTime(0, 0);
$dateEnd->setTime(23, 59, 59); $dateEnd->setTime(23, 59, 59);
return new DatePeriod($dateStart, $dateEnd); return new DatePeriod($dateStart, $dateEnd);
@@ -218,7 +222,8 @@ class Date
return $dateTime return $dateTime
->setTime($hour, $minute, $second) ->setTime($hour, $minute, $second)
->format($format); ->format($format)
;
} }
/** /**
@@ -350,7 +355,7 @@ class Date
* *
* @param string|DateTime $dateStart The start date * @param string|DateTime $dateStart The start date
* @param string|DateTime $dateEnd The end date * @param string|DateTime $dateEnd The end date
* @param int $differenceUnit (optional) Unit of date difference. One of this class * @param string $differenceUnit (optional) Unit of date difference. One of this class
* DATE_DIFFERENCE_UNIT_* constants. If is set to null all units are * DATE_DIFFERENCE_UNIT_* constants. If is set to null all units are
* returned in the array. * returned in the array.
* @return array|int * @return array|int
@@ -531,11 +536,15 @@ class Date
/** /**
* Returns random date based on given start date * Returns random date based on given start date
* *
* @param DateTime $startDate The start date. Start of the random date. * @param DateTime $startDate (optional) Beginning of the random date. If not provided, current date will
* @param int $start (optional) Start of random partition * be used (default behaviour).
* @param int $end (optional) End of random partition * @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 * @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 * @throws Exception
* @return DateTime * @return DateTime
*/ */
@@ -569,10 +578,11 @@ class Date
* @param mixed $value The value which maybe is a 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 * @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 * 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. * @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 * 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 * @return DateTime|bool
*/ */
public static function getDateTime($value, $allowCompoundFormats = false, $dateFormat = 'Y-m-d') public static function getDateTime($value, $allowCompoundFormats = false, $dateFormat = 'Y-m-d')

View File

@@ -52,7 +52,7 @@ class Locale
LC_MESSAGES, LC_MESSAGES,
]; ];
if (empty($languageCode) || !in_array($category, $availableCategories)) { if (empty($languageCode) || !in_array($category, $availableCategories, true)) {
return false; return false;
} }

View File

@@ -733,7 +733,7 @@ class MimeTypes
*/ */
public static function getExtension($mimeType) public static function getExtension($mimeType)
{ {
if (is_string($mimeType) && in_array($mimeType, self::$mimeTypes)) { if (is_string($mimeType) && in_array($mimeType, self::$mimeTypes, true)) {
$data = Arrays::setKeysAsValues(self::$mimeTypes, false); $data = Arrays::setKeysAsValues(self::$mimeTypes, false);
return $data[$mimeType]; return $data[$mimeType];
@@ -806,7 +806,7 @@ class MimeTypes
*/ */
public static function isImage($mimeType) public static function isImage($mimeType)
{ {
if (in_array($mimeType, self::$mimeTypes)) { if (in_array($mimeType, self::$mimeTypes, true)) {
return (bool)preg_match('|^image/.+$|', $mimeType); return (bool)preg_match('|^image/.+$|', $mimeType);
} }

View File

@@ -296,34 +296,6 @@ class Miscellaneous
return $effect; return $effect;
} }
/**
* Displays variable content as preformatted text (fixed-width font and preserves both spaces and line breaks)
*
* If xdebug php module is loaded, displays variable using var_dump(), otherwise <pre>var_dump()</pre>.
* You can pass as many variables as you wish.
*
* Pass each variable as argument of this function. Amount unlimited. Variables are loaded using the
* func_get_args() function (@see http://pl1.php.net/manual/en/function.func-get-args.php).
*/
public static function variableDump()
{
$xdebugLoaded = self::isPhpModuleLoaded('xdebug');
if (!$xdebugLoaded) {
echo '<pre>';
}
$arguments = func_get_args();
foreach ($arguments as $argument) {
var_dump($argument);
}
if (!$xdebugLoaded) {
echo '</pre>';
}
}
/** /**
* Returns information if given PHP module is compiled and loaded * Returns information if given PHP module is compiled and loaded
* *

View File

@@ -10,7 +10,6 @@ namespace Meritoo\Common\Utilities;
use Doctrine\Common\Collections\ArrayCollection; use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\ORM\EntityManager; use Doctrine\ORM\EntityManager;
use Doctrine\ORM\OptimisticLockException;
use Doctrine\ORM\Query\Expr\Join; use Doctrine\ORM\Query\Expr\Join;
use Doctrine\ORM\Query\Parameter; use Doctrine\ORM\Query\Parameter;
use Doctrine\ORM\QueryBuilder; use Doctrine\ORM\QueryBuilder;
@@ -91,7 +90,7 @@ class QueryBuilderUtility
* @param array $criteria (optional) The criteria used in WHERE clause. It may simple array with pairs * @param array $criteria (optional) The criteria used in WHERE clause. It may simple array with pairs
* key-value or an array of arrays where second element of sub-array is the * key-value or an array of arrays where second element of sub-array is the
* comparison operator. Example below. * comparison operator. Example below.
* @param string $alias (optional) Alias used in the query * @param string|null $alias (optional) Alias used in the query
* @return QueryBuilder * @return QueryBuilder
* *
* Example of the $criteria argument: * Example of the $criteria argument:
@@ -107,7 +106,7 @@ class QueryBuilderUtility
* 'position' => 5, * 'position' => 5,
* ] * ]
*/ */
public static function setCriteria(QueryBuilder $queryBuilder, array $criteria = [], $alias = '') public static function setCriteria(QueryBuilder $queryBuilder, array $criteria = [], $alias = null)
{ {
/* /*
* No criteria used in WHERE clause? * No criteria used in WHERE clause?
@@ -121,7 +120,7 @@ class QueryBuilderUtility
* No alias provided? * No alias provided?
* Let's use root alias * Let's use root alias
*/ */
if (empty($alias)) { if (null === $alias || '' === $alias) {
$alias = self::getRootAlias($queryBuilder); $alias = self::getRootAlias($queryBuilder);
} }
@@ -129,7 +128,7 @@ class QueryBuilderUtility
$compareOperator = '='; $compareOperator = '=';
if (is_array($value) && !empty($value)) { if (is_array($value) && !empty($value)) {
if (2 == count($value)) { if (2 === count($value)) {
$compareOperator = $value[1]; $compareOperator = $value[1];
} }
@@ -158,7 +157,6 @@ class QueryBuilderUtility
* @param array|ArrayCollection $entities The entities to delete * @param array|ArrayCollection $entities The entities to delete
* @param bool $flushDeleted (optional) If is set to true, flushes the deleted objects (default * @param bool $flushDeleted (optional) If is set to true, flushes the deleted objects (default
* behaviour). Otherwise - not. * behaviour). Otherwise - not.
* @throws OptimisticLockException
* @return bool * @return bool
*/ */
public static function deleteEntities(EntityManager $entityManager, $entities, $flushDeleted = true) public static function deleteEntities(EntityManager $entityManager, $entities, $flushDeleted = true)

View File

@@ -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 mixed $object Object that should contains given property
* @param string $property Name of the property * @param string $property Name of the property
@@ -692,4 +692,25 @@ class Reflection
$reflectionProperty->setAccessible(false); $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);
}
}
} }

View File

@@ -12,7 +12,7 @@ use Meritoo\Common\Exception\Regex\IncorrectColorHexLengthException;
use Meritoo\Common\Exception\Regex\InvalidColorHexValueException; use Meritoo\Common\Exception\Regex\InvalidColorHexValueException;
/** /**
* Useful regular expressions methods * Useful methods related to regular expressions
* *
* @author Meritoo <github@meritoo.pl> * @author Meritoo <github@meritoo.pl>
* @copyright Meritoo <http://www.meritoo.pl> * @copyright Meritoo <http://www.meritoo.pl>
@@ -102,7 +102,7 @@ class Regex
* Tax ID is not 10 characters length OR is not numeric? * Tax ID is not 10 characters length OR is not numeric?
* Nothing to do * Nothing to do
*/ */
if (10 !== strlen($taxId) || !is_numeric($taxId)) { if (!is_numeric($taxId) || 10 !== strlen($taxId)) {
return false; return false;
} }
@@ -125,14 +125,11 @@ class Regex
} }
/* /*
* Last number it's not a remainder from dividing per 11? * Last number it's a remainder from dividing per 11?
* Nothing to do * Tax ID is valid
*/ */
if ($sum % 11 == $taxId[9]) {
return true;
}
return false; return $sum % 11 === (int)$taxId[9];
} }
/** /**
@@ -248,7 +245,7 @@ class Regex
if ($itsRegularExpression) { if ($itsRegularExpression) {
$matchesCount = preg_match($filterExpression, $value); $matchesCount = preg_match($filterExpression, $value);
$remove = 0 == $matchesCount; $remove = 0 === $matchesCount;
} else { } else {
if (is_string($value)) { if (is_string($value)) {
$value = sprintf('\'%s\'', $value); $value = sprintf('\'%s\'', $value);
@@ -306,13 +303,11 @@ class Regex
if ($mustAllMatch) { if ($mustAllMatch) {
$effect = $effect && $matched; $effect = $effect && $matched;
} else { } elseif ($matched) {
if ($matched) {
$effect = $matched; $effect = $matched;
break; break;
} }
} }
}
return $effect; return $effect;
} }
@@ -501,7 +496,7 @@ class Regex
public static function startsWith($string, $beginning) public static function startsWith($string, $beginning)
{ {
if (!empty($string) && !empty($beginning)) { if (!empty($string) && !empty($beginning)) {
if (1 == strlen($beginning) && !self::isLetterOrDigit($beginning)) { if (1 === strlen($beginning) && !self::isLetterOrDigit($beginning)) {
$beginning = '\\' . $beginning; $beginning = '\\' . $beginning;
} }
@@ -522,7 +517,7 @@ class Regex
*/ */
public static function endsWith($string, $ending) public static function endsWith($string, $ending)
{ {
if (1 == strlen($ending) && !self::isLetterOrDigit($ending)) { if (1 === strlen($ending) && !self::isLetterOrDigit($ending)) {
$ending = '\\' . $ending; $ending = '\\' . $ending;
} }
@@ -607,7 +602,7 @@ class Regex
*/ */
public static function contains($haystack, $needle) public static function contains($haystack, $needle)
{ {
if (1 == strlen($needle) && !self::isLetterOrDigit($needle)) { if (1 === strlen($needle) && !self::isLetterOrDigit($needle)) {
$needle = '\\' . $needle; $needle = '\\' . $needle;
} }
@@ -694,14 +689,14 @@ class Regex
*/ */
public static function isValidNip($nip) public static function isValidNip($nip)
{ {
$nip = preg_replace('/[^0-9]/', '', $nip); $nip = preg_replace('/[\D]/', '', $nip);
$invalidNips = [ $invalidNips = [
'1234567890', '1234567890',
'0000000000', '0000000000',
]; ];
if (!preg_match('/^[0-9]{10}$/', $nip) || in_array($nip, $invalidNips)) { if (!preg_match('/^[\d]{10}$/', $nip) || in_array($nip, $invalidNips, true)) {
return false; return false;
} }
@@ -723,9 +718,9 @@ class Regex
} }
$modulo = $sum % 11; $modulo = $sum % 11;
$numberControl = (10 == $modulo) ? 0 : $modulo; $numberControl = (10 === $modulo) ? 0 : $modulo;
return $numberControl == $nip[9]; return $numberControl === (int)$nip[9];
} }
/** /**
@@ -924,4 +919,37 @@ class Regex
return (bool)preg_match($pattern, $value); return (bool)preg_match($pattern, $value);
} }
/**
* Returns slug for given value
*
* @param string $value Value that should be transformed to slug
* @return string|bool
*/
public static function createSlug($value)
{
/*
* Not a scalar value?
* Nothing to do
*/
if (!is_scalar($value)) {
return false;
}
/*
* It's an empty string?
* Nothing to do
*/
if ('' === $value) {
return '';
}
$id = 'Latin-ASCII; NFD; [:Nonspacing Mark:] Remove; NFC; [:Punctuation:] Remove; Lower();';
$transliterator = \Transliterator::create($id);
$cleanValue = trim($value);
$result = $transliterator->transliterate($cleanValue);
return preg_replace('/[-\s]+/', '-', $result);
}
} }

View File

@@ -177,10 +177,13 @@ class Repository
$direction = 'ASC' $direction = 'ASC'
) { ) {
$alias = 'qb'; $alias = 'qb';
$queryBuilder = $repository->createQueryBuilder($alias);
return $repository if (empty($property)) {
->createQueryBuilder($alias) return $queryBuilder;
->orderBy(sprintf('%s.%s', $alias, $property), $direction); }
return $queryBuilder->orderBy(sprintf('%s.%s', $alias, $property), $direction);
} }
/** /**

View File

@@ -93,7 +93,7 @@ class Uri
/* /*
* Oops, cannot match protocol * Oops, cannot match protocol
*/ */
if (0 == $matchCount) { if (0 === $matchCount) {
return ''; return '';
} }

View File

@@ -40,7 +40,7 @@ class Xml
$query = $path->query('/*/*'); $query = $path->query('/*/*');
$nodesCount = $query->length; $nodesCount = $query->length;
if (0 == $nodesCount) { if (0 === $nodesCount) {
return $element1; return $element1;
} }

159
src/ValueObject/Address.php Normal file
View File

@@ -0,0 +1,159 @@
<?php
/**
* (c) Meritoo.pl, http://www.meritoo.pl
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Meritoo\Common\ValueObject;
use Meritoo\Common\Utilities\Arrays;
/**
* Address
*
* @author Meritoo <github@meritoo.pl>
* @copyright Meritoo <http://www.meritoo.pl>
*/
class Address
{
/**
* The street
*
* @var string
*/
protected $street;
/**
* The number of building
*
* @var string
*/
protected $buildingNumber;
/**
* The number of flat
*
* @var string
*/
protected $flatNumber;
/**
* The zip code
*
* @var string
*/
protected $zipCode;
/**
* The city, location
*
* @var string
*/
protected $city;
/**
* Class constructor
*
* @param string $city City, location
* @param string $zipCode The zip code
* @param string $street The street
* @param string $buildingNumber The number of building
* @param string $flatNumber (optional) The number of flat. Default: "".
*/
public function __construct($city, $zipCode, $street, $buildingNumber, $flatNumber = '')
{
$this->city = $city;
$this->zipCode = $zipCode;
$this->street = $street;
$this->buildingNumber = $buildingNumber;
$this->flatNumber = $flatNumber;
}
/**
* Returns representation of object as string
*
* @return string
*/
public function __toString()
{
$values = [
$this->getFullStreet(),
$this->zipCode,
$this->city,
];
return Arrays::getNonEmptyValuesAsString($values);
}
/**
* Returns street
*
* @return string
*/
public function getStreet()
{
return $this->street;
}
/**
* Returns full street (name + building & flat number)
*
* @return string
*/
public function getFullStreet()
{
if (empty($this->street)) {
return '';
}
$numbers = $this->buildingNumber;
if (!empty($numbers) && !empty($this->flatNumber)) {
$numbers = sprintf('%s/%s', $numbers, $this->flatNumber);
}
return sprintf('%s %s', $this->street, $numbers);
}
/**
* Returns number of building
*
* @return string
*/
public function getBuildingNumber()
{
return $this->buildingNumber;
}
/**
* Returns number of flat
*
* @return string
*/
public function getFlatNumber()
{
return $this->flatNumber;
}
/**
* Returns zip code
*
* @return string
*/
public function getZipCode()
{
return $this->zipCode;
}
/**
* Returns city, location
*
* @return string
*/
public function getCity()
{
return $this->city;
}
}

View File

@@ -0,0 +1,81 @@
<?php
/**
* (c) Meritoo.pl, http://www.meritoo.pl
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Meritoo\Common\ValueObject;
use Meritoo\Common\Utilities\Arrays;
/**
* Bank account
*
* @author Meritoo <github@meritoo.pl>
* @copyright Meritoo <http://www.meritoo.pl>
*/
class BankAccount
{
/**
* Name of bank
*
* @var string
*/
protected $bankName;
/**
* Number of bank's account
*
* @var string
*/
protected $accountNumber;
/**
* Class constructor
*
* @param string $bankName Name of bank
* @param string $accountNumber Number of bank's account
*/
public function __construct($bankName, $accountNumber)
{
$this->bankName = $bankName;
$this->accountNumber = $accountNumber;
}
/**
* Returns representation of object as string
*
* @return string
*/
public function __toString()
{
$values = [
$this->bankName,
$this->accountNumber,
];
return Arrays::getNonEmptyValuesAsString($values);
}
/**
* Returns name of bank
*
* @return string
*/
public function getBankName()
{
return $this->bankName;
}
/**
* Returns number of bank's account
*
* @return string
*/
public function getAccountNumber()
{
return $this->accountNumber;
}
}

101
src/ValueObject/Company.php Normal file
View File

@@ -0,0 +1,101 @@
<?php
/**
* (c) Meritoo.pl, http://www.meritoo.pl
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Meritoo\Common\ValueObject;
use Meritoo\Common\Utilities\Arrays;
/**
* Company
*
* @author Meritoo <github@meritoo.pl>
* @copyright Meritoo <http://www.meritoo.pl>
*/
class Company
{
/**
* Name of company
*
* @var string
*/
protected $name;
/**
* Address of company
*
* @var Address
*/
protected $address;
/**
* Bank account of company
*
* @var BankAccount
*/
protected $bankAccount;
/**
* Class constructor
*
* @param string $name Name of company
* @param Address $address Address of company
* @param BankAccount|null $bankAccount (optional) Bank account of company
*/
public function __construct($name, Address $address, BankAccount $bankAccount = null)
{
$this->name = $name;
$this->address = $address;
$this->bankAccount = $bankAccount;
}
/**
* Returns representation of object as string
*
* @return string
*/
public function __toString()
{
$values = [
$this->name,
$this->address,
$this->bankAccount,
];
return Arrays::getNonEmptyValuesAsString($values);
}
/**
* Returns name of company
*
* @return string
*/
public function getName()
{
return $this->name;
}
/**
* Returns address of company
*
* @return Address
*/
public function getAddress()
{
return $this->address;
}
/**
* Returns bank account of company
*
* @return BankAccount|null
*/
public function getBankAccount()
{
return $this->bankAccount;
}
}

0
tests/Resources/var/cache/.gitkeep vendored Normal file
View File

View File

View File

View File

@@ -0,0 +1,44 @@
<?php
/**
* (c) Meritoo.pl, http://www.meritoo.pl
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Meritoo\Common\Test\Utilities\Arrays;
/**
* Simple class convertible to string.
* Used for testing the Arrays class.
*
* @author Meritoo <github@meritoo.pl>
* @copyright Meritoo <http://www.meritoo.pl>
*/
class SimpleToString
{
/**
* Identifier
*
* @var string
*/
private $id;
/**
* Class constructor
*
* @param string $id Identifier
*/
public function __construct($id)
{
$this->id = $id;
}
/**
* {@inheritdoc}
*/
public function __toString()
{
return sprintf('Instance with ID: %s', $this->id);
}
}

View File

@@ -9,6 +9,7 @@
namespace Meritoo\Common\Test\Utilities; namespace Meritoo\Common\Test\Utilities;
use Meritoo\Common\Test\Base\BaseTestCase; use Meritoo\Common\Test\Base\BaseTestCase;
use Meritoo\Common\Test\Utilities\Arrays\SimpleToString;
use Meritoo\Common\Utilities\Arrays; use Meritoo\Common\Utilities\Arrays;
/** /**
@@ -1486,6 +1487,43 @@ letsTest[2] = value_2;';
self::assertTrue(Arrays::isMultiDimensional($this->complexArray)); self::assertTrue(Arrays::isMultiDimensional($this->complexArray));
} }
/**
* @param string $description Description of test case
* @param array $values The values to filter
* @param array $expected Expected non-empty values
*
* @dataProvider provideValuesToFilterNonEmpty
*/
public function testGetNonEmptyValues($description, array $values, array $expected)
{
self::assertSame($expected, Arrays::getNonEmptyValues($values), $description);
}
/**
* @param string $description Description of test case
* @param array $values The values to filter
* @param string $expected Expected non-empty values (as string)
*
* @dataProvider provideValuesToFilterNonEmptyAsStringUsingDefaultSeparator
*/
public function testGetNonEmptyValuesAsStringUsingDefaultSeparator($description, array $values, $expected)
{
self::assertSame($expected, Arrays::getNonEmptyValuesAsString($values), $description);
}
/**
* @param string $description Description of test case
* @param array $values The values to filter
* @param string $separator Separator used to implode the values
* @param string $expected Expected non-empty values (as string)
*
* @dataProvider provideValuesToFilterNonEmptyAsString
*/
public function testGetNonEmptyValuesAsString($description, array $values, $separator, $expected)
{
self::assertSame($expected, Arrays::getNonEmptyValuesAsString($values, $separator), $description);
}
/** /**
* Provides simple array to set/replace values with keys * Provides simple array to set/replace values with keys
* *
@@ -1807,6 +1845,264 @@ letsTest[2] = value_2;';
]; ];
} }
/**
* Provide values to filter and get non-empty values
*
* @return \Generator
*/
public function provideValuesToFilterNonEmpty()
{
$simpleObject = new SimpleToString('1234');
yield[
'An empty array (no values to filter)',
[],
[],
];
yield[
'All values are empty',
[
'',
null,
[],
],
[],
];
yield[
'5 values with 2 empty strings',
[
'test 1',
'',
'test 2',
'test 3',
'',
],
[
0 => 'test 1',
2 => 'test 2',
3 => 'test 3',
],
];
yield[
'"0" shouldn\'t be treated like an empty value',
[
123,
0,
456,
],
[
123,
0,
456,
],
];
yield[
'Object shouldn\'t be treated like an empty value',
[
'test 1',
$simpleObject,
'test 2',
null,
'test 3',
],
[
0 => 'test 1',
1 => $simpleObject,
2 => 'test 2',
4 => 'test 3',
],
];
yield[
'Mixed values (non-empty, empty, strings, integers, objects)',
[
'test 1',
'',
123,
null,
'test 2',
'test 3',
0,
$simpleObject,
456,
[],
$simpleObject,
],
[
0 => 'test 1',
2 => 123,
4 => 'test 2',
5 => 'test 3',
6 => 0,
7 => $simpleObject,
8 => 456,
10 => $simpleObject,
],
];
}
/**
* Provide values to filter and get non-empty values concatenated by default separator
*
* @return \Generator
*/
public function provideValuesToFilterNonEmptyAsStringUsingDefaultSeparator()
{
yield[
'An empty array (no values to filter)',
[],
'',
];
yield[
'All values are empty',
[
'',
null,
[],
],
'',
];
yield[
'5 values with 2 empty strings',
[
'test 1',
'',
'test 2',
'test 3',
'',
],
'test 1, test 2, test 3',
];
yield[
'Numbers with "0" that shouldn\'t be treated like an empty value',
[
123,
0,
456,
],
'123, 0, 456',
];
yield[
'Object shouldn\'t be treated like an empty value',
[
'test 1',
new SimpleToString('1234'),
'test 2',
null,
'test 3',
],
'test 1, Instance with ID: 1234, test 2, test 3',
];
yield[
'Mixed values (non-empty, empty, strings, integers, objects)',
[
'test 1',
'',
123,
null,
'test 2',
'test 3',
0,
new SimpleToString('A1XC90Z'),
456,
[],
new SimpleToString('FF-45-0Z'),
],
'test 1, 123, test 2, test 3, 0, Instance with ID: A1XC90Z, 456, Instance with ID: FF-45-0Z',
];
}
/**
* Provide values to filter and get non-empty values concatenated by given separator
*
* @return \Generator
*/
public function provideValuesToFilterNonEmptyAsString()
{
yield[
'An empty array (no values to filter)',
[],
' | ',
'',
];
yield[
'All values are empty',
[
'',
null,
[],
],
' | ',
'',
];
yield[
'5 values with 2 empty strings',
[
'test 1',
'',
'test 2',
'test 3',
'',
],
' | ',
'test 1 | test 2 | test 3',
];
yield[
'Numbers with "0" that shouldn\'t be treated like an empty value',
[
123,
0,
456,
],
' <-> ',
'123 <-> 0 <-> 456',
];
yield[
'Object shouldn\'t be treated like an empty value',
[
'test 1',
new SimpleToString('1234'),
'test 2',
null,
'test 3',
],
' | ',
'test 1 | Instance with ID: 1234 | test 2 | test 3',
];
yield[
'Mixed values (non-empty, empty, strings, integers, objects)',
[
'test 1',
'',
123,
null,
'test 2',
'test 3',
0,
new SimpleToString('A1XC90Z'),
456,
[],
new SimpleToString('FF-45-0Z'),
],
';',
'test 1;123;test 2;test 3;0;Instance with ID: A1XC90Z;456;Instance with ID: FF-45-0Z',
];
}
/** /**
* {@inheritdoc} * {@inheritdoc}
*/ */

View File

@@ -279,9 +279,18 @@ class DateTest extends BaseTestCase
self::assertEquals(0, Date::getDateDifference($dateStart, $dateEnd, Date::DATE_DIFFERENCE_UNIT_YEARS)); self::assertEquals(0, Date::getDateDifference($dateStart, $dateEnd, Date::DATE_DIFFERENCE_UNIT_YEARS));
self::assertEquals(0, Date::getDateDifference(new DateTime($dateStart), new DateTime($dateEnd), Date::DATE_DIFFERENCE_UNIT_YEARS)); self::assertEquals(0, Date::getDateDifference(new DateTime($dateStart), new DateTime($dateEnd), Date::DATE_DIFFERENCE_UNIT_YEARS));
self::assertEquals(0, Date::getDateDifference($dateStart, $dateEnd, Date::DATE_DIFFERENCE_UNIT_MONTHS));
self::assertEquals(0, Date::getDateDifference(new DateTime($dateStart), new DateTime($dateEnd), Date::DATE_DIFFERENCE_UNIT_MONTHS));
self::assertEquals(1, Date::getDateDifference($dateStart, $dateEnd, Date::DATE_DIFFERENCE_UNIT_DAYS)); self::assertEquals(1, Date::getDateDifference($dateStart, $dateEnd, Date::DATE_DIFFERENCE_UNIT_DAYS));
self::assertEquals(1, Date::getDateDifference(new DateTime($dateStart), new DateTime($dateEnd), Date::DATE_DIFFERENCE_UNIT_DAYS)); self::assertEquals(1, Date::getDateDifference(new DateTime($dateStart), new DateTime($dateEnd), Date::DATE_DIFFERENCE_UNIT_DAYS));
self::assertEquals(0, Date::getDateDifference($dateStart, $dateEnd, Date::DATE_DIFFERENCE_UNIT_HOURS));
self::assertEquals(0, Date::getDateDifference(new DateTime($dateStart), new DateTime($dateEnd), Date::DATE_DIFFERENCE_UNIT_HOURS));
self::assertEquals(0, Date::getDateDifference($dateStart, $dateEnd, Date::DATE_DIFFERENCE_UNIT_MINUTES));
self::assertEquals(0, Date::getDateDifference(new DateTime($dateStart), new DateTime($dateEnd), Date::DATE_DIFFERENCE_UNIT_MINUTES));
/* /*
* Difference of 1 day (using the relative date format) * Difference of 1 day (using the relative date format)
*/ */
@@ -294,8 +303,10 @@ class DateTest extends BaseTestCase
]; ];
self::assertEquals($effect, Date::getDateDifference(new DateTime('yesterday'), new DateTime('midnight'))); self::assertEquals($effect, Date::getDateDifference(new DateTime('yesterday'), new DateTime('midnight')));
self::assertEquals(0, Date::getDateDifference(new DateTime('yesterday'), new DateTime('midnight'), Date::DATE_DIFFERENCE_UNIT_MONTHS));
self::assertEquals(1, Date::getDateDifference(new DateTime('yesterday'), new DateTime('midnight'), Date::DATE_DIFFERENCE_UNIT_DAYS)); self::assertEquals(1, Date::getDateDifference(new DateTime('yesterday'), new DateTime('midnight'), Date::DATE_DIFFERENCE_UNIT_DAYS));
self::assertEquals(0, Date::getDateDifference(new DateTime('yesterday'), new DateTime('midnight'), Date::DATE_DIFFERENCE_UNIT_HOURS)); self::assertEquals(0, Date::getDateDifference(new DateTime('yesterday'), new DateTime('midnight'), Date::DATE_DIFFERENCE_UNIT_HOURS));
self::assertEquals(0, Date::getDateDifference(new DateTime('yesterday'), new DateTime('midnight'), Date::DATE_DIFFERENCE_UNIT_MINUTES));
} }
public function testGetDateDifferenceOneDayTwoHours() public function testGetDateDifferenceOneDayTwoHours()
@@ -320,6 +331,12 @@ class DateTest extends BaseTestCase
self::assertEquals(0, Date::getDateDifference($dateStart, $dateEnd, Date::DATE_DIFFERENCE_UNIT_YEARS)); self::assertEquals(0, Date::getDateDifference($dateStart, $dateEnd, Date::DATE_DIFFERENCE_UNIT_YEARS));
self::assertEquals(0, Date::getDateDifference(new DateTime($dateStart), new DateTime($dateEnd), Date::DATE_DIFFERENCE_UNIT_YEARS)); self::assertEquals(0, Date::getDateDifference(new DateTime($dateStart), new DateTime($dateEnd), Date::DATE_DIFFERENCE_UNIT_YEARS));
self::assertEquals(0, Date::getDateDifference($dateStart, $dateEnd, Date::DATE_DIFFERENCE_UNIT_MONTHS));
self::assertEquals(0, Date::getDateDifference(new DateTime($dateStart), new DateTime($dateEnd), Date::DATE_DIFFERENCE_UNIT_MONTHS));
self::assertEquals(1, Date::getDateDifference($dateStart, $dateEnd, Date::DATE_DIFFERENCE_UNIT_DAYS));
self::assertEquals(1, Date::getDateDifference(new DateTime($dateStart), new DateTime($dateEnd), Date::DATE_DIFFERENCE_UNIT_DAYS));
self::assertEquals(2, Date::getDateDifference($dateStart, $dateEnd, Date::DATE_DIFFERENCE_UNIT_HOURS)); self::assertEquals(2, Date::getDateDifference($dateStart, $dateEnd, Date::DATE_DIFFERENCE_UNIT_HOURS));
self::assertEquals(2, Date::getDateDifference(new DateTime($dateStart), new DateTime($dateEnd), Date::DATE_DIFFERENCE_UNIT_HOURS)); self::assertEquals(2, Date::getDateDifference(new DateTime($dateStart), new DateTime($dateEnd), Date::DATE_DIFFERENCE_UNIT_HOURS));
@@ -355,10 +372,141 @@ class DateTest extends BaseTestCase
self::assertEquals(41, Date::getDateDifference($dateStart, $dateEnd, Date::DATE_DIFFERENCE_UNIT_DAYS)); self::assertEquals(41, Date::getDateDifference($dateStart, $dateEnd, Date::DATE_DIFFERENCE_UNIT_DAYS));
self::assertEquals(41, Date::getDateDifference(new DateTime($dateStart), new DateTime($dateEnd), Date::DATE_DIFFERENCE_UNIT_DAYS)); self::assertEquals(41, Date::getDateDifference(new DateTime($dateStart), new DateTime($dateEnd), Date::DATE_DIFFERENCE_UNIT_DAYS));
self::assertEquals(4, Date::getDateDifference($dateStart, $dateEnd, Date::DATE_DIFFERENCE_UNIT_HOURS));
self::assertEquals(4, Date::getDateDifference(new DateTime($dateStart), new DateTime($dateEnd), Date::DATE_DIFFERENCE_UNIT_HOURS));
self::assertEquals(30, Date::getDateDifference($dateStart, $dateEnd, Date::DATE_DIFFERENCE_UNIT_MINUTES)); self::assertEquals(30, Date::getDateDifference($dateStart, $dateEnd, Date::DATE_DIFFERENCE_UNIT_MINUTES));
self::assertEquals(30, Date::getDateDifference(new DateTime($dateStart), new DateTime($dateEnd), Date::DATE_DIFFERENCE_UNIT_MINUTES)); self::assertEquals(30, Date::getDateDifference(new DateTime($dateStart), new DateTime($dateEnd), Date::DATE_DIFFERENCE_UNIT_MINUTES));
} }
public function testGetDateDifferenceNewYear()
{
$dateStart = '2017-12-31 23:59';
$dateEnd = '2018-01-01 00:00';
$effect = [
Date::DATE_DIFFERENCE_UNIT_YEARS => 0,
Date::DATE_DIFFERENCE_UNIT_MONTHS => 0,
Date::DATE_DIFFERENCE_UNIT_DAYS => 0,
Date::DATE_DIFFERENCE_UNIT_HOURS => 0,
Date::DATE_DIFFERENCE_UNIT_MINUTES => 1,
];
self::assertEquals($effect, Date::getDateDifference($dateStart, $dateEnd));
self::assertEquals($effect, Date::getDateDifference(new DateTime($dateStart), new DateTime($dateEnd)));
self::assertEquals(0, Date::getDateDifference($dateStart, $dateEnd, Date::DATE_DIFFERENCE_UNIT_YEARS));
self::assertEquals(0, Date::getDateDifference(new DateTime($dateStart), new DateTime($dateEnd), Date::DATE_DIFFERENCE_UNIT_YEARS));
self::assertEquals(0, Date::getDateDifference($dateStart, $dateEnd, Date::DATE_DIFFERENCE_UNIT_MONTHS));
self::assertEquals(0, Date::getDateDifference(new DateTime($dateStart), new DateTime($dateEnd), Date::DATE_DIFFERENCE_UNIT_MONTHS));
self::assertEquals(0, Date::getDateDifference($dateStart, $dateEnd, Date::DATE_DIFFERENCE_UNIT_DAYS));
self::assertEquals(0, Date::getDateDifference(new DateTime($dateStart), new DateTime($dateEnd), Date::DATE_DIFFERENCE_UNIT_DAYS));
self::assertEquals(0, Date::getDateDifference($dateStart, $dateEnd, Date::DATE_DIFFERENCE_UNIT_HOURS));
self::assertEquals(0, Date::getDateDifference(new DateTime($dateStart), new DateTime($dateEnd), Date::DATE_DIFFERENCE_UNIT_HOURS));
self::assertEquals(1, Date::getDateDifference($dateStart, $dateEnd, Date::DATE_DIFFERENCE_UNIT_MINUTES));
self::assertEquals(1, Date::getDateDifference(new DateTime($dateStart), new DateTime($dateEnd), Date::DATE_DIFFERENCE_UNIT_MINUTES));
}
public function testGetDateDifferenceLessThan24Hours()
{
$dateStart = '2017-01-01 16:00';
$dateEnd = '2017-01-02 10:00';
$effect = [
Date::DATE_DIFFERENCE_UNIT_YEARS => 0,
Date::DATE_DIFFERENCE_UNIT_MONTHS => 0,
Date::DATE_DIFFERENCE_UNIT_DAYS => 0,
Date::DATE_DIFFERENCE_UNIT_HOURS => 18,
Date::DATE_DIFFERENCE_UNIT_MINUTES => 0,
];
self::assertEquals($effect, Date::getDateDifference($dateStart, $dateEnd));
self::assertEquals($effect, Date::getDateDifference(new DateTime($dateStart), new DateTime($dateEnd)));
self::assertEquals(0, Date::getDateDifference($dateStart, $dateEnd, Date::DATE_DIFFERENCE_UNIT_YEARS));
self::assertEquals(0, Date::getDateDifference(new DateTime($dateStart), new DateTime($dateEnd), Date::DATE_DIFFERENCE_UNIT_YEARS));
self::assertEquals(0, Date::getDateDifference($dateStart, $dateEnd, Date::DATE_DIFFERENCE_UNIT_MONTHS));
self::assertEquals(0, Date::getDateDifference(new DateTime($dateStart), new DateTime($dateEnd), Date::DATE_DIFFERENCE_UNIT_MONTHS));
self::assertEquals(0, Date::getDateDifference($dateStart, $dateEnd, Date::DATE_DIFFERENCE_UNIT_DAYS));
self::assertEquals(0, Date::getDateDifference(new DateTime($dateStart), new DateTime($dateEnd), Date::DATE_DIFFERENCE_UNIT_DAYS));
self::assertEquals(18, Date::getDateDifference($dateStart, $dateEnd, Date::DATE_DIFFERENCE_UNIT_HOURS));
self::assertEquals(18, Date::getDateDifference(new DateTime($dateStart), new DateTime($dateEnd), Date::DATE_DIFFERENCE_UNIT_HOURS));
self::assertEquals(0, Date::getDateDifference($dateStart, $dateEnd, Date::DATE_DIFFERENCE_UNIT_MINUTES));
self::assertEquals(0, Date::getDateDifference(new DateTime($dateStart), new DateTime($dateEnd), Date::DATE_DIFFERENCE_UNIT_MINUTES));
}
public function testGetDateDifferenceEqual24Hours()
{
$dateStart = '2017-01-01 00:00';
$dateEnd = '2017-01-02 00:00';
$effect = [
Date::DATE_DIFFERENCE_UNIT_YEARS => 0,
Date::DATE_DIFFERENCE_UNIT_MONTHS => 0,
Date::DATE_DIFFERENCE_UNIT_DAYS => 1,
Date::DATE_DIFFERENCE_UNIT_HOURS => 0,
Date::DATE_DIFFERENCE_UNIT_MINUTES => 0,
];
self::assertEquals($effect, Date::getDateDifference($dateStart, $dateEnd));
self::assertEquals($effect, Date::getDateDifference(new DateTime($dateStart), new DateTime($dateEnd)));
self::assertEquals(0, Date::getDateDifference($dateStart, $dateEnd, Date::DATE_DIFFERENCE_UNIT_YEARS));
self::assertEquals(0, Date::getDateDifference(new DateTime($dateStart), new DateTime($dateEnd), Date::DATE_DIFFERENCE_UNIT_YEARS));
self::assertEquals(0, Date::getDateDifference($dateStart, $dateEnd, Date::DATE_DIFFERENCE_UNIT_MONTHS));
self::assertEquals(0, Date::getDateDifference(new DateTime($dateStart), new DateTime($dateEnd), Date::DATE_DIFFERENCE_UNIT_MONTHS));
self::assertEquals(1, Date::getDateDifference($dateStart, $dateEnd, Date::DATE_DIFFERENCE_UNIT_DAYS));
self::assertEquals(1, Date::getDateDifference(new DateTime($dateStart), new DateTime($dateEnd), Date::DATE_DIFFERENCE_UNIT_DAYS));
self::assertEquals(0, Date::getDateDifference($dateStart, $dateEnd, Date::DATE_DIFFERENCE_UNIT_HOURS));
self::assertEquals(0, Date::getDateDifference(new DateTime($dateStart), new DateTime($dateEnd), Date::DATE_DIFFERENCE_UNIT_HOURS));
self::assertEquals(0, Date::getDateDifference($dateStart, $dateEnd, Date::DATE_DIFFERENCE_UNIT_MINUTES));
self::assertEquals(0, Date::getDateDifference(new DateTime($dateStart), new DateTime($dateEnd), Date::DATE_DIFFERENCE_UNIT_MINUTES));
}
public function testGetDateDifferenceInvertedDates()
{
$dateStart = '2017-01-02 10:00';
$dateEnd = '2017-01-01 16:00';
$effect = [
Date::DATE_DIFFERENCE_UNIT_YEARS => 0,
Date::DATE_DIFFERENCE_UNIT_MONTHS => 0,
Date::DATE_DIFFERENCE_UNIT_DAYS => -1,
Date::DATE_DIFFERENCE_UNIT_HOURS => 6,
Date::DATE_DIFFERENCE_UNIT_MINUTES => 0,
];
self::assertEquals($effect, Date::getDateDifference($dateStart, $dateEnd));
self::assertEquals($effect, Date::getDateDifference(new DateTime($dateStart), new DateTime($dateEnd)));
self::assertEquals(0, Date::getDateDifference($dateStart, $dateEnd, Date::DATE_DIFFERENCE_UNIT_YEARS));
self::assertEquals(0, Date::getDateDifference(new DateTime($dateStart), new DateTime($dateEnd), Date::DATE_DIFFERENCE_UNIT_YEARS));
self::assertEquals(0, Date::getDateDifference($dateStart, $dateEnd, Date::DATE_DIFFERENCE_UNIT_MONTHS));
self::assertEquals(0, Date::getDateDifference(new DateTime($dateStart), new DateTime($dateEnd), Date::DATE_DIFFERENCE_UNIT_MONTHS));
self::assertEquals(-1, Date::getDateDifference($dateStart, $dateEnd, Date::DATE_DIFFERENCE_UNIT_DAYS));
self::assertEquals(-1, Date::getDateDifference(new DateTime($dateStart), new DateTime($dateEnd), Date::DATE_DIFFERENCE_UNIT_DAYS));
self::assertEquals(6, Date::getDateDifference($dateStart, $dateEnd, Date::DATE_DIFFERENCE_UNIT_HOURS));
self::assertEquals(6, Date::getDateDifference(new DateTime($dateStart), new DateTime($dateEnd), Date::DATE_DIFFERENCE_UNIT_HOURS));
self::assertEquals(0, Date::getDateDifference($dateStart, $dateEnd, Date::DATE_DIFFERENCE_UNIT_MINUTES));
self::assertEquals(0, Date::getDateDifference(new DateTime($dateStart), new DateTime($dateEnd), Date::DATE_DIFFERENCE_UNIT_MINUTES));
}
public function testGetDateDifferenceNoDifference() public function testGetDateDifferenceNoDifference()
{ {
/* /*
@@ -384,6 +532,12 @@ class DateTest extends BaseTestCase
self::assertEquals(0, Date::getDateDifference($dateStart, $dateEnd, Date::DATE_DIFFERENCE_UNIT_MONTHS)); self::assertEquals(0, Date::getDateDifference($dateStart, $dateEnd, Date::DATE_DIFFERENCE_UNIT_MONTHS));
self::assertEquals(0, Date::getDateDifference(new DateTime(), new DateTime(), Date::DATE_DIFFERENCE_UNIT_MONTHS)); self::assertEquals(0, Date::getDateDifference(new DateTime(), new DateTime(), Date::DATE_DIFFERENCE_UNIT_MONTHS));
self::assertEquals(0, Date::getDateDifference($dateStart, $dateEnd, Date::DATE_DIFFERENCE_UNIT_DAYS));
self::assertEquals(0, Date::getDateDifference(new DateTime(), new DateTime(), Date::DATE_DIFFERENCE_UNIT_DAYS));
self::assertEquals(0, Date::getDateDifference($dateStart, $dateEnd, Date::DATE_DIFFERENCE_UNIT_HOURS));
self::assertEquals(0, Date::getDateDifference(new DateTime(), new DateTime(), Date::DATE_DIFFERENCE_UNIT_HOURS));
self::assertEquals(0, Date::getDateDifference($dateStart, $dateEnd, Date::DATE_DIFFERENCE_UNIT_MINUTES)); self::assertEquals(0, Date::getDateDifference($dateStart, $dateEnd, Date::DATE_DIFFERENCE_UNIT_MINUTES));
self::assertEquals(0, Date::getDateDifference(new DateTime(), new DateTime(), Date::DATE_DIFFERENCE_UNIT_MINUTES)); self::assertEquals(0, Date::getDateDifference(new DateTime(), new DateTime(), Date::DATE_DIFFERENCE_UNIT_MINUTES));
} }

View File

@@ -156,33 +156,6 @@ class MiscellaneousTest extends BaseTestCase
self::assertFalse(Miscellaneous::isPhpModuleLoaded('xyz123')); self::assertFalse(Miscellaneous::isPhpModuleLoaded('xyz123'));
} }
public function testVariableDump()
{
$xdebugLoaded = Miscellaneous::isPhpModuleLoaded('xdebug');
$variable = 123;
$expected = "int(123)\n";
if ($xdebugLoaded) {
$libraryPath = realpath(sprintf('%s%s', __DIR__, '/../..'));
$filePath = sprintf('%s%s', $libraryPath, '/src/Utilities/Miscellaneous.php:');
/*
* Attention. I have to use "\d+" at the end of $filePath, because number of line may be different if new
* method / function will be created.
*/
$filePathQuoted = sprintf('%s\d+\:', preg_quote($filePath, '/'));
$expectedPattern = sprintf("/%s\n%s/", $filePathQuoted, preg_quote($expected, '/'));
$this->expectOutputRegex($expectedPattern);
} else {
$expected = sprintf('<pre>%s</pre>', $expected);
$this->expectOutputString($expected);
}
Miscellaneous::variableDump($variable);
}
/** /**
* @param mixed $string Empty value, e.g. "" * @param mixed $string Empty value, e.g. ""
* @dataProvider provideEmptyValue * @dataProvider provideEmptyValue

View File

@@ -82,8 +82,15 @@ class ReflectionTest extends BaseTestCase
* Class with namespace containing name of class (duplicated string) * Class with namespace containing name of class (duplicated string)
*/ */
if (class_exists('Symfony\Bundle\SecurityBundle\SecurityBundle')) { if (class_exists('Symfony\Bundle\SecurityBundle\SecurityBundle')) {
self::assertEquals('Symfony\Bundle\SecurityBundle\SecurityBundle', Reflection::getClassName('Symfony\Bundle\SecurityBundle\SecurityBundle')); self::assertEquals(
self::assertEquals('SecurityBundle', Reflection::getClassName('Symfony\Bundle\SecurityBundle\SecurityBundle', true)); '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) * Class with namespace containing name of class (duplicated string)
*/ */
if (class_exists('Symfony\Bundle\SecurityBundle\SecurityBundle')) { 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() public function testGetMethods()
{ {
self::assertEquals(1, count(Reflection::getMethods(B::class, true))); self::assertCount(1, Reflection::getMethods(B::class, true));
self::assertEquals(3, count(Reflection::getMethods(B::class))); self::assertCount(3, Reflection::getMethods(B::class));
self::assertEquals(2, count(Reflection::getMethods(A::class))); self::assertCount(2, Reflection::getMethods(A::class));
self::assertEquals(2, count(Reflection::getMethods(C::class, true))); self::assertCount(2, Reflection::getMethods(C::class, true));
self::assertEquals(5, count(Reflection::getMethods(C::class))); self::assertCount(5, Reflection::getMethods(C::class));
} }
/** /**
@@ -235,9 +245,20 @@ class ReflectionTest extends BaseTestCase
public function testGetPropertiesUsingFilter() public function testGetPropertiesUsingFilter()
{ {
self::assertCount(1, Reflection::getProperties(B::class, ReflectionProperty::IS_PROTECTED)); self::assertCount(
self::assertCount(0, Reflection::getProperties(B::class, ReflectionProperty::IS_PRIVATE)); 1,
self::assertCount(1, Reflection::getProperties(B::class, ReflectionProperty::IS_PRIVATE, true)); 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() public function testGetPropertiesWithParents()
@@ -484,9 +505,7 @@ class ReflectionTest extends BaseTestCase
public function testSetPropertyValueUsingNotExistingProperty($object, $property) public function testSetPropertyValueUsingNotExistingProperty($object, $property)
{ {
$this->setExpectedException(NotExistingPropertyException::class); $this->setExpectedException(NotExistingPropertyException::class);
Reflection::setPropertyValue($object, $property, 'test test test');
$object = new \stdClass();
Reflection::setPropertyValue($object, 'test', 'test test test');
} }
/** /**
@@ -506,6 +525,43 @@ class ReflectionTest extends BaseTestCase
static::assertSame($newValue, $value); 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 * Provides invalid class and trait
* *
@@ -588,4 +644,104 @@ class ReflectionTest extends BaseTestCase
'Smith', '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,
],
];
}
} }

View File

@@ -12,7 +12,6 @@ use Generator;
use Meritoo\Common\Exception\Regex\IncorrectColorHexLengthException; use Meritoo\Common\Exception\Regex\IncorrectColorHexLengthException;
use Meritoo\Common\Exception\Regex\InvalidColorHexValueException; use Meritoo\Common\Exception\Regex\InvalidColorHexValueException;
use Meritoo\Common\Test\Base\BaseTestCase; use Meritoo\Common\Test\Base\BaseTestCase;
use ReflectionException;
/** /**
* Test case of the useful regular expressions methods * Test case of the useful regular expressions methods
@@ -25,9 +24,6 @@ class RegexTest extends BaseTestCase
private $simpleText; private $simpleText;
private $camelCaseText; private $camelCaseText;
/**
* @throws ReflectionException
*/
public function testConstructor() public function testConstructor()
{ {
static::assertHasNoConstructor(Regex::class); static::assertHasNoConstructor(Regex::class);
@@ -553,10 +549,6 @@ class RegexTest extends BaseTestCase
/** /**
* @param mixed $nonScalarValue Non scalar value, e.g. [] or null * @param mixed $nonScalarValue Non scalar value, e.g. [] or null
*
* @throws IncorrectColorHexLengthException
* @throws InvalidColorHexValueException
*
* @dataProvider provideNonScalarValue * @dataProvider provideNonScalarValue
*/ */
public function testGetValidColorHexValueUsingNonScalarValue($nonScalarValue) public function testGetValidColorHexValueUsingNonScalarValue($nonScalarValue)
@@ -566,10 +558,6 @@ class RegexTest extends BaseTestCase
/** /**
* @param mixed $emptyValue Empty value, e.g. "" * @param mixed $emptyValue Empty value, e.g. ""
*
* @throws IncorrectColorHexLengthException
* @throws InvalidColorHexValueException
*
* @dataProvider provideColorEmptyValue * @dataProvider provideColorEmptyValue
*/ */
public function testGetValidColorHexValueUsingEmptyValueWithoutException($emptyValue) public function testGetValidColorHexValueUsingEmptyValueWithoutException($emptyValue)
@@ -579,10 +567,6 @@ class RegexTest extends BaseTestCase
/** /**
* @param mixed $emptyValue Empty value, e.g. "" * @param mixed $emptyValue Empty value, e.g. ""
*
* @throws IncorrectColorHexLengthException
* @throws InvalidColorHexValueException
*
* @dataProvider provideColorEmptyValue * @dataProvider provideColorEmptyValue
*/ */
public function testGetValidColorHexValueUsingEmptyValue($emptyValue) public function testGetValidColorHexValueUsingEmptyValue($emptyValue)
@@ -593,10 +577,6 @@ class RegexTest extends BaseTestCase
/** /**
* @param string $incorrectColor Incorrect value of color * @param string $incorrectColor Incorrect value of color
*
* @throws IncorrectColorHexLengthException
* @throws InvalidColorHexValueException
*
* @dataProvider provideColorIncorrectLength * @dataProvider provideColorIncorrectLength
*/ */
public function testGetValidColorHexValueUsingIncorrectValueWithoutException($incorrectColor) public function testGetValidColorHexValueUsingIncorrectValueWithoutException($incorrectColor)
@@ -606,10 +586,6 @@ class RegexTest extends BaseTestCase
/** /**
* @param string $incorrectColor Incorrect value of color * @param string $incorrectColor Incorrect value of color
*
* @throws IncorrectColorHexLengthException
* @throws InvalidColorHexValueException
*
* @dataProvider provideColorIncorrectLength * @dataProvider provideColorIncorrectLength
*/ */
public function testGetValidColorHexValueUsingIncorrectValue($incorrectColor) public function testGetValidColorHexValueUsingIncorrectValue($incorrectColor)
@@ -620,10 +596,6 @@ class RegexTest extends BaseTestCase
/** /**
* @param string $invalidColor Invalid value of color * @param string $invalidColor Invalid value of color
*
* @throws IncorrectColorHexLengthException
* @throws InvalidColorHexValueException
*
* @dataProvider provideColorInvalidValue * @dataProvider provideColorInvalidValue
*/ */
public function testGetValidColorHexValueUsingInvalidValueWithoutException($invalidColor) public function testGetValidColorHexValueUsingInvalidValueWithoutException($invalidColor)
@@ -633,10 +605,6 @@ class RegexTest extends BaseTestCase
/** /**
* @param string $invalidColor Invalid value of color * @param string $invalidColor Invalid value of color
*
* @throws IncorrectColorHexLengthException
* @throws InvalidColorHexValueException
*
* @dataProvider provideColorInvalidValue * @dataProvider provideColorInvalidValue
*/ */
public function testGetValidColorHexValueUsingInvalidValue($invalidColor) public function testGetValidColorHexValueUsingInvalidValue($invalidColor)
@@ -649,9 +617,6 @@ class RegexTest extends BaseTestCase
* @param string $color Color to verify * @param string $color Color to verify
* @param string $expected Expected value of color * @param string $expected Expected value of color
* *
* @throws IncorrectColorHexLengthException
* @throws InvalidColorHexValueException
*
* @dataProvider provideColor * @dataProvider provideColor
*/ */
public function testGetValidColorHexValue($color, $expected) public function testGetValidColorHexValue($color, $expected)
@@ -659,6 +624,17 @@ class RegexTest extends BaseTestCase
self::assertEquals($expected, Regex::getValidColorHexValue($color)); self::assertEquals($expected, Regex::getValidColorHexValue($color));
} }
/**
* @param string $value Value that should be transformed to slug
* @param string $expected Expected slug
*
* @dataProvider provideValueSlug
*/
public function testCreateSlug($value, $expected)
{
self::assertSame($expected, Regex::createSlug($value));
}
/** /**
* Provides name of bundle and information if it's valid name * Provides name of bundle and information if it's valid name
* *
@@ -834,12 +810,12 @@ class RegexTest extends BaseTestCase
]; ];
yield[ yield[
fread(fopen($file1Path, 'r'), 1), fread(fopen($file1Path, 'rb'), 1),
false, false,
]; ];
yield[ yield[
fread(fopen($file2Path, 'r'), 1), fread(fopen($file2Path, 'rb'), 1),
true, true,
]; ];
} }
@@ -1729,6 +1705,89 @@ class RegexTest extends BaseTestCase
]; ];
} }
/**
* Provide value to create slug
*
* @return Generator
*/
public function provideValueSlug()
{
yield[
[],
false,
];
yield[
null,
false,
];
yield[
'',
'',
];
yield[
1234,
'1234',
];
yield[
'1234',
'1234',
];
yield[
'1/2/3/4',
'1234',
];
yield[
'1 / 2 / 3 / 4',
'1-2-3-4',
];
yield[
'test',
'test',
];
yield[
'test test',
'test-test',
];
yield[
'lorem ipsum dolor sit',
'lorem-ipsum-dolor-sit',
];
yield[
'Lorem ipsum. Dolor sit 12.34 amet.',
'lorem-ipsum-dolor-sit-1234-amet',
];
yield[
'Was sind Löwen, Bären, Vögel und Käfer (für die Prüfung)?',
'was-sind-lowen-baren-vogel-und-kafer-fur-die-prufung',
];
yield[
'äöü (ÄÖÜ)',
'aou-aou',
];
yield[
'Półka dębowa. Kolor: żółędziowy. Wymiary: 80 x 30 cm.',
'polka-debowa-kolor-zoledziowy-wymiary-80-x-30-cm',
];
yield[
'ąęółńśżźć (ĄĘÓŁŃŚŻŹĆ)',
'aeolnszzc-aeolnszzc',
];
}
/** /**
* {@inheritdoc} * {@inheritdoc}
*/ */
@@ -1737,7 +1796,8 @@ class RegexTest extends BaseTestCase
parent::setUp(); parent::setUp();
$this->simpleText = 'lorem ipsum dolor sit'; $this->simpleText = 'lorem ipsum dolor sit';
$this->camelCaseText = str_replace(' ', '', lcfirst(ucwords($this->simpleText))); // 'loremIpsumDolorSit' $simpleUppercase = ucwords($this->simpleText);
$this->camelCaseText = str_replace(' ', '', lcfirst($simpleUppercase)); // 'loremIpsumDolorSit'
} }
/** /**
@@ -1746,8 +1806,6 @@ class RegexTest extends BaseTestCase
protected function tearDown() protected function tearDown()
{ {
parent::tearDown(); parent::tearDown();
unset($this->simpleText, $this->camelCaseText);
unset($this->simpleText);
unset($this->camelCaseText);
} }
} }

View File

@@ -8,6 +8,10 @@
namespace Meritoo\Common\Test\Utilities; 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 Generator;
use Meritoo\Common\Test\Base\BaseTestCase; use Meritoo\Common\Test\Base\BaseTestCase;
use Meritoo\Common\Test\Utilities\Repository\Sortable; 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 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 * @param int $expected Extreme position (max or min) of given items
* *
* @dataProvider provideArraysWithoutExtremePositionToGetExtremePosition * @dataProvider provideArraysWithoutExtremePositionToGetExtremePosition
@@ -170,12 +174,122 @@ class RepositoryTest extends BaseTestCase
static::assertEquals($expected, Repository::getExtremePosition($items, $max)); 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, true,
1, 2,
]; ];
yield[ yield[
@@ -596,7 +710,125 @@ class RepositoryTest extends BaseTestCase
[], [],
], ],
false, 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',
]; ];
} }
} }

View File

@@ -0,0 +1,105 @@
<?php
/**
* (c) Meritoo.pl, http://www.meritoo.pl
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Meritoo\Common\Test\ValueObject;
use Meritoo\Common\Test\Base\BaseTestCase;
use Meritoo\Common\Type\OopVisibilityType;
use Meritoo\Common\ValueObject\Address;
/**
* Test case for the address
*
* @author Meritoo <github@meritoo.pl>
* @copyright Meritoo <http://www.meritoo.pl>
*/
class AddressTest extends BaseTestCase
{
/**
* @var Address
*/
private $address;
/**
* @var Address
*/
private $addressWithoutFlat;
/**
* @var Address
*/
private $addressWithoutStreet;
public function testConstructor()
{
static::assertConstructorVisibilityAndArguments(
Address::class,
OopVisibilityType::IS_PUBLIC,
5,
4
);
}
public function testGetFlatNumber()
{
static::assertSame('200', $this->address->getFlatNumber());
static::assertSame('', $this->addressWithoutFlat->getFlatNumber());
static::assertSame('300', $this->addressWithoutStreet->getFlatNumber());
}
public function testGetBuildingNumber()
{
static::assertSame('10', $this->address->getBuildingNumber());
static::assertSame('22', $this->addressWithoutFlat->getBuildingNumber());
static::assertSame('1', $this->addressWithoutStreet->getBuildingNumber());
}
public function testGetStreet()
{
static::assertSame('4th Avenue', $this->address->getStreet());
static::assertSame('Green Street', $this->addressWithoutFlat->getStreet());
static::assertSame('', $this->addressWithoutStreet->getStreet());
}
public function testGetFullStreet()
{
static::assertSame('4th Avenue 10/200', $this->address->getFullStreet());
static::assertSame('Green Street 22', $this->addressWithoutFlat->getFullStreet());
static::assertSame('', $this->addressWithoutStreet->getFullStreet());
}
public function testGetCity()
{
static::assertSame('New York', $this->address->getCity());
static::assertSame('San Francisco', $this->addressWithoutFlat->getCity());
static::assertSame('Saint Louis', $this->addressWithoutStreet->getCity());
}
public function testGetZipCode()
{
static::assertSame('00123', $this->address->getZipCode());
static::assertSame('00456', $this->addressWithoutFlat->getZipCode());
static::assertSame('00111', $this->addressWithoutStreet->getZipCode());
}
public function testToString()
{
static::assertSame('4th Avenue 10/200, 00123, New York', (string)$this->address);
static::assertSame('Green Street 22, 00456, San Francisco', (string)$this->addressWithoutFlat);
static::assertSame('00111, Saint Louis', (string)$this->addressWithoutStreet);
}
protected function setUp()
{
parent::setUp();
$this->address = new Address('New York', '00123', '4th Avenue', '10', '200');
$this->addressWithoutFlat = new Address('San Francisco', '00456', 'Green Street', '22');
$this->addressWithoutStreet = new Address('Saint Louis', '00111', '', '1', '300');
}
}

View File

@@ -0,0 +1,71 @@
<?php
/**
* (c) Meritoo.pl, http://www.meritoo.pl
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Meritoo\Common\Test\ValueObject;
use Meritoo\Common\Test\Base\BaseTestCase;
use Meritoo\Common\Type\OopVisibilityType;
use Meritoo\Common\ValueObject\BankAccount;
/**
* Test case for the bank account
*
* @author Meritoo <github@meritoo.pl>
* @copyright Meritoo <http://www.meritoo.pl>
*/
class BankAccountTest extends BaseTestCase
{
/**
* @var BankAccount
*/
private $emptyBankAccount;
/**
* @var BankAccount
*/
private $bankAccount;
public function testConstructor()
{
static::assertConstructorVisibilityAndArguments(
BankAccount::class,
OopVisibilityType::IS_PUBLIC,
2,
2
);
}
public function testGetAccountNumber()
{
self::assertSame('', $this->emptyBankAccount->getAccountNumber());
self::assertSame('1234567890', $this->bankAccount->getAccountNumber());
}
public function testGetBankName()
{
self::assertSame('', $this->emptyBankAccount->getBankName());
self::assertSame('Bank of America', $this->bankAccount->getBankName());
}
public function testToString()
{
static::assertSame('', (string)$this->emptyBankAccount);
static::assertSame('Bank of America, 1234567890', (string)$this->bankAccount);
}
/**
* {@inheritdoc}
*/
protected function setUp()
{
parent::setUp();
$this->emptyBankAccount = new BankAccount('', '');
$this->bankAccount = new BankAccount('Bank of America', '1234567890');
}
}

View File

@@ -0,0 +1,98 @@
<?php
/**
* (c) Meritoo.pl, http://www.meritoo.pl
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Meritoo\Common\Test\ValueObject;
use Meritoo\Common\Test\Base\BaseTestCase;
use Meritoo\Common\Type\OopVisibilityType;
use Meritoo\Common\ValueObject\Address;
use Meritoo\Common\ValueObject\BankAccount;
use Meritoo\Common\ValueObject\Company;
/**
* Test case for the company
*
* @author Meritoo <github@meritoo.pl>
* @copyright Meritoo <http://www.meritoo.pl>
*/
class CompanyTest extends BaseTestCase
{
/**
* @var Company
*/
private $company;
/**
* @var Company
*/
private $companyWithoutBankAccount;
public function testConstructor()
{
static::assertConstructorVisibilityAndArguments(
Company::class,
OopVisibilityType::IS_PUBLIC,
3,
2
);
}
public function testGetName()
{
static::assertSame('Test 1', $this->company->getName());
static::assertSame('Test 2', $this->companyWithoutBankAccount->getName());
}
public function testGetAddress()
{
static::assertEquals(
new Address('New York', '00123', '4th Avenue', '10', '200'),
$this->company->getAddress()
);
static::assertEquals(
new Address('San Francisco', '00456', 'Green Street', '22'),
$this->companyWithoutBankAccount->getAddress()
);
}
public function testGetBankAccount()
{
static::assertEquals(
new BankAccount('Bank 1', '12345'),
$this->company->getBankAccount()
);
static::assertNull($this->companyWithoutBankAccount->getBankAccount());
}
public function testToString()
{
static::assertSame('Test 1, 4th Avenue 10/200, 00123, New York, Bank 1, 12345', (string)$this->company);
static::assertSame('Test 2, Green Street 22, 00456, San Francisco', (string)$this->companyWithoutBankAccount);
}
/**
* {@inheritdoc}
*/
protected function setUp()
{
parent::setUp();
$this->company = new Company(
'Test 1',
new Address('New York', '00123', '4th Avenue', '10', '200'),
new BankAccount('Bank 1', '12345')
);
$this->companyWithoutBankAccount = new Company(
'Test 2',
new Address('San Francisco', '00456', 'Green Street', '22')
);
}
}

View File

@@ -6,7 +6,7 @@
* file that was distributed with this source code. * file that was distributed with this source code.
*/ */
namespace Meritoo\Test\Common\ValueObject; namespace Meritoo\Common\Test\ValueObject;
use Generator; use Generator;
use Meritoo\Common\Test\Base\BaseTestCase; use Meritoo\Common\Test\Base\BaseTestCase;