Skip to content

Commit

Permalink
PHPCheck initial implementation
Browse files Browse the repository at this point in the history
  • Loading branch information
datashaman committed Apr 15, 2019
1 parent 7c27f96 commit 826d992
Show file tree
Hide file tree
Showing 33 changed files with 2,277 additions and 10 deletions.
4 changes: 4 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,2 +1,6 @@
/composer.lock
/.phpcheck/
/php_errors.log
/.phpunit.result.cache
/vendor/
/.vscode/
111 changes: 111 additions & 0 deletions .php_cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
<?php

return PhpCsFixer\Config::create()
->setRiskyAllowed(true)
->setRules(
[
'@PSR2' => true,
'psr4' => true,
'align_multiline_comment' => true,
'array_syntax' => [
'syntax' => 'short',
],
'binary_operator_spaces' => [
'align_double_arrow' => false,
'align_equals' => false,
],
'binary_operator_spaces' => true,
'blank_line_after_opening_tag' => true,
'blank_line_before_statement' => [
'statements' => [
'return',
'throw',
],
],
'cast_spaces' => [
'space' => 'single',
],
'concat_space' => [
'spacing' => 'one',
],
'declare_equal_normalize' => [
'space' => 'single',
],
'method_argument_space' => [
'keep_multiple_spaces_after_comma' => false,
'on_multiline' => 'ensure_fully_multiline',
],
'method_chaining_indentation' => true,
'function_typehint_space' => true,
'general_phpdoc_annotation_remove' => [
'@author',
'@package',
],
'include' => true,
'indentation_type' => true,
'line_ending' => true,
'linebreak_after_opening_tag' => true,
'lowercase_cast' => true,
'method_separation' => true,
'modernize_types_casting' => true,
'native_function_casing' => true,
'no_blank_lines_after_class_opening' => true,
'no_blank_lines_after_phpdoc' => true,
'no_closing_tag' => true,
'no_empty_comment' => true,
'no_empty_phpdoc' => true,
'no_empty_statement' => true,
'no_extra_consecutive_blank_lines' => true,
'no_leading_import_slash' => true,
'no_mixed_echo_print' => [
'use' => 'echo',
],
'no_multiline_whitespace_before_semicolons' => true,
'no_php4_constructor' => true,
'no_short_bool_cast' => true,
'no_trailing_comma_in_singleline_array' => true,
'no_trailing_whitespace' => true,
'no_unused_imports' => true,
'no_whitespace_before_comma_in_array' => true,
'no_whitespace_in_blank_line' => true,
'object_operator_without_whitespace' => true,
'ordered_imports' => true,
'phpdoc_add_missing_param_annotation' => [
'only_untyped' => false,
],
'phpdoc_indent' => true,
'phpdoc_inline_tag' => true,
'phpdoc_no_alias_tag' => [
'type' => 'var',
],
'phpdoc_no_empty_return' => true,
'phpdoc_no_package' => true,
'phpdoc_no_useless_inheritdoc' => true,
'phpdoc_order' => true,
'phpdoc_scalar' => true,
'phpdoc_separation' => true,
'phpdoc_trim' => true,
'phpdoc_types' => true,
'phpdoc_var_without_name' => true,
'random_api_migration' => true,
'return_type_declaration' => true,
'short_scalar_cast' => true,
'single_blank_line_before_namespace' => true,
'single_line_comment_style' => [
'comment_types' => [
'asterisk',
'hash',
],
],
'single_quote' => true,
'space_after_semicolon' => true,
'standardize_not_equals' => true,
'switch_case_semicolon_to_colon' => true,
'ternary_operator_spaces' => true,
'ternary_to_null_coalescing' => true,
'trailing_comma_in_multiline_array' => true,
'trim_array_spaces' => true,
'unary_operator_spaces' => true,
'yoda_style' => false,
]
);
33 changes: 33 additions & 0 deletions .travis.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
language: php

sudo: false

php:
- 7.1
- 7.2
- 7.3

matrix:
fast_finish: true

env:
matrix:
- DEPENDENCIES="high"
- DEPENDENCIES="low"
global:
- DEFAULT_COMPOSER_FLAGS="--no-interaction --no-ansi --no-progress --no-suggest"

git:
depth: 3

install:
- if [[ "$DEPENDENCIES" = "high" ]]; then travis_retry composer update $DEFAULT_COMPOSER_FLAGS; fi
- if [[ "$DEPENDENCIES" = "low" ]]; then travis_retry composer update $DEFAULT_COMPOSER_FLAGS --prefer-lowest; fi

script:
- bin/phpcheck

cache:
directories:
- $HOME/.cache/composer/files
- $HOME/.composer/cache/files
153 changes: 153 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,153 @@
# phpcheck

![Development Status](https://img.shields.io/badge/status-alpha-red.svg)
[![Build Status](https://travis-ci.org/datashaman/phpcheck.svg?branch=master)](https://travis-ci.org/datashaman/phpcheck)

PHP implementation of Haskell's QuickCheck.

*NB* This is *ALPHA* status. Do not use it yet.

Table of Contents
=================

* [phpcheck](#phpcheck)
* [type declarations](#type-declarations)
* [annotations](#annotations)
* [generators](#generators)
* [examples](#examples)
* [command line arguments](#command-line-arguments)
* [storage of results](#storage-of-results)

## type declarations

`PHPCheck` will automatically generate arguments for check methods based on type declarations. For finer-grained control
over the arguments, use annotations on the method parameters.

## annotations

Annotate your check method parameters to control the arguments provided to the method.

Parameter tags (use them in the description of a parameter, usually the end):

* `{@gen name}` or `{@gen name:params}` where `name` is the name of the generator and `params` is a JSON encoded array of arguments passed to the generator.

Method tags:

* `@iterates` indicates that this check method handles its own iteration, and should be called once with no parameters.
* `@iterations` sets the number of iterations for this check method. The default is 100.

## generators

Below is the list of generators that are currently available:

* `ascii(Generator $sizes = null)`
* `booleans(int $chanceOfGettingTrue = 50)`
* `characters($minChar, $maxChar)`
* `choose(array $arr)`
* `floats(float $min, float $max, Generator $decimals = null)`
* `integers(int $min = PHP_INT_MIN, int $max = PHP_INT_MAX)`
* `intervals(array $include = [[PHP_INT_MIN, PHP_INT_MAX]], array $exclude=[])`
* `listOf(Generator $values = null, Generator $sizes = null)`
* `strings(Generator $sizes = null, Generator $characters = null)`

You have to nest the parameter tag to specify a generator argument. See (GenCheck.php)[checks/GenCheck.php] for examples.

## examples

There is an example check implemented in the _examples_ folder. To run it:

phpcheck examples

The [_Gen_ class checks](checks/GenCheck.php) for this package are a great illustration of the use of the generators.

## command line arguments

The `phpcheck` program accept a number of arguments and options:

Description:
Runs checks.

Usage:
phpcheck [options] [--] [<path>]

Arguments:
path File or folder with checks [default: "checks"]

Options:
--bootstrap[=BOOTSTRAP] A PHP script that is included before the checks run
-f, --filter[=FILTER] Filter the checks that will be run
-i, --iterations=ITERATIONS How many times each check will be run [default: 100]
-j, --log-junit[=LOG-JUNIT] Log check execution in JUnit XML format to file
-d, --no-defects[=NO-DEFECTS] Ignore previous defects [default: false]
-h, --help Display this help message
-q, --quiet Do not output any message
-V, --version Display this application version
--ansi Force ANSI output
--no-ansi Disable ANSI output
-n, --no-interaction Do not ask any interactive question
-v|vv|vvv, --verbose Increase the verbosity of messages: 1 for normal output, 2 for more verbose output and 3 for debug

The `--bootstrap` parameter can be included in a _phpcheck.xml_ or _phpcheck.xml.dist_ file. See [ours](phpcheck.xml.dist) for an example.

The `--filter` or `-f` parameter is a filename-style match as follows:

ClassName::
ClassName::MethodName
MethodName

where `ClassName` and `MethodName` can include patterns using `*` and `?` as you'd expect.

The console reporter outputs check results much like `PHPUnit`:

PHPCheck 0.1.0 by Marlin Forbes and contributors.

.............

13 / 13 (100%)

Time: 284 ms, Memory: 6.00 MB

OK (Checks: 13, Iterations: 120006, Failures: 0, Errors: 0)

Using `---verbose 3` or `-vvv` enables a list of the checks as they are run:

PHPCheck 0.1.0 by Marlin Forbes and contributors.

Check 'Datashaman\PHPCheck\Checks\GenCheck::checkCharacters' started
Check 'Datashaman\PHPCheck\Checks\GenCheck::checkCharacters' ended
Check 'Datashaman\PHPCheck\Checks\GenCheck::checkStrings' started
Check 'Datashaman\PHPCheck\Checks\GenCheck::checkStrings' ended
Check 'Datashaman\PHPCheck\Checks\GenCheck::checkAscii' started
Check 'Datashaman\PHPCheck\Checks\GenCheck::checkAscii' ended
Check 'Datashaman\PHPCheck\Checks\GenCheck::checkBooleans' started
Check 'Datashaman\PHPCheck\Checks\GenCheck::checkBooleans' ended
Check 'Datashaman\PHPCheck\Checks\GenCheck::checkBooleansWithPercentage' started
Check 'Datashaman\PHPCheck\Checks\GenCheck::checkBooleansWithPercentage' ended
Check 'Datashaman\PHPCheck\Checks\GenCheck::checkCharactersWithNumbers' started
Check 'Datashaman\PHPCheck\Checks\GenCheck::checkCharactersWithNumbers' ended
Check 'Datashaman\PHPCheck\Checks\GenCheck::checkCharactersWithStrings' started
Check 'Datashaman\PHPCheck\Checks\GenCheck::checkCharactersWithStrings' ended
Check 'Datashaman\PHPCheck\Checks\GenCheck::checkChoose' started
Check 'Datashaman\PHPCheck\Checks\GenCheck::checkChoose' ended
Check 'Datashaman\PHPCheck\Checks\GenCheck::checkIterations' started
Check 'Datashaman\PHPCheck\Checks\GenCheck::checkIterations' ended
Check 'Datashaman\PHPCheck\Checks\GenCheck::checkFloats' started
Check 'Datashaman\PHPCheck\Checks\GenCheck::checkFloats' ended
Check 'Datashaman\PHPCheck\Checks\GenCheck::checkFloatsWithDecimalGen' started
Check 'Datashaman\PHPCheck\Checks\GenCheck::checkFloatsWithDecimalGen' ended
Check 'Datashaman\PHPCheck\Checks\GenCheck::checkStringsWithMinMax' started
Check 'Datashaman\PHPCheck\Checks\GenCheck::checkStringsWithMinMax' ended
Check 'Datashaman\PHPCheck\Checks\GenCheck::checkListOfInts' started
Check 'Datashaman\PHPCheck\Checks\GenCheck::checkListOfInts' ended

Time: 305 ms, Memory: 6.00 MB

OK (Checks: 13, Iterations: 120006, Failures: 0, Errors: 0)

## storage of results

`PHPCheck` stores results of check execution in the `.phpcheck` folder of the project. You should add that to your `.gitignore` file.

When `PHPCheck` finds an error or failure, it will retry the defective arguments first before going onto regular iterations with new arguments.

If you wish to ignore the previous defects and run through new iterations only, use `--no-defects` or `-d`.
31 changes: 31 additions & 0 deletions bin/phpcheck
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
#!/usr/bin/env php
<?php

if (!ini_get('date.timezone')) {
ini_set('date.timezone', 'UTC');
}

$autoloaders = [
__DIR__ . '/../../autoload.php',
__DIR__ . '/../vendor/autoload.php',
__DIR__ . '/vendor/autoload.php'
];

foreach ($autoloaders as $file) {
if (file_exists($file)) {
require $file;

break;
}
}

unset($file);

use Datashaman\PHPCheck\CheckCommand;
use Symfony\Component\Console\Application;

$application = new Application('phpcheck', CheckCommand::VERSION);
$command = new CheckCommand();
$application->add($command);
$application->setDefaultCommand($command->getName(), true);
$application->run();
Loading

0 comments on commit 826d992

Please sign in to comment.