From 59efb4596a0788ee0337f13bccac19e5637935c6 Mon Sep 17 00:00:00 2001
From: Ilario Pierbattista
<987038+ilario-pierbattista@users.noreply.github.com>
Date: Sun, 5 Dec 2021 19:30:27 +0100
Subject: [PATCH] Add Psalm (#146)
---
.github/workflows/ci.yml | 12 +++++---
.github/workflows/static-analysis.yml | 4 ++-
.gitignore | 1 +
composer.json | 8 +++--
examples/AlwaysFailsTest.php | 5 ++--
examples/AssociativeArrayTest.php | 9 +++---
examples/BindTest.php | 13 ++++----
examples/BooleanTest.php | 5 ++--
examples/CharacterTest.php | 23 ++++++++-------
examples/ChooseTest.php | 7 +++--
examples/CollectTest.php | 19 ++++++------
examples/ConstantTest.php | 8 ++---
examples/DateTest.php | 13 ++++----
examples/DifferentElementsTest.php | 11 +++----
examples/DisableShrinkingTest.php | 5 ++--
examples/ElementsTest.php | 11 +++----
examples/ErrorTest.php | 5 ++--
examples/FloatTest.php | 7 +++--
examples/FrequencyTest.php | 13 ++++----
examples/GeneratorSamplesTest.php | 7 +++--
examples/IntegerTest.php | 15 +++++-----
examples/LimitToTest.php | 9 +++---
examples/LogFileTest.php | 13 ++++----
examples/MapTest.php | 19 ++++++------
examples/MinimumEvaluationsTest.php | 9 +++---
examples/NamesTest.php | 4 ++-
examples/OneOfTest.php | 9 +++---
examples/RandConfigurationTest.php | 13 ++++----
examples/ReadmeTest.php | 5 ++--
examples/RegexTest.php | 7 +++--
examples/SequenceTest.php | 9 +++---
examples/SetTest.php | 5 ++--
examples/ShrinkingTest.php | 7 +++--
examples/ShrinkingTimeLimitTest.php | 6 ++--
examples/SizeTest.php | 5 ++--
examples/SortTest.php | 5 ++--
examples/StringTest.php | 13 ++++----
examples/SubsetTest.php | 5 ++--
examples/SuchThatTest.php | 41 +++++++++++++-------------
examples/SumTest.php | 15 +++++-----
examples/TupleTest.php | 9 +++---
examples/VectorTest.php | 7 +++--
examples/WhenTest.php | 23 ++++++++-------
examples/generating_integers.php | 5 ++--
psalm-baseline.xml | 28 ++++++++++++++++++
psalm.xml | 19 ++++++++++++
src/Antecedent/PrintableCharacter.php | 11 +++++--
src/Antecedents.php | 18 +++++++++++
src/Generator/GeneratedValueSingle.php | 14 +++++++--
src/Listener/CollectFrequencies.php | 8 +++--
src/Listener/Log.php | 7 +++--
src/Listeners.php | 19 ++++++++++++
src/Shrinker.php | 2 +-
test/Generator/SubsetGeneratorTest.php | 15 +++++-----
test/SampleTest.php | 4 +--
55 files changed, 373 insertions(+), 216 deletions(-)
create mode 100644 psalm-baseline.xml
create mode 100644 psalm.xml
create mode 100644 src/Antecedents.php
create mode 100644 src/Listeners.php
diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index fb125c65..31c2bd54 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -19,9 +19,11 @@ jobs:
uses: shivammathur/setup-php@v2
with:
php-version: ${{ matrix.php }}
- - name: Remove phpstan from dev dependecies for older php versions
+ - name: Remove dev dependecies for older php versions
if: ${{ matrix.php < 7.1 }}
- run: composer remove --dev phpstan/phpstan --ignore-platform-reqs --no-update
+ run: |
+ composer remove --dev phpstan/phpstan --ignore-platform-reqs --no-update
+ composer remove --dev psalm/phar --ignore-platform-reqs --no-update
- name: Install dependencies
uses: ramsey/composer-install@v1
with:
@@ -48,9 +50,11 @@ jobs:
uses: shivammathur/setup-php@v2
with:
php-version: ${{ matrix.php }}
- - name: Remove phpstan from dev dependecies for older php versions
+ - name: Remove dev dependecies for older php versions
if: ${{ matrix.php < 7.1 }}
- run: composer remove --dev phpstan/phpstan --ignore-platform-reqs --no-update
+ run: |
+ composer remove --dev phpstan/phpstan --ignore-platform-reqs --no-update
+ composer remove --dev psalm/phar --ignore-platform-reqs --no-update
- name: Install dependencies
uses: ramsey/composer-install@v1
- name: Download phpunit phar
diff --git a/.github/workflows/static-analysis.yml b/.github/workflows/static-analysis.yml
index 4ac9fccd..2959357d 100644
--- a/.github/workflows/static-analysis.yml
+++ b/.github/workflows/static-analysis.yml
@@ -12,7 +12,9 @@ jobs:
- description: Code style
script: vendor/bin/php-cs-fixer fix --verbose --diff --dry-run
- description: PHPStan
- script: vendor/bin/phpstan analyse -c phpstan.neon
+ script: vendor/bin/phpstan
+ - description: Psalm
+ script: vendor/bin/psalm.phar
name: ${{ matrix.description }}
runs-on: ubuntu-latest
steps:
diff --git a/.gitignore b/.gitignore
index 5e528b6f..423a8762 100644
--- a/.gitignore
+++ b/.gitignore
@@ -4,3 +4,4 @@ composer.lock
docs/_build
.phpunit.result.cache
docker-compose.override.yml
+.psalm-cache/
diff --git a/composer.json b/composer.json
index c6961d0a..ceaf6132 100644
--- a/composer.json
+++ b/composer.json
@@ -24,7 +24,8 @@
"sebastian/comparator": ">=1.2.4",
"friendsofphp/php-cs-fixer": "^2.0",
"icomefromthenet/reverse-regex": "v0.0.6.3",
- "phpstan/phpstan": "^1.2"
+ "phpstan/phpstan": "^1.2",
+ "psalm/phar": "^4.13"
},
"suggest":
{
@@ -55,8 +56,9 @@
"composer update",
"vendor/bin/phpunit test"
],
- "phpstan": [
- "vendor/bin/phpstan analyse -c phpstan.neon"
+ "static": [
+ "vendor/bin/phpstan",
+ "vendor/bin/psalm.phar"
],
"phpstan-baseline": [
"vendor/bin/phpstan analyse -c phpstan.neon --generate-baseline"
diff --git a/examples/AlwaysFailsTest.php b/examples/AlwaysFailsTest.php
index c1f6aedd..a178bf5b 100644
--- a/examples/AlwaysFailsTest.php
+++ b/examples/AlwaysFailsTest.php
@@ -1,5 +1,6 @@
forAll(
- Generator\elements(['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j'])
+ Generators::elements(['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j'])
)
->then(function ($someChar) {
$this->fail("This test fails by design. '$someChar' was passed in");
diff --git a/examples/AssociativeArrayTest.php b/examples/AssociativeArrayTest.php
index 9d43425b..db04d338 100644
--- a/examples/AssociativeArrayTest.php
+++ b/examples/AssociativeArrayTest.php
@@ -1,5 +1,6 @@
forAll(
- Generator\associative([
- 'letter' => Generator\elements("A", "B", "C"),
- 'cipher' => Generator\choose(0, 9),
+ Generators::associative([
+ 'letter' => Generators::elements("A", "B", "C"),
+ 'cipher' => Generators::choose(0, 9),
])
)
->then(function ($array) {
diff --git a/examples/BindTest.php b/examples/BindTest.php
index 909c12ec..c690cb07 100644
--- a/examples/BindTest.php
+++ b/examples/BindTest.php
@@ -1,5 +1,6 @@
forAll(
- Generator\bind(
- Generator\vector(4, Generator\nat()),
+ Generators::bind(
+ Generators::vector(4, Generators::nat()),
function ($vector) {
- return Generator\tuple(
- Generator\elements($vector),
- Generator\constant($vector)
+ return Generators::tuple(
+ Generators::elements($vector),
+ Generators::constant($vector)
);
}
)
diff --git a/examples/BooleanTest.php b/examples/BooleanTest.php
index 989fb8ae..b13e288c 100644
--- a/examples/BooleanTest.php
+++ b/examples/BooleanTest.php
@@ -1,5 +1,6 @@
forAll(
- Generator\bool()
+ Generators::bool()
)
->then(function ($boolValue) {
$this->assertTrue(
diff --git a/examples/CharacterTest.php b/examples/CharacterTest.php
index 1390f5b4..0890aabf 100644
--- a/examples/CharacterTest.php
+++ b/examples/CharacterTest.php
@@ -1,6 +1,7 @@
forAll(
- Generator\char(['basic-latin'])
+ Generators::char(['basic-latin'])
)
->then(function ($char) {
$this->assertLenghtIs1($char);
@@ -19,9 +20,9 @@ public function testLengthOfAsciiCharactersInPhp()
public function testLengthOfPrintableAsciiCharacters()
{
$this->forAll(
- Generator\char(['basic-latin'])
+ Generators::char(['basic-latin'])
)
- ->when(Antecedent\printableCharacter())
+ ->when(Antecedents::printableCharacter())
->then(function ($char) {
$this->assertFalse(ord($char) < 32);
});
@@ -32,10 +33,10 @@ public function testMultiplePrintableCharacters()
$this
->minimumEvaluationRatio(0.1)
->forAll(
- Generator\char(['basic-latin']),
- Generator\char(['basic-latin'])
+ Generators::char(['basic-latin']),
+ Generators::char(['basic-latin'])
)
- ->when(Antecedent\printableCharacters())
+ ->when(Antecedents::printableCharacters())
->then(function ($first, $second) {
$this->assertFalse(ord($first) < 32);
$this->assertFalse(ord($second) < 32);
@@ -49,10 +50,10 @@ public function testMultiplePrintableCharactersFromAnnotation()
{
$this
->forAll(
- Generator\char(['basic-latin']),
- Generator\char(['basic-latin'])
+ Generators::char(['basic-latin']),
+ Generators::char(['basic-latin'])
)
- ->when(Antecedent\printableCharacters())
+ ->when(Antecedents::printableCharacters())
->then(function ($first, $second) {
$this->assertFalse(ord($first) < 32);
$this->assertFalse(ord($second) < 32);
diff --git a/examples/ChooseTest.php b/examples/ChooseTest.php
index 20283736..734e15be 100644
--- a/examples/ChooseTest.php
+++ b/examples/ChooseTest.php
@@ -1,5 +1,6 @@
forAll(
- Generator\choose(-1000, 430),
- Generator\choose(230, -30000)
+ Generators::choose(-1000, 430),
+ Generators::choose(230, -30000)
)
->then(function ($first, $second) {
$x = $first + $second;
diff --git a/examples/CollectTest.php b/examples/CollectTest.php
index 764152b3..aabce91e 100644
--- a/examples/CollectTest.php
+++ b/examples/CollectTest.php
@@ -1,7 +1,8 @@
forAll(Generator\neg())
- ->hook(Listener\collectFrequencies())
+ ->forAll(Generators::neg())
+ ->hook(Listeners::collectFrequencies())
->then(function ($x) {
$this->assertTrue($x < $x + 1);
});
@@ -21,10 +22,10 @@ public function testGeneratedDataCollectionOnMoreComplexDataStructures()
{
$this
->forAll(
- Generator\vector(2, Generator\int()),
- Generator\char()
+ Generators::vector(2, Generators::int()),
+ Generators::char()
)
- ->hook(Listener\collectFrequencies())
+ ->hook(Listeners::collectFrequencies())
->then(function ($vector) {
$this->assertEquals(2, count($vector));
});
@@ -34,10 +35,10 @@ public function testGeneratedDataCollectionWithCustomMapper()
{
$this
->forAll(
- Generator\seq(Generator\nat())
+ Generators::seq(Generators::nat())
)
->withMaxSize(10)
- ->hook(Listener\collectFrequencies(function ($array) {
+ ->hook(Listeners::collectFrequencies(function ($array) {
return count($array);
}))
->then(function ($array) {
diff --git a/examples/ConstantTest.php b/examples/ConstantTest.php
index 06aee749..855c6695 100644
--- a/examples/ConstantTest.php
+++ b/examples/ConstantTest.php
@@ -1,6 +1,6 @@
forAll(
- Generator\nat(),
- Generator\constant(2)
+ Generators::nat(),
+ Generators::constant(2)
)
->then(function ($number, $alwaysTwo) {
$this->assertTrue(($number * $alwaysTwo % 2) === 0);
@@ -22,7 +22,7 @@ public function testUseConstantGeneratorImplicitly()
{
$this
->forAll(
- Generator\nat(),
+ Generators::nat(),
2
)
->then(function ($number, $alwaysTwo) {
diff --git a/examples/DateTest.php b/examples/DateTest.php
index 1b663356..66f9d627 100644
--- a/examples/DateTest.php
+++ b/examples/DateTest.php
@@ -1,5 +1,6 @@
forAll(
- Generator\date("2014-01-01T00:00:00", "2014-12-31T23:59:59")
+ Generators::date("2014-01-01T00:00:00", "2014-12-31T23:59:59")
)
->then(function (DateTime $date) {
$this->assertEquals(
@@ -21,7 +22,7 @@ public function testYearOfADate()
public function testDefaultValuesForTheInterval()
{
$this->forAll(
- Generator\date()
+ Generators::date()
)
->then(function (DateTime $date) {
$this->assertGreaterThanOrEqual(
@@ -38,9 +39,9 @@ public function testDefaultValuesForTheInterval()
public function testFromDayOfYearFactoryMethodRespectsDistanceBetweenDays()
{
$this->forAll(
- Generator\choose(2000, 2020),
- Generator\choose(0, 364),
- Generator\choose(0, 364)
+ Generators::choose(2000, 2020),
+ Generators::choose(0, 364),
+ Generators::choose(0, 364)
)
->then(function ($year, $dayOfYear, $anotherDayOfYear) {
$day = fromZeroBasedDayOfYear($year, $dayOfYear);
diff --git a/examples/DifferentElementsTest.php b/examples/DifferentElementsTest.php
index 01d3bf06..2174e1f1 100644
--- a/examples/DifferentElementsTest.php
+++ b/examples/DifferentElementsTest.php
@@ -1,5 +1,6 @@
forAll(Generator\bind(
+ ->forAll(Generators::bind(
call_user_func_array('Eris\Generator\elements', $allTypes),
function ($first) use ($allTypes, $remove) {
- return Generator\tuple(
- Generator\constant($first),
- Generator\elements($remove($allTypes, $first))
+ return Generators::tuple(
+ Generators::constant($first),
+ Generators::elements($remove($allTypes, $first))
);
}
))
diff --git a/examples/DisableShrinkingTest.php b/examples/DisableShrinkingTest.php
index c82cf0e1..aa69ec35 100644
--- a/examples/DisableShrinkingTest.php
+++ b/examples/DisableShrinkingTest.php
@@ -1,5 +1,6 @@
calls = 0;
$this
->forAll(
- Generator\nat()
+ Generators::nat()
)
->disableShrinking()
->then(function ($number) {
diff --git a/examples/ElementsTest.php b/examples/ElementsTest.php
index f5560db3..5b28402b 100644
--- a/examples/ElementsTest.php
+++ b/examples/ElementsTest.php
@@ -1,5 +1,6 @@
forAll(
- Generator\elements(1, 2, 3)
+ Generators::elements(1, 2, 3)
)
->then(function ($number) {
$this->assertContains(
@@ -26,7 +27,7 @@ public function testElementsOnlyProducesElementsFromTheGivenArguments()
public function testElementsOnlyProducesElementsFromTheGivenArrayDomain()
{
$this->forAll(
- Generator\elements([1, 2, 3])
+ Generators::elements([1, 2, 3])
)
->then(function ($number) {
$this->assertContains(
@@ -40,9 +41,9 @@ public function testElementsOnlyProducesElementsFromTheGivenArrayDomain()
public function testVectorOfElementsGenerators()
{
$this->forAll(
- Generator\vector(
+ Generators::vector(
4,
- Generator\elements([2, 4, 6, 8, 10, 12])
+ Generators::elements([2, 4, 6, 8, 10, 12])
)
)
->then(function ($vector) {
diff --git a/examples/ErrorTest.php b/examples/ErrorTest.php
index 10fc35ab..be00b1e6 100644
--- a/examples/ErrorTest.php
+++ b/examples/ErrorTest.php
@@ -1,5 +1,6 @@
forAll(
- Generator\string()
+ Generators::string()
)
->then(function ($string) {
throw new RuntimeException("Something like a missing array index happened.");
diff --git a/examples/FloatTest.php b/examples/FloatTest.php
index 62dbedf8..92d54280 100644
--- a/examples/FloatTest.php
+++ b/examples/FloatTest.php
@@ -1,5 +1,6 @@
forAll(Generator\float())
+ $this->forAll(Generators::float())
->then(function ($number) {
$this->assertEquals(
0.0,
@@ -18,7 +19,7 @@ public function testAPropertyHoldingForAllNumbers()
public function testAPropertyHoldingOnlyForPositiveNumbers()
{
- $this->forAll(Generator\float())
+ $this->forAll(Generators::float())
->then(function ($number) {
$this->assertTrue(
$number >= 0,
diff --git a/examples/FrequencyTest.php b/examples/FrequencyTest.php
index e2988852..a895d463 100644
--- a/examples/FrequencyTest.php
+++ b/examples/FrequencyTest.php
@@ -1,5 +1,6 @@
forAll(
- Generator\frequency(
+ Generators::frequency(
[8, false],
[4, 0],
[4, '']
@@ -24,10 +25,10 @@ public function testAlwaysFails()
{
$this
->forAll(
- Generator\frequency(
- [8, Generator\choose(1, 100)],
- [4, Generator\choose(100, 200)],
- [4, Generator\choose(200, 300)]
+ Generators::frequency(
+ [8, Generators::choose(1, 100)],
+ [4, Generators::choose(100, 200)],
+ [4, Generators::choose(200, 300)]
)
)
->then(function ($element) {
diff --git a/examples/GeneratorSamplesTest.php b/examples/GeneratorSamplesTest.php
index e8ae5303..0fc97af0 100644
--- a/examples/GeneratorSamplesTest.php
+++ b/examples/GeneratorSamplesTest.php
@@ -1,5 +1,6 @@
Generator\int(),
- "Gen\\neg" => Generator\neg(),
+ "Gen\\neg" => Generators::neg(),
//"Gen\\nat" => Generator\nat(),
- "Gen\\pos" => Generator\pos(),
+ "Gen\\pos" => Generators::pos(),
/*
"Gen\\float" => Generator\float(),
"Gen\\choose(30, 9000) - no size used" => Generator\choose(30, 9000),
diff --git a/examples/IntegerTest.php b/examples/IntegerTest.php
index 4aef46be..f2184704 100644
--- a/examples/IntegerTest.php
+++ b/examples/IntegerTest.php
@@ -1,5 +1,6 @@
forAll(
- Generator\int(),
- Generator\int()
+ Generators::int(),
+ Generators::int()
)
->then(function ($first, $second) {
$x = $first + $second;
@@ -26,9 +27,9 @@ public function testSumIsCommutative()
public function testSumIsAssociative()
{
$this->forAll(
- Generator\int(),
- Generator\neg(),
- Generator\pos()
+ Generators::int(),
+ Generators::neg(),
+ Generators::pos()
)
->then(function ($first, $second, $third) {
$x = $first + ($second + $third);
@@ -44,7 +45,7 @@ public function testSumIsAssociative()
public function testByteData()
{
$this->forAll(
- Generator\byte()
+ Generators::byte()
)
->then(function ($byte) {
$this->assertTrue(
diff --git a/examples/LimitToTest.php b/examples/LimitToTest.php
index 9c0ed7e3..cfa3a27f 100644
--- a/examples/LimitToTest.php
+++ b/examples/LimitToTest.php
@@ -1,5 +1,6 @@
forAll(
- Generator\int()
+ Generators::int()
)
->then(function ($value) {
$this->assertInternalType('integer', $value);
@@ -41,7 +42,7 @@ public function testTimeIntervalToRunForCanBeConfiguredAndAVeryLowNumberOfIterat
->minimumEvaluationRatio(0)
->limitTo(new DateInterval('PT2S'))
->forAll(
- Generator\int()
+ Generators::int()
)
->then(function ($value) {
usleep(100 * 1000);
@@ -56,7 +57,7 @@ public function testTimeIntervalToRunForCanBeConfiguredAndAVeryLowNumberOfIterat
public function testTimeIntervalToRunForCanBeConfiguredAndAVeryLowNumberOfIterationsCanBeIgnoredFromAnnotation()
{
$this->forAll(
- Generator\int()
+ Generators::int()
)
->then(function ($value) {
usleep(100 * 1000);
diff --git a/examples/LogFileTest.php b/examples/LogFileTest.php
index fcca1490..98d79303 100644
--- a/examples/LogFileTest.php
+++ b/examples/LogFileTest.php
@@ -1,7 +1,8 @@
forAll(
- Generator\int()
+ Generators::int()
)
- ->hook(Listener\log(sys_get_temp_dir().'/eris-log-file-test.log'))
+ ->hook(Listeners::log(sys_get_temp_dir().'/eris-log-file-test.log'))
->then(function ($number) {
$this->assertInternalType('integer', $number);
});
@@ -23,9 +24,9 @@ public function testLogOfFailuresAndShrinking()
{
$this
->forAll(
- Generator\int()
+ Generators::int()
)
- ->hook(Listener\log(sys_get_temp_dir().'/eris-log-file-shrinking.log'))
+ ->hook(Listeners::log(sys_get_temp_dir().'/eris-log-file-shrinking.log'))
->then(function ($number) {
$this->assertLessThanOrEqual(42, $number);
});
diff --git a/examples/MapTest.php b/examples/MapTest.php
index e99a5168..eab1f1a5 100644
--- a/examples/MapTest.php
+++ b/examples/MapTest.php
@@ -1,5 +1,6 @@
forAll(
- Generator\vector(
+ Generators::vector(
3,
- Generator\map(
+ Generators::map(
function ($n) {
return $n * 2;
},
- Generator\nat()
+ Generators::nat()
)
)
)
@@ -31,11 +32,11 @@ function ($n) {
public function testShrinkingJustMappedValues()
{
$this->forAll(
- Generator\map(
+ Generators::map(
function ($n) {
return $n * 2;
},
- Generator\nat()
+ Generators::nat()
)
)
->then(function ($evenNumber) {
@@ -50,13 +51,13 @@ function ($n) {
public function testShrinkingMappedValuesInsideOtherGenerators()
{
$this->forAll(
- Generator\vector(
+ Generators::vector(
3,
- Generator\map(
+ Generators::map(
function ($n) {
return $n * 2;
},
- Generator\nat()
+ Generators::nat()
)
)
)
diff --git a/examples/MinimumEvaluationsTest.php b/examples/MinimumEvaluationsTest.php
index c3e09b87..69aca00f 100644
--- a/examples/MinimumEvaluationsTest.php
+++ b/examples/MinimumEvaluationsTest.php
@@ -1,5 +1,6 @@
forAll(
- Generator\choose(0, 100)
+ Generators::choose(0, 100)
)
->when(function ($n) {
return $n > 90;
@@ -24,7 +25,7 @@ public function testPassesBecauseOfTheArtificiallyLowMinimumEvaluationRatio()
$this
->minimumEvaluationRatio(0.01)
->forAll(
- Generator\choose(0, 100)
+ Generators::choose(0, 100)
)
->when(function ($n) {
return $n > 90;
@@ -41,7 +42,7 @@ public function testPassesBecauseOfTheArtificiallyLowMinimumEvaluationRatioFromA
{
$this
->forAll(
- Generator\choose(0, 100)
+ Generators::choose(0, 100)
)
->when(function ($n) {
return $n > 90;
diff --git a/examples/NamesTest.php b/examples/NamesTest.php
index c47aa19f..70614c50 100644
--- a/examples/NamesTest.php
+++ b/examples/NamesTest.php
@@ -1,5 +1,7 @@
forAll(
- Generator\names()
+ Generators::names()
)->then(function ($name) {
$this->assertInternalType('string', $name);
var_dump($name);
diff --git a/examples/OneOfTest.php b/examples/OneOfTest.php
index 25e80e11..c1729ac6 100644
--- a/examples/OneOfTest.php
+++ b/examples/OneOfTest.php
@@ -1,5 +1,6 @@
forAll(
- Generator\oneOf(
- Generator\pos(),
- Generator\neg()
+ Generators::oneOf(
+ Generators::pos(),
+ Generators::neg()
)
)
->then(function ($number) {
diff --git a/examples/RandConfigurationTest.php b/examples/RandConfigurationTest.php
index 9fefd8e1..e74c5bdc 100644
--- a/examples/RandConfigurationTest.php
+++ b/examples/RandConfigurationTest.php
@@ -1,5 +1,6 @@
withRand('rand')
->forAll(
- Generator\int()
+ Generators::int()
)
->withMaxSize(1000 * 1000* 1000)
->then($this->isInteger());
@@ -25,7 +26,7 @@ public function testUsingTheDefaultRandFunctionFromAnnotation()
{
$this
->forAll(
- Generator\int()
+ Generators::int()
)
->withMaxSize(1000 * 1000* 1000)
->then($this->isInteger());
@@ -36,7 +37,7 @@ public function testUsingTheDefaultMtRandFunction()
$this
->withRand('mt_rand')
->forAll(
- Generator\int()
+ Generators::int()
)
->then($this->isInteger());
}
@@ -49,7 +50,7 @@ public function testUsingTheDefaultMtRandFunctionFromAnnotation()
{
$this
->forAll(
- Generator\int()
+ Generators::int()
)
->then($this->isInteger());
}
@@ -63,7 +64,7 @@ public function testUsingThePurePhpMtRandFunction()
$this
->withRand(Random\purePhpMtRand())
->forAll(
- Generator\int()
+ Generators::int()
)
->then($this->isInteger());
}
diff --git a/examples/ReadmeTest.php b/examples/ReadmeTest.php
index 972bdad9..53b3e70b 100644
--- a/examples/ReadmeTest.php
+++ b/examples/ReadmeTest.php
@@ -1,5 +1,6 @@
forAll(
- Generator\choose(0, 1000)
+ Generators::choose(0, 1000)
)
->then(function ($number) {
$this->assertTrue(
diff --git a/examples/RegexTest.php b/examples/RegexTest.php
index 66489b71..82c45d54 100644
--- a/examples/RegexTest.php
+++ b/examples/RegexTest.php
@@ -1,17 +1,18 @@
forAll(
- Generator\regex("[a-z]{10}")
+ Generators::regex("[a-z]{10}")
)
->then(function ($string) {
$this->assertEquals(10, strlen($string));
diff --git a/examples/SequenceTest.php b/examples/SequenceTest.php
index ae4f72fa..ce84258c 100644
--- a/examples/SequenceTest.php
+++ b/examples/SequenceTest.php
@@ -1,5 +1,6 @@
forAll(
- Generator\seq(Generator\nat())
+ Generators::seq(Generators::nat())
)
->then(function ($array) {
$this->assertEquals(count($array), count(array_reverse($array)));
@@ -20,7 +21,7 @@ public function testArrayReverse()
{
$this
->forAll(
- Generator\seq(Generator\nat())
+ Generators::seq(Generators::nat())
)
->then(function ($array) {
$this->assertEquals($array, array_reverse(array_reverse($array)));
@@ -31,7 +32,7 @@ public function testArraySortingIsIdempotent()
{
$this
->forAll(
- Generator\seq(Generator\nat())
+ Generators::seq(Generators::nat())
)
->then(function ($array) {
sort($array);
diff --git a/examples/SetTest.php b/examples/SetTest.php
index 2b37a65b..fa2d0222 100644
--- a/examples/SetTest.php
+++ b/examples/SetTest.php
@@ -1,5 +1,6 @@
forAll(
- Generator\set(Generator\nat())
+ Generators::set(Generators::nat())
)
->then(function ($set) {
$this->assertInternalType('array', $set);
diff --git a/examples/ShrinkingTest.php b/examples/ShrinkingTest.php
index 5feaffcf..1f6e36e8 100644
--- a/examples/ShrinkingTest.php
+++ b/examples/ShrinkingTest.php
@@ -1,5 +1,6 @@
forAll(
- Generator\string()
+ Generators::string()
)
->then(function ($string) {
var_dump($string);
@@ -20,7 +21,7 @@ public function testShrinkingAString()
public function testShrinkingRespectsAntecedents()
{
$this->forAll(
- Generator\choose(0, 20)
+ Generators::choose(0, 20)
)
->when(function ($number) {
return $number > 10;
diff --git a/examples/ShrinkingTimeLimitTest.php b/examples/ShrinkingTimeLimitTest.php
index a435d7c4..2c9a47ba 100644
--- a/examples/ShrinkingTimeLimitTest.php
+++ b/examples/ShrinkingTimeLimitTest.php
@@ -1,5 +1,7 @@
shrinkingTimeLimit(2)
->forAll(
- Generator\string(),
- Generator\string()
+ Generators::string(),
+ Generators::string()
)
->then(function ($first, $second) {
$result = very_slow_concatenation($first, $second);
diff --git a/examples/SizeTest.php b/examples/SizeTest.php
index bf7ff977..9a79c721 100644
--- a/examples/SizeTest.php
+++ b/examples/SizeTest.php
@@ -1,5 +1,6 @@
forAll(
- Generator\int()
+ Generators::int()
)
->withMaxSize(1000 * 1000)
->then(function ($number) {
diff --git a/examples/SortTest.php b/examples/SortTest.php
index f8d3136e..f3bd2d62 100644
--- a/examples/SortTest.php
+++ b/examples/SortTest.php
@@ -1,5 +1,6 @@
forAll(
- Generator\seq(Generator\nat())
+ Generators::seq(Generators::nat())
)
->then(function ($array) {
sort($array);
diff --git a/examples/StringTest.php b/examples/StringTest.php
index c2fafc43..27cab426 100644
--- a/examples/StringTest.php
+++ b/examples/StringTest.php
@@ -1,6 +1,7 @@
forAll(
- Generator\string()
+ Generators::string()
)
->then(function ($string) {
$this->assertEquals(
@@ -33,10 +34,10 @@ public function testLengthPreservation()
{
$this
->forAll(
- Generator\string(),
- Generator\string()
+ Generators::string(),
+ Generators::string()
)
- ->hook(Listener\log(sys_get_temp_dir().'/eris-string-shrinking.log'))
+ ->hook(Listeners::log(sys_get_temp_dir().'/eris-string-shrinking.log'))
->then(function ($first, $second) {
$result = string_concatenation($first, $second);
$this->assertEquals(
diff --git a/examples/SubsetTest.php b/examples/SubsetTest.php
index 19f9a758..4111747b 100644
--- a/examples/SubsetTest.php
+++ b/examples/SubsetTest.php
@@ -1,5 +1,6 @@
forAll(
- Generator\subset([
+ Generators::subset([
2, 4, 6, 8, 10
])
)
diff --git a/examples/SuchThatTest.php b/examples/SuchThatTest.php
index 0523626c..9817a1cd 100644
--- a/examples/SuchThatTest.php
+++ b/examples/SuchThatTest.php
@@ -1,6 +1,7 @@
forAll(
- Generator\vector(
+ Generators::vector(
5,
- Generator\suchThat(
+ Generators::suchThat(
function ($n) {
return $n > 42;
},
- Generator\choose(0, 1000)
+ Generators::choose(0, 1000)
)
)
)
@@ -27,13 +28,13 @@ public function testFilterSyntax()
{
$this
->forAll(
- Generator\vector(
+ Generators::vector(
5,
- Generator\filter(
+ Generators::filter(
function ($n) {
return $n > 42;
},
- Generator\choose(0, 1000)
+ Generators::choose(0, 1000)
)
)
)
@@ -44,18 +45,18 @@ public function testSuchThatAcceptsPHPUnitConstraints()
{
$this
->forAll(
- Generator\vector(
+ Generators::vector(
5,
- Generator\suchThat(
+ Generators::suchThat(
$this->isType('integer'),
- Generator\oneOf(
- Generator\choose(0, 1000),
- Generator\string()
+ Generators::oneOf(
+ Generators::choose(0, 1000),
+ Generators::string()
)
)
)
)
- ->hook(Listener\log(sys_get_temp_dir().'/eris-such-that.log'))
+ ->hook(Listeners::log(sys_get_temp_dir().'/eris-such-that.log'))
->then($this->allNumbersAreBiggerThan(42));
}
@@ -64,11 +65,11 @@ public function testSuchThatShrinkingRespectsTheCondition()
{
$this
->forAll(
- Generator\suchThat(
+ Generators::suchThat(
function ($n) {
return $n > 42;
},
- Generator\choose(0, 1000)
+ Generators::choose(0, 1000)
)
)
->then($this->numberIsBiggerThan(100));
@@ -78,11 +79,11 @@ public function testSuchThatShrinkingRespectsTheConditionButTriesToSkipOverTheNo
{
$this
->forAll(
- Generator\suchThat(
+ Generators::suchThat(
function ($n) {
return $n <> 42;
},
- Generator\choose(0, 1000)
+ Generators::choose(0, 1000)
)
)
->then($this->numberIsBiggerThan(100));
@@ -92,11 +93,11 @@ public function testSuchThatAvoidingTheEmptyListDoesNotGetStuckOnASmallGenerator
{
$this
->forAll(
- Generator\suchThat(
+ Generators::suchThat(
function (array $ints) {
return count($ints) > 0;
},
- Generator\seq(Generator\int())
+ Generators::seq(Generators::int())
)
)
->then(function (array $ints) use (&$i) {
diff --git a/examples/SumTest.php b/examples/SumTest.php
index 6b5afb2c..d321490a 100644
--- a/examples/SumTest.php
+++ b/examples/SumTest.php
@@ -1,5 +1,6 @@
forAll(
- Generator\nat(1000)
+ Generators::nat(1000)
)
->then(function ($number) {
$this->assertEquals(
@@ -30,7 +31,7 @@ public function testRightIdentityElement()
public function testLeftIdentityElement()
{
$this->forAll(
- Generator\nat(1000)
+ Generators::nat(1000)
)
->then(function ($number) {
$this->assertEquals(
@@ -44,8 +45,8 @@ public function testLeftIdentityElement()
public function testEqualToReferencePhpImplementation()
{
$this->forAll(
- Generator\nat(1000),
- Generator\nat(1000)
+ Generators::nat(1000),
+ Generators::nat(1000)
)
->then(function ($first, $second) {
$this->assertEquals(
@@ -59,8 +60,8 @@ public function testEqualToReferencePhpImplementation()
public function testPropertyNeverSatisfied()
{
$this->forAll(
- Generator\nat(1000),
- Generator\nat(1000)
+ Generators::nat(1000),
+ Generators::nat(1000)
)
->then(function ($first, $second) {
$this->assertEquals(
diff --git a/examples/TupleTest.php b/examples/TupleTest.php
index 8c6a00a2..3822ddc7 100644
--- a/examples/TupleTest.php
+++ b/examples/TupleTest.php
@@ -1,5 +1,6 @@
forAll(
- Generator\tuple(
- Generator\elements("A", "B", "C"),
- Generator\choose(0, 9)
+ Generators::tuple(
+ Generators::elements("A", "B", "C"),
+ Generators::choose(0, 9)
)
)
->then(function ($tuple) {
diff --git a/examples/VectorTest.php b/examples/VectorTest.php
index 7300b634..61dcd472 100644
--- a/examples/VectorTest.php
+++ b/examples/VectorTest.php
@@ -1,5 +1,6 @@
forAll(
- Generator\vector(10, Generator\nat(1000)),
- Generator\vector(10, Generator\nat(1000))
+ Generators::vector(10, Generators::nat(1000)),
+ Generators::vector(10, Generators::nat(1000))
)
->then(function ($first, $second) {
$concatenated = array_merge($first, $second);
diff --git a/examples/WhenTest.php b/examples/WhenTest.php
index ee94d1b5..8ae68bc1 100644
--- a/examples/WhenTest.php
+++ b/examples/WhenTest.php
@@ -1,5 +1,6 @@
forAll(
- Generator\choose(0, 1000)
+ Generators::choose(0, 1000)
)
->when(function ($n) {
return $n > 42;
@@ -24,8 +25,8 @@ public function testWhenWithAnAnonymousFunctionWithGherkinSyntax()
public function testWhenWithAnAnonymousFunctionForMultipleArguments()
{
$this->forAll(
- Generator\choose(0, 1000),
- Generator\choose(0, 1000)
+ Generators::choose(0, 1000),
+ Generators::choose(0, 1000)
)
->when(function ($first, $second) {
return $first > 42 && $second > 23;
@@ -41,7 +42,7 @@ public function testWhenWithAnAnonymousFunctionForMultipleArguments()
public function testWhenWithOnePHPUnitConstraint()
{
$this->forAll(
- Generator\choose(0, 1000)
+ Generators::choose(0, 1000)
)
->when($this->greaterThan(42))
->then(function ($number) {
@@ -55,8 +56,8 @@ public function testWhenWithOnePHPUnitConstraint()
public function testWhenWithMultiplePHPUnitConstraints()
{
$this->forAll(
- Generator\choose(0, 1000),
- Generator\choose(0, 1000)
+ Generators::choose(0, 1000),
+ Generators::choose(0, 1000)
)
->when($this->greaterThan(42), $this->greaterThan(23))
->then(function ($first, $second) {
@@ -70,7 +71,7 @@ public function testWhenWithMultiplePHPUnitConstraints()
public function testMultipleWhenClausesWithGherkinSyntax()
{
$this->forAll(
- Generator\choose(0, 1000)
+ Generators::choose(0, 1000)
)
->when($this->greaterThan(42))
->and($this->lessThan(900))
@@ -85,7 +86,7 @@ public function testMultipleWhenClausesWithGherkinSyntax()
public function testWhenWhichSkipsTooManyValues()
{
$this->forAll(
- Generator\choose(0, 1000)
+ Generators::choose(0, 1000)
)
->when($this->greaterThan(800))
->then(function ($number) {
@@ -103,7 +104,7 @@ public function testWhenWhichSkipsTooManyValues()
public function testWhenFailingWillNaturallyHaveALowEvaluationRatioSoWeDontWantThatErrorToObscureTheTrueOne()
{
$this->forAll(
- Generator\choose(0, 1000)
+ Generators::choose(0, 1000)
)
->when($this->greaterThan(100))
->then(function ($number) {
@@ -117,7 +118,7 @@ public function testWhenFailingWillNaturallyHaveALowEvaluationRatioSoWeDontWantT
public function testSizeIncreasesEvenIfEvaluationsAreSkippedDueToAntecedentsNotBeingSatisfied()
{
$this->forAll(
- Generator\seq(Generator\elements(1, 2, 3))
+ Generators::seq(Generators::elements(1, 2, 3))
)
->when(function ($seq) {
return count($seq) > 0;
diff --git a/examples/generating_integers.php b/examples/generating_integers.php
index b155840e..4b425860 100644
--- a/examples/generating_integers.php
+++ b/examples/generating_integers.php
@@ -1,11 +1,12 @@
forAll(Generator\int())
+ ->forAll(Generators::int())
->then(function ($integer) {
echo var_export($integer, true) . PHP_EOL;
});
diff --git a/psalm-baseline.xml b/psalm-baseline.xml
new file mode 100644
index 00000000..ae34e755
--- /dev/null
+++ b/psalm-baseline.xml
@@ -0,0 +1,28 @@
+
+
+
+
+ PHPUnit_Framework_ExpectationFailedException
+
+
+
+
+ PHPUnit_Framework_Constraint
+
+
+ callable|PHPUnit_Framework_Constraint|Constraint
+ callable|PHPUnit_Framework_Constraint|Constraint
+
+
+
+
+ callable|PHPUnit_Framework_Constraint|Constraint
+ callable|PHPUnit_Framework_Constraint|Constraint
+
+
+
+
+ PHPUnit_Framework_Constraint
+
+
+
diff --git a/psalm.xml b/psalm.xml
new file mode 100644
index 00000000..21a07cc8
--- /dev/null
+++ b/psalm.xml
@@ -0,0 +1,19 @@
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/Antecedent/PrintableCharacter.php b/src/Antecedent/PrintableCharacter.php
index 1e3a12f0..860ad9e0 100644
--- a/src/Antecedent/PrintableCharacter.php
+++ b/src/Antecedent/PrintableCharacter.php
@@ -2,15 +2,22 @@
namespace Eris\Antecedent;
use Eris\Antecedent;
+use Eris\Antecedents;
+/**
+ * @see Antecedents::printableCharacter()
+ */
function printableCharacter()
{
- return new PrintableCharacter();
+ return Antecedents::printableCharacter();
}
+/**
+ * @see Antecedents::printableCharacters()
+ */
function printableCharacters()
{
- return new PrintableCharacter();
+ return Antecedents::printableCharacters();
}
class PrintableCharacter implements Antecedent
diff --git a/src/Antecedents.php b/src/Antecedents.php
new file mode 100644
index 00000000..c1db9666
--- /dev/null
+++ b/src/Antecedents.php
@@ -0,0 +1,18 @@
+ of its value.
* Immutable object, modifiers return a new GeneratedValueSingle instance.
+ *
+ * @template T
*/
final class GeneratedValueSingle implements GeneratedValue // TODO? interface ShrunkValue extends IteratorAggregate[, Countable]
{
+ /** @var T */
private $value;
private $input;
private $generatorName;
@@ -22,7 +25,9 @@ final class GeneratedValueSingle implements GeneratedValue // TODO? interface Sh
* A value and the input that was used to derive it.
* The input usually comes from another Generator.
*
- * @param T $value
+ * @template T
+ * @psalm-param T $value
+ * @param mixed $value
* @param GeneratedValueSingle|mixed $input
* @param string $generatorName 'tuple'
* @return GeneratedValueSingle
@@ -35,7 +40,9 @@ public static function fromValueAndInput($value, $input, $generatorName = null)
/**
* Input will be copied from value.
*
- * @param T $value
+ * @template T
+ * @psalm-param T $value
+ * @param mixed $value
* @param string $generatorName 'tuple'
* @return GeneratedValueSingle
*/
@@ -64,7 +71,8 @@ public function input()
}
/**
- * @return T
+ * @psalm-return T
+ * @return mixed
*/
public function unbox()
{
diff --git a/src/Listener/CollectFrequencies.php b/src/Listener/CollectFrequencies.php
index b76f177f..25b63e8b 100644
--- a/src/Listener/CollectFrequencies.php
+++ b/src/Listener/CollectFrequencies.php
@@ -2,12 +2,16 @@
namespace Eris\Listener;
use Eris\Listener;
-use InvalidArgumentException;
+use Eris\Listeners;
use Exception;
+use InvalidArgumentException;
+/**
+ * @see Listeners::collectFrequencies()
+ */
function collectFrequencies(callable $collectFunction = null)
{
- return new CollectFrequencies($collectFunction);
+ return Listeners::collectFrequencies($collectFunction);
}
class CollectFrequencies extends EmptyListener implements Listener
diff --git a/src/Listener/Log.php b/src/Listener/Log.php
index 1a4aadee..4d846b58 100644
--- a/src/Listener/Log.php
+++ b/src/Listener/Log.php
@@ -2,12 +2,15 @@
namespace Eris\Listener;
use Eris\Listener;
-use Eris\Listener\EmptyListener;
+use Eris\Listeners;
use Exception;
+/**
+ * @see Listeners::log()
+ */
function log($file)
{
- return new Log($file, 'time', getmypid());
+ return Listeners::log($file);
}
class Log extends EmptyListener implements Listener
diff --git a/src/Listeners.php b/src/Listeners.php
new file mode 100644
index 00000000..ca87a603
--- /dev/null
+++ b/src/Listeners.php
@@ -0,0 +1,19 @@
+> $subsetSizes */
$subsetSizes = [];
for ($size = 0; $size < $maxSize; $size++) {
$subsetSizes[] = count($this->generator->__invoke($size, $this->rand)->unbox());
@@ -43,7 +44,7 @@ public function testScalesGenerationSizeToTouchAllPossibleSubsets()
$subsetSizeFrequencies = array_count_values($subsetSizes);
// notice the full universe is very rarely generated
// hence its presence is not asserted here
- for ($subsetSize = 0; $subsetSize < count($this->universe); $subsetSize++) {
+ for ($subsetSize = 0, $subsetSizeMax = count($this->universe); $subsetSize < $subsetSizeMax; $subsetSize++) {
$this->assertGreaterThan(
0,
$subsetSizeFrequencies[$subsetSize],
@@ -75,17 +76,17 @@ public function testShrinksOnlyInSizeBecauseShrinkingElementsMayCauseCollisions(
public function testShrinkEmptySet()
{
$elements = $this->generator->__invoke($size = 0, $this->rand);
- $this->assertEquals(0, count($elements->unbox()));
- $this->assertEquals(0, count($this->generator->shrink($elements)->unbox()));
+ $this->assertCount(0, $elements->unbox());
+ $this->assertCount(0, $this->generator->shrink($elements)->unbox());
}
private function assertNoRepeatedElements($generated)
{
sort($generated);
- $this->assertTrue(
- array_unique($generated) === $generated,
- "There are repeated elements inside a generated value: "
- . var_export($generated, true)
+ $this->assertSame(
+ array_unique($generated),
+ $generated,
+ "There are repeated elements inside a generated value: " . var_export($generated, true)
);
}
}
diff --git a/test/SampleTest.php b/test/SampleTest.php
index dec26b7e..98abb63a 100644
--- a/test/SampleTest.php
+++ b/test/SampleTest.php
@@ -10,9 +10,9 @@ public function testWithGeneratorSize()
{
$times = 100;
$generatorSize = 100;
- $generator = Generator\suchThat(function ($n) {
+ $generator = Generators::suchThat(function ($n) {
return $n > 10;
- }, Generator\nat());
+ }, Generators::nat());
$sample = $this->sample($generator, $times, $generatorSize);
$this->assertNotEmpty(count($sample->collected()));
}