Skip to content

Commit

Permalink
Add missing tests for allowed-by-path callable params calls
Browse files Browse the repository at this point in the history
Follow-up to #281

Close #282
  • Loading branch information
spaze committed Jan 9, 2025
1 parent 3c11864 commit 5be5208
Show file tree
Hide file tree
Showing 5 changed files with 259 additions and 1 deletion.
2 changes: 1 addition & 1 deletion composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@
},
"scripts": {
"lint": "vendor/bin/parallel-lint --colors src/ tests/",
"lint-7.x": "vendor/bin/parallel-lint --colors src/ tests/ --exclude tests/src/TypesEverywhere.php --exclude tests/src/AttributesEverywhere.php --exclude tests/src/disallowed/functionCallsNamedParams.php --exclude tests/src/disallowed-allow/functionCallsNamedParams.php --exclude tests/src/disallowed/attributeUsages.php --exclude tests/src/disallowed-allow/attributeUsages.php --exclude tests/src/disallowed/constantDynamicUsages.php --exclude tests/src/disallowed-allow/constantDynamicUsages.php --exclude tests/src/Enums.php --exclude tests/src/disallowed/controlStructures.php --exclude tests/src/disallowed-allow/controlStructures.php --exclude tests/src/disallowed/firstClassCallable.php --exclude tests/src/disallowed-allow/firstClassCallable.php --exclude tests/src/disallowed/callableParameters.php",
"lint-7.x": "vendor/bin/parallel-lint --colors src/ tests/ --exclude tests/src/TypesEverywhere.php --exclude tests/src/AttributesEverywhere.php --exclude tests/src/disallowed/functionCallsNamedParams.php --exclude tests/src/disallowed-allow/functionCallsNamedParams.php --exclude tests/src/disallowed/attributeUsages.php --exclude tests/src/disallowed-allow/attributeUsages.php --exclude tests/src/disallowed/constantDynamicUsages.php --exclude tests/src/disallowed-allow/constantDynamicUsages.php --exclude tests/src/Enums.php --exclude tests/src/disallowed/controlStructures.php --exclude tests/src/disallowed-allow/controlStructures.php --exclude tests/src/disallowed/firstClassCallable.php --exclude tests/src/disallowed-allow/firstClassCallable.php --exclude tests/src/disallowed/callableParameters.php --exclude tests/src/disallowed-allow/callableParameters.php",
"lint-8.0": "vendor/bin/parallel-lint --colors src/ tests/ --exclude tests/src/TypesEverywhere.php --exclude tests/src/AttributesEverywhere.php --exclude tests/src/disallowed/constantDynamicUsages.php --exclude tests/src/disallowed-allow/constantDynamicUsages.php --exclude tests/src/Enums.php --exclude tests/src/disallowed/firstClassCallable.php --exclude tests/src/disallowed-allow/firstClassCallable.php",
"lint-8.1": "vendor/bin/parallel-lint --colors src/ tests/ --exclude tests/src/AttributesEverywhere.php --exclude tests/src/disallowed/constantDynamicUsages.php --exclude tests/src/disallowed-allow/constantDynamicUsages.php --exclude tests/src/disallowed/firstClassCallable.php --exclude tests/src/disallowed-allow/firstClassCallable.php",
"lint-8.2": "vendor/bin/parallel-lint --colors src/ tests/ --exclude tests/src/disallowed/constantDynamicUsages.php --exclude tests/src/disallowed-allow/constantDynamicUsages.php",
Expand Down
30 changes: 30 additions & 0 deletions tests/Calls/FunctionCallsCallableParametersTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -31,28 +31,56 @@ protected function getRule(): Rule
[
[
'function' => 'var_dump()',
'allowIn' => [
__DIR__ . '/../src/disallowed-allow/*.php',
__DIR__ . '/../src/*-allow/*.*',
],
],
],
[
[
'method' => 'Callbacks::call()',
'allowIn' => [
__DIR__ . '/../src/disallowed-allow/*.php',
__DIR__ . '/../src/*-allow/*.*',
],
],
[
'method' => 'CallbacksInterface::interfaceCall()',
'allowIn' => [
__DIR__ . '/../src/disallowed-allow/*.php',
__DIR__ . '/../src/*-allow/*.*',
],
],
[
'method' => 'CallbacksTrait::traitCall()',
'allowIn' => [
__DIR__ . '/../src/disallowed-allow/*.php',
__DIR__ . '/../src/*-allow/*.*',
],
],
],
[
[
'method' => 'Callbacks::staticCall()',
'allowIn' => [
__DIR__ . '/../src/disallowed-allow/*.php',
__DIR__ . '/../src/*-allow/*.*',
],
],
[
'method' => 'CallbacksInterface::interfaceStaticCall()',
'allowIn' => [
__DIR__ . '/../src/disallowed-allow/*.php',
__DIR__ . '/../src/*-allow/*.*',
],
],
[
'method' => 'CallbacksTrait::traitStaticCall()',
'allowIn' => [
__DIR__ . '/../src/disallowed-allow/*.php',
__DIR__ . '/../src/*-allow/*.*',
],
],
],
);
Expand Down Expand Up @@ -172,6 +200,8 @@ public function testRule(): void
158,
],
]);
// Based on the configuration above, no errors in this file:
$this->analyse([__DIR__ . '/../src/disallowed-allow/callableParameters.php'], []);
}


Expand Down
30 changes: 30 additions & 0 deletions tests/Calls/MethodCallsCallableParametersTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -31,28 +31,56 @@ protected function getRule(): Rule
[
[
'function' => 'var_dump()',
'allowIn' => [
__DIR__ . '/../src/disallowed-allow/*.php',
__DIR__ . '/../src/*-allow/*.*',
],
],
],
[
[
'method' => 'Callbacks::call()',
'allowIn' => [
__DIR__ . '/../src/disallowed-allow/*.php',
__DIR__ . '/../src/*-allow/*.*',
],
],
[
'method' => 'CallbacksInterface::interfaceCall()',
'allowIn' => [
__DIR__ . '/../src/disallowed-allow/*.php',
__DIR__ . '/../src/*-allow/*.*',
],
],
[
'method' => 'CallbacksTrait::traitCall()',
'allowIn' => [
__DIR__ . '/../src/disallowed-allow/*.php',
__DIR__ . '/../src/*-allow/*.*',
],
],
],
[
[
'method' => 'Callbacks::staticCall()',
'allowIn' => [
__DIR__ . '/../src/disallowed-allow/*.php',
__DIR__ . '/../src/*-allow/*.*',
],
],
[
'method' => 'CallbacksInterface::interfaceStaticCall()',
'allowIn' => [
__DIR__ . '/../src/disallowed-allow/*.php',
__DIR__ . '/../src/*-allow/*.*',
],
],
[
'method' => 'CallbacksTrait::traitStaticCall()',
'allowIn' => [
__DIR__ . '/../src/disallowed-allow/*.php',
__DIR__ . '/../src/*-allow/*.*',
],
],
],
);
Expand Down Expand Up @@ -216,6 +244,8 @@ public function testRule(): void
163,
],
]);
// Based on the configuration above, no errors in this file:
$this->analyse([__DIR__ . '/../src/disallowed-allow/callableParameters.php'], []);
}


Expand Down
30 changes: 30 additions & 0 deletions tests/Calls/StaticCallsCallableParametersTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -31,28 +31,56 @@ protected function getRule(): Rule
[
[
'function' => 'var_dump()',
'allowIn' => [
__DIR__ . '/../src/disallowed-allow/*.php',
__DIR__ . '/../src/*-allow/*.*',
],
],
],
[
[
'method' => 'Callbacks::call()',
'allowIn' => [
__DIR__ . '/../src/disallowed-allow/*.php',
__DIR__ . '/../src/*-allow/*.*',
],
],
[
'method' => 'CallbacksInterface::interfaceCall()',
'allowIn' => [
__DIR__ . '/../src/disallowed-allow/*.php',
__DIR__ . '/../src/*-allow/*.*',
],
],
[
'method' => 'CallbacksTrait::traitCall()',
'allowIn' => [
__DIR__ . '/../src/disallowed-allow/*.php',
__DIR__ . '/../src/*-allow/*.*',
],
],
],
[
[
'method' => 'Callbacks::staticCall()',
'allowIn' => [
__DIR__ . '/../src/disallowed-allow/*.php',
__DIR__ . '/../src/*-allow/*.*',
],
],
[
'method' => 'CallbacksInterface::interfaceStaticCall()',
'allowIn' => [
__DIR__ . '/../src/disallowed-allow/*.php',
__DIR__ . '/../src/*-allow/*.*',
],
],
[
'method' => 'CallbacksTrait::traitStaticCall()',
'allowIn' => [
__DIR__ . '/../src/disallowed-allow/*.php',
__DIR__ . '/../src/*-allow/*.*',
],
],
],
);
Expand Down Expand Up @@ -220,6 +248,8 @@ public function testRule(): void
168,
],
]);
// Based on the configuration above, no errors in this file:
$this->analyse([__DIR__ . '/../src/disallowed-allow/callableParameters.php'], []);
}


Expand Down
168 changes: 168 additions & 0 deletions tests/src/disallowed-allow/callableParameters.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,168 @@
<?php
declare(strict_types = 1);

function foo(callable $callback): void { $callback(); }

class Callbacks
{
public function call(): void { echo __METHOD__; }
public static function staticCall(): void { echo __METHOD__; }
}

class CallableParams
{
public function call(callable $callback, ?int $num = null): void {}
public static function staticCall(callable $callback, ?int $num = null): void {}
}

class Callbacks2 extends Callbacks {}
class CallableParams2 extends CallableParams {}

// allowed by path
$varDump = 'var_dump';
array_map('var_dump', []);
array_map($varDump, []);
array_map(callback: 'var_dump', array: []);
array_map(array: [], callback: 'var_dump');

foo('var_dump');
foo($varDump);

// not a callback param
strlen('var_dump');
strlen($varDump);

// allowed by path
$call = 'call';
$staticCall = 'staticCall';
$callbacks = new Callbacks();
$callbacks2 = new Callbacks2();
array_map([$callbacks, $call], []);
foo([$callbacks, 'call']);
foo([$callbacks, $call]);
foo([new Callbacks, $call]);

foo([$callbacks2, 'call']);
foo([$callbacks2, $call]);
foo([new Callbacks2, $call]);

foo(['Callbacks', 'staticCall']);
foo(['Callbacks', $staticCall]);
foo([Callbacks::class, 'staticCall']);
foo([Callbacks::class, $staticCall]);

foo(['Callbacks2', 'staticCall']);
foo(['Callbacks2', $staticCall]);
foo([Callbacks2::class, 'staticCall']);
foo([Callbacks2::class, $staticCall]);

$callableParams = new CallableParams();
$callableParams2 = new CallableParams2();

// allowed by path
$callableParams->call('var_dump');
$callableParams->call($varDump);
$callableParams2->call('var_dump');
$callableParams2->call($varDump);

// allowed by path
$callableParams->call([$callbacks, 'call']);
$callableParams->call([$callbacks, $call]);
$callableParams->call([new Callbacks, $call]);
$callableParams->call([$callbacks2, 'call']);
$callableParams->call([$callbacks2, $call]);
$callableParams->call([new Callbacks2, $call]);
$callableParams->call(['Callbacks', 'staticCall']);
$callableParams->call(['Callbacks', $staticCall]);
$callableParams->call([Callbacks::class, 'staticCall']);
$callableParams->call([Callbacks::class, $staticCall]);
$callableParams->call(['Callbacks2', 'staticCall']);
$callableParams->call(['Callbacks2', $staticCall]);
$callableParams->call([Callbacks2::class, 'staticCall']);
$callableParams->call([Callbacks2::class, $staticCall]);

$callableParams2->call([$callbacks, 'call']);
$callableParams2->call([$callbacks, $call]);
$callableParams2->call([new Callbacks, $call]);
$callableParams2->call([$callbacks2, 'call']);
$callableParams2->call([$callbacks2, $call]);
$callableParams2->call([new Callbacks2, $call]);
$callableParams2->call(['Callbacks', 'staticCall']);
$callableParams2->call(['Callbacks', $staticCall]);
$callableParams2->call([Callbacks::class, 'staticCall']);
$callableParams2->call([Callbacks::class, $staticCall]);
$callableParams2->call(['Callbacks2', 'staticCall']);
$callableParams2->call(['Callbacks2', $staticCall]);
$callableParams2->call([Callbacks2::class, 'staticCall']);
$callableParams2->call([Callbacks2::class, $staticCall]);

IntlChar::enumCharTypes($varDump);
CallableParams::staticCall('var_dump');
CallableParams::staticCall($varDump);
CallableParams::staticCall([$callbacks, 'call']);
CallableParams::staticCall([$callbacks, $call]);
CallableParams::staticCall([new Callbacks, $call]);
CallableParams::staticCall([$callbacks2, 'call']);
CallableParams::staticCall([$callbacks2, $call]);
CallableParams::staticCall([new Callbacks2, $call]);
CallableParams::staticCall(['Callbacks', 'staticCall']);
CallableParams::staticCall(['Callbacks', $staticCall]);
CallableParams::staticCall([Callbacks::class, 'staticCall']);
CallableParams::staticCall([Callbacks::class, $staticCall]);
CallableParams::staticCall(['Callbacks2', 'staticCall']);
CallableParams::staticCall(['Callbacks2', $staticCall]);
CallableParams::staticCall([Callbacks2::class, 'staticCall']);
CallableParams::staticCall([Callbacks2::class, $staticCall]);

CallableParams2::staticCall('var_dump');
CallableParams2::staticCall($varDump);
CallableParams2::staticCall([$callbacks, 'call']);
CallableParams2::staticCall([$callbacks, $call]);
CallableParams2::staticCall([new Callbacks, $call]);
CallableParams2::staticCall([$callbacks2, 'call']);
CallableParams2::staticCall([$callbacks2, $call]);
CallableParams2::staticCall([new Callbacks2, $call]);
CallableParams2::staticCall(['Callbacks', 'staticCall']);
CallableParams2::staticCall(['Callbacks', $staticCall]);
CallableParams2::staticCall([Callbacks::class, 'staticCall']);
CallableParams2::staticCall([Callbacks::class, $staticCall]);
CallableParams2::staticCall(['Callbacks2', 'staticCall']);
CallableParams2::staticCall(['Callbacks2', $staticCall]);
CallableParams2::staticCall([Callbacks2::class, 'staticCall']);
CallableParams2::staticCall([Callbacks2::class, $staticCall]);

interface CallbacksInterface
{
public function interfaceCall(): void;
public static function interfaceStaticCall(): void;
}

trait CallbacksTrait
{
public function traitCall(): void { echo __METHOD__; }
public static function traitStaticCall(): void { echo __METHOD__; }
}

class CallbacksPlusPlus implements CallbacksInterface
{
use CallbacksTrait;

public function interfaceCall(): void { echo __METHOD__; }
public static function interfaceStaticCall(): void { echo __METHOD__; }
}

$callbacksPlusPlus = new CallbacksPlusPlus();
foo([$callbacksPlusPlus, 'interfaceCall']);
foo([$callbacksPlusPlus, 'interfaceStaticCall']);
foo([$callbacksPlusPlus, 'traitCall']);
foo([CallbacksPlusPlus::class, 'traitStaticCall']);

$callableParams->call([$callbacksPlusPlus, 'interfaceCall']);
$callableParams->call([$callbacksPlusPlus, 'interfaceStaticCall']);
$callableParams->call([$callbacksPlusPlus, 'traitCall']);
$callableParams->call([CallbacksPlusPlus::class, 'traitStaticCall']);

CallableParams::staticCall([$callbacksPlusPlus, 'interfaceCall']);
CallableParams::staticCall([$callbacksPlusPlus, 'interfaceStaticCall']);
CallableParams::staticCall([$callbacksPlusPlus, 'traitCall']);
CallableParams::staticCall([CallbacksPlusPlus::class, 'traitStaticCall']);

0 comments on commit 5be5208

Please sign in to comment.