Repository: spaze/phpstan-disallowed-calls (php)

Issue:
Introduce `disallowIn` as inverse of `allowIn`
It would be great if I could enforce some rules that only apply in some directories. 

Currently, the only way to get that working is to construct a list of all options using wildcards, and then exclude the target from it. Not very ideal / scalable.

What do you think, would this be worth adding? Of course I can work on a PR to address it.

Pull request:
Can disallow calls, constants, classes, superglobals only in specified paths
With `allowExceptIn` or `disallowIn` (which is an alias only).

Close #95

Patch:
diff --git a/README.md b/README.md
index a1d3965..f7bbdc8 100644
--- a/README.md
+++ b/README.md
@@ -260,6 +260,18 @@ parameters:
 ```
 then `Logger::log()` will be allowed in `/home/foo/path/to/some/file-bar.php`.
 
+If you need to disallow a methods or a function call, a constant, a namespace, a class, or a superglobal usage only in certain paths, as an inverse of `allowIn`, you can use `allowExceptIn` (or the `disallowIn` alias):
+```neon
+parameters:
+    allowInRootDir: %rootDir%/../../..
+    disallowedMethodCalls:
+        -
+            method: 'PotentiallyDangerous\Logger::log()'
+            allowExceptIn:
+                - path/to/some/dir/*.php
+```
+This will disallow `PotentiallyDangerous\Logger::log()` calls in `%rootDir%/../../../path/to/some/dir/*.php`.
+
 To allow a previously disallowed method or function only when called from a different method or function in any file, use `allowInFunctions` (or `allowInMethods` alias):
 
 ```neon
diff --git a/phpstan.neon b/phpstan.neon
index 205e1f7..d49ed9a 100644
--- a/phpstan.neon
+++ b/phpstan.neon
@@ -3,7 +3,7 @@ parameters:
 		- src
 	level: max
 	typeAliases:
-		ForbiddenCallsConfig: 'array<array{function?:string, method?:string, message?:string, allowIn?:string[], allowInFunctions?:string[], allowInMethods?:string[], allowParamsInAllowed?:array<integer, integer|boolean|string>, allowParamsInAllowedAnyValue?:array<integer, integer>, allowParamsAnywhere?:array<integer, integer|boolean|string>, allowParamsAnywhereAnyValue?:array<integer, integer>, allowExceptParamsInAllowed?:array<integer, integer|boolean|string>, disallowParamsInAllowed?:array<integer, integer|boolean|string>, allowExceptParams?:array<integer, integer|boolean|string>, disallowParams?:array<integer, integer|boolean|string>, allowExceptCaseInsensitiveParams?:array<integer, integer|boolean|string>, disallowCaseInsensitiveParams?:array<integer, integer|boolean|string>, errorIdentifier?:string, errorTip?:string}>'
+		ForbiddenCallsConfig: 'array<array{function?:string, method?:string, message?:string, allowIn?:string[], allowExceptIn?:string[], disallowIn?:string[], allowInFunctions?:string[], allowInMethods?:string[], allowParamsInAllowed?:array<integer, integer|boolean|string>, allowParamsInAllowedAnyValue?:array<integer, integer>, allowParamsAnywhere?:array<integer, integer|boolean|string>, allowParamsAnywhereAnyValue?:array<integer, integer>, allowExceptParamsInAllowed?:array<integer, integer|boolean|string>, disallowParamsInAllowed?:array<integer, integer|boolean|string>, allowExceptParams?:array<integer, integer|boolean|string>, disallowParams?:array<integer, integer|boolean|string>, allowExceptCaseInsensitiveParams?:array<integer, integer|boolean|string>, disallowCaseInsensitiveParams?:array<integer, integer|boolean|string>, errorIdentifier?:string, errorTip?:string}>'
 
 includes:
 	- vendor/phpstan/phpstan/conf/bleedingEdge.neon
diff --git a/src/Disallowed.php b/src/Disallowed.php
index 7aa90ec..05d02ae 100644
--- a/src/Disallowed.php
+++ b/src/Disallowed.php
@@ -11,4 +11,10 @@ interface Disallowed
 	 */
 	public function getAllowIn(): array;
 
+
+	/**
+	 * @return string[]
+	 */
+	public function getAllowExceptIn(): array;
+
 }
diff --git a/src/DisallowedCall.php b/src/DisallowedCall.php
index 6669e9d..ef64ab4 100644
--- a/src/DisallowedCall.php
+++ b/src/DisallowedCall.php
@@ -17,6 +17,9 @@ class DisallowedCall implements Disallowed
 	/** @var string[] */
 	private $allowIn;
 
+	/** @var string[] */
+	private $allowExceptIn;
+
 	/** @var string[] */
 	private $allowInCalls;
 
@@ -40,11 +43,10 @@ class DisallowedCall implements Disallowed
 
 
 	/**
-	 * DisallowedCall constructor.
-	 *
 	 * @param string $call
 	 * @param string|null $message
 	 * @param string[] $allowIn
+	 * @param string[] $allowExceptIn
 	 * @param string[] $allowInCalls
 	 * @param array<int, DisallowedCallParam> $allowParamsInAllowed
 	 * @param array<int, DisallowedCallParam> $allowParamsAnywhere
@@ -57,6 +59,7 @@ class DisallowedCall implements Disallowed
 		string $call,
 		?string $message,
 		array $allowIn,
+		array $allowExceptIn,
 		array $allowInCalls,
 		array $allowParamsInAllowed,
 		array $allowParamsAnywhere,
@@ -68,6 +71,7 @@ class DisallowedCall implements Disallowed
 		$this->call = $call;
 		$this->message = $message;
 		$this->allowIn = $allowIn;
+		$this->allowExceptIn = $allowExceptIn;
 		$this->allowInCalls = $allowInCalls;
 		$this->allowParamsInAllowed = $allowParamsInAllowed;
 		$this->allowParamsAnywhere = $allowParamsAnywhere;
@@ -97,6 +101,13 @@ class DisallowedCall implements Disallowed
 	}
 
 
+	/** @inheritDoc */
+	public function getAllowExceptIn(): array
+	{
+		return $this->allowExceptIn;
+	}
+
+
 	/**
 	 * @return string[]
 	 */
diff --git a/src/DisallowedCallFactory.php b/src/DisallowedCallFactory.php
index 77fc100..79f305c 100644
--- a/src/DisallowedCallFactory.php
+++ b/src/DisallowedCallFactory.php
@@ -58,6 +58,7 @@ class DisallowedCallFactory
 					$this->normalizeCall($call),
 					$disallowed['message'] ?? null,
 					$disallowed['allowIn'] ?? [],
+					$disallowed['allowExceptIn'] ?? $disallowed['disallowIn'] ?? [],
 					$allowInCalls,
 					$allowParamsInAllowed,
 					$allowParamsAnywhere,
diff --git a/src/DisallowedConstant.php b/src/DisallowedConstant.php
index f1153ac..d646b0e 100644
--- a/src/DisallowedConstant.php
+++ b/src/DisallowedConstant.php
@@ -15,6 +15,9 @@ class DisallowedConstant implements Disallowed
 	/** @var string[] */
 	private $allowIn;
 
+	/** @var string[] */
+	private $allowExceptIn;
+
 	/** @var string|null */
 	private $errorIdentifier;
 
@@ -23,11 +26,10 @@ class DisallowedConstant implements Disallowed
 
 
 	/**
-	 * DisallowedCall constructor.
-	 *
 	 * @param string $constant
 	 * @param string|null $message
 	 * @param string[] $allowIn
+	 * @param string[] $allowExceptIn
 	 * @param string|null $errorIdentifier
 	 * @param string|null $errorTip
 	 */
@@ -35,12 +37,14 @@ class DisallowedConstant implements Disallowed
 		string $constant,
 		?string $message,
 		array $allowIn,
+		array $allowExceptIn,
 		?string $errorIdentifier,
 		?string $errorTip
 	) {
 		$this->constant = ltrim($constant, '\\');
 		$this->message = $message;
 		$this->allowIn = $allowIn;
+		$this->allowExceptIn = $allowExceptIn;
 		$this->errorIdentifier = $errorIdentifier;
 		$this->errorTip = $errorTip;
 	}
@@ -65,6 +69,13 @@ class DisallowedConstant implements Disallowed
 	}
 
 
+	/** @inheritDoc */
+	public function getAllowExceptIn(): array
+	{
+		return $this->allowExceptIn;
+	}
+
+
 	public function getErrorIdentifier(): ?string
 	{
 		return $this->errorIdentifier;
diff --git a/src/DisallowedConstantFactory.php b/src/DisallowedConstantFactory.php
index b17a18a..482b42a 100644
--- a/src/DisallowedConstantFactory.php
+++ b/src/DisallowedConstantFactory.php
@@ -9,7 +9,7 @@ class DisallowedConstantFactory
 {
 
 	/**
-	 * @param array<array{class?:string, constant?:string, message?:string, allowIn?:string[], errorIdentifier?:string, errorTip?:string}> $config
+	 * @param array<array{class?:string, constant?:string, message?:string, allowIn?:string[], allowExceptIn?:string[], disallowIn?:string[], errorIdentifier?:string, errorTip?:string}> $config
 	 * @return DisallowedConstant[]
 	 * @throws ShouldNotHappenException
 	 */
@@ -28,6 +28,7 @@ class DisallowedConstantFactory
 					$class ? "{$class}::{$constant}" : $constant,
 					$disallowed['message'] ?? null,
 					$disallowed['allowIn'] ?? [],
+					$disallowed['allowExceptIn'] ?? $disallowed['disallowIn'] ?? [],
 					$disallowed['errorIdentifier'] ?? null,
 					$disallowed['errorTip'] ?? null
 				);
diff --git a/src/DisallowedHelper.php b/src/DisallowedHelper.php
index c4e17a5..9437bab 100644
--- a/src/DisallowedHelper.php
+++ b/src/DisallowedHelper.php
@@ -51,6 +51,14 @@ class DisallowedHelper
 				return $this->hasAllowedParamsInAllowed($scope, $node, $disallowedCall);
 			}
 		}
+		if ($disallowedCall->getAllowExceptIn()) {
+			foreach ($disallowedCall->getAllowExceptIn() as $allowedExceptPath) {
+				if ($this->isAllowedFileHelper->matches($scope, $allowedExceptPath)) {
+					return false;
+				}
+			}
+			return true;
+		}
 		if ($disallowedCall->getAllowExceptParams()) {
 			return $this->hasAllowedParams($scope, $node, $disallowedCall->getAllowExceptParams(), false);
 		}
diff --git a/src/DisallowedNamespace.php b/src/DisallowedNamespace.php
index ce68177..c787284 100644
--- a/src/DisallowedNamespace.php
+++ b/src/DisallowedNamespace.php
@@ -15,6 +15,9 @@ class DisallowedNamespace implements Disallowed
 	/** @var string[] */
 	private $allowIn;
 
+	/** @var string[] */
+	private $allowExceptIn;
+
 	/** @var string|null */
 	private $errorIdentifier;
 
@@ -26,6 +29,7 @@ class DisallowedNamespace implements Disallowed
 	 * @param string $namespace
 	 * @param string|null $message
 	 * @param string[] $allowIn
+	 * @param string[] $allowExceptIn
 	 * @param string|null $errorIdentifier
 	 * @param string|null $errorTip
 	 */
@@ -33,12 +37,14 @@ class DisallowedNamespace implements Disallowed
 		string $namespace,
 		?string $message,
 		array $allowIn,
+		array $allowExceptIn,
 		?string $errorIdentifier,
 		?string $errorTip
 	) {
 		$this->namespace = ltrim($namespace, '\\');
 		$this->message = $message;
 		$this->allowIn = $allowIn;
+		$this->allowExceptIn = $allowExceptIn;
 		$this->errorIdentifier = $errorIdentifier;
 		$this->errorTip = $errorTip;
 	}
@@ -63,6 +69,13 @@ class DisallowedNamespace implements Disallowed
 	}
 
 
+	/** @inheritDoc */
+	public function getAllowExceptIn(): array
+	{
+		return $this->allowExceptIn;
+	}
+
+
 	public function getErrorIdentifier(): ?string
 	{
 		return $this->errorIdentifier;
diff --git a/src/DisallowedNamespaceFactory.php b/src/DisallowedNamespaceFactory.php
index 2b1bfd4..398d67b 100644
--- a/src/DisallowedNamespaceFactory.php
+++ b/src/DisallowedNamespaceFactory.php
@@ -9,7 +9,7 @@ class DisallowedNamespaceFactory
 {
 
 	/**
-	 * @param array<array{namespace?:string, class?:string, message?:string, allowIn?:string[], errorIdentifier?:string, errorTip?:string}> $config
+	 * @param array<array{namespace?:string, class?:string, message?:string, allowIn?:string[], allowExceptIn?:string[], disallowIn?:string[], errorIdentifier?:string, errorTip?:string}> $config
 	 * @return DisallowedNamespace[]
 	 */
 	public function createFromConfig(array $config): array
@@ -26,6 +26,7 @@ class DisallowedNamespaceFactory
 					$namespace,
 					$disallowed['message'] ?? null,
 					$disallowed['allowIn'] ?? [],
+					$disallowed['allowExceptIn'] ?? $disallowed['disallowIn'] ?? [],
 					$disallowed['errorIdentifier'] ?? null,
 					$disallowed['errorTip'] ?? null
 				);
diff --git a/src/DisallowedSuperglobalFactory.php b/src/DisallowedSuperglobalFactory.php
index 038d5eb..eaa4d00 100644
--- a/src/DisallowedSuperglobalFactory.php
+++ b/src/DisallowedSuperglobalFactory.php
@@ -25,7 +25,7 @@ class DisallowedSuperglobalFactory implements DisallowedVariableFactory
 
 
 	/**
-	 * @param array<array{superglobal?:string, message?:string, allowIn?:string[], errorIdentifier?:string, errorTip?:string}> $config
+	 * @param array<array{superglobal?:string, message?:string, allowIn?:string[], allowExceptIn?:string[], disallowIn?:string[], errorIdentifier?:string, errorTip?:string}> $config
 	 * @return DisallowedVariable[]
 	 * @throws ShouldNotHappenException
 	 */
@@ -46,6 +46,7 @@ class DisallowedSuperglobalFactory implements DisallowedVariableFactory
 					$superglobal,
 					$disallowed['message'] ?? null,
 					$disallowed['allowIn'] ?? [],
+					$disallowed['allowExceptIn'] ?? $disallowed['disallowIn'] ?? [],
 					$disallowed['errorIdentifier'] ?? null,
 					$disallowed['errorTip'] ?? null
 				);
diff --git a/src/DisallowedVariable.php b/src/DisallowedVariable.php
index 2c6123f..df6351c 100644
--- a/src/DisallowedVariable.php
+++ b/src/DisallowedVariable.php
@@ -15,6 +15,9 @@ class DisallowedVariable implements Disallowed
 	/** @var string[] */
 	private $allowIn;
 
+	/** @var string[] */
+	private $allowExceptIn;
+
 	/** @var string|null */
 	private $errorIdentifier;
 
@@ -26,6 +29,7 @@ class DisallowedVariable implements Disallowed
 	 * @param string $variable
 	 * @param string|null $message
 	 * @param string[] $allowIn
+	 * @param string[] $allowExceptIn
 	 * @param string|null $errorIdentifier
 	 * @param string|null $errorTip
 	 */
@@ -33,12 +37,14 @@ class DisallowedVariable implements Disallowed
 		string $variable,
 		?string $message,
 		array $allowIn,
+		array $allowExceptIn,
 		?string $errorIdentifier,
 		?string $errorTip
 	) {
 		$this->variable = $variable;
 		$this->message = $message;
 		$this->allowIn = $allowIn;
+		$this->allowExceptIn = $allowExceptIn;
 		$this->errorIdentifier = $errorIdentifier;
 		$this->errorTip = $errorTip;
 	}
@@ -63,6 +69,13 @@ class DisallowedVariable implements Disallowed
 	}
 
 
+	/** @inheritDoc */
+	public function getAllowExceptIn(): array
+	{
+		return $this->allowExceptIn;
+	}
+
+
 	public function getErrorIdentifier(): ?string
 	{
 		return $this->errorIdentifier;
diff --git a/src/DisallowedVariableFactory.php b/src/DisallowedVariableFactory.php
index 9fe8927..e35c5d9 100644
--- a/src/DisallowedVariableFactory.php
+++ b/src/DisallowedVariableFactory.php
@@ -7,7 +7,7 @@ interface DisallowedVariableFactory
 {
 
 	/**
-	 * @param array<array{variable?:string, message?:string, allowIn?:string[], errorIdentifier?:string}> $config
+	 * @param array<array{variable?:string, message?:string, allowIn?:string[], allowExceptIn?:string[], disallowIn?:string[], errorIdentifier?:string}> $config
 	 * @return DisallowedVariable[]
 	 */
 	public function getDisallowedVariables(array $config): array;
diff --git a/src/IsAllowedFileHelper.php b/src/IsAllowedFileHelper.php
index bd41a9c..dd1b891 100644
--- a/src/IsAllowedFileHelper.php
+++ b/src/IsAllowedFileHelper.php
@@ -56,6 +56,14 @@ class IsAllowedFileHelper
 				return true;
 			}
 		}
+		if ($disallowed->getAllowExceptIn()) {
+			foreach ($disallowed->getAllowExceptIn() as $allowedExceptPath) {
+				if ($this->matches($scope, $allowedExceptPath)) {
+					return false;
+				}
+			}
+			return true;
+		}
 		return false;
 	}
 


Test patch:
diff --git a/tests/Calls/MethodCallsTest.php b/tests/Calls/MethodCallsTest.php
index edf86a0..e78ec86 100644
--- a/tests/Calls/MethodCallsTest.php
+++ b/tests/Calls/MethodCallsTest.php
@@ -109,6 +109,14 @@ class MethodCallsTest extends RuleTestCase
 					],
 					'errorTip' => '2038 is approaching fast',
 				],
+				// test disallowed paths
+				[
+					'method' => 'Waldo\Quux\Blade::andSorcery()',
+					'message' => 'use magic',
+					'allowExceptIn' => [
+						'../src/disallowed/*.php',
+					],
+				],
 			]
 		);
 	}
@@ -185,6 +193,10 @@ class MethodCallsTest extends RuleTestCase
 				'Calling Waldo\Quux\Blade::trinity() is forbidden, holy trinity [Waldo\Quux\Blade::trinity() matches Waldo\Quux\Blade::Trinity()]',
 				65,
 			],
+			[
+				'Calling Waldo\Quux\Blade::andSorcery() is forbidden, use magic',
+				68,
+			],
 		]);
 		$this->analyse([__DIR__ . '/../src/disallowed-allow/methodCalls.php'], [
 			[
diff --git a/tests/Usages/ConstantUsagesTest.php b/tests/Usages/ConstantUsagesTest.php
index 86ab3c0..0aa8c87 100644
--- a/tests/Usages/ConstantUsagesTest.php
+++ b/tests/Usages/ConstantUsagesTest.php
@@ -39,6 +39,13 @@ class ConstantUsagesTest extends RuleTestCase
 					],
 					'errorTip' => 'Use https://github.com/mlocati/ip-lib instead',
 				],
+				// test disallowed paths
+				[
+					'constant' => 'PHP_EOL',
+					'allowExceptIn' => [
+						'../src/disallowed/*.php',
+					],
+				],
 			]
 		);
 	}
@@ -64,6 +71,10 @@ class ConstantUsagesTest extends RuleTestCase
 				'Using FILTER_FLAG_NO_RES_RANGE is forbidden, the cake is a lie',
 				10,
 			],
+			[
+				'Using PHP_EOL is forbidden, because reasons',
+				40,
+			],
 		]);
 		$this->analyse([__DIR__ . '/../src/disallowed-allow/constantUsages.php'], []);
 	}
diff --git a/tests/Usages/NamespaceUsagesTest.php b/tests/Usages/NamespaceUsagesTest.php
index 64975a1..2ed5708 100644
--- a/tests/Usages/NamespaceUsagesTest.php
+++ b/tests/Usages/NamespaceUsagesTest.php
@@ -63,6 +63,14 @@ class NamespaceUsagesTest extends RuleTestCase
 						'../src/*-allow/*.*',
 					],
 				],
+				// test disallowed paths
+				[
+					'namespace' => 'ZipArchive',
+					'message' => 'use clippy instead of zippy',
+					'disallowIn' => [
+						'../src/disallowed/*.php',
+					],
+				],
 			]
 		);
 	}
@@ -99,34 +107,42 @@ class NamespaceUsagesTest extends RuleTestCase
 				'Namespace Waldo\Quux\blade is forbidden, no blade [Waldo\Quux\blade matches Waldo\Quux\Blade]',
 				11,
 			],
+			[
+				'Namespace ZipArchive is forbidden, use clippy instead of zippy',
+				12,
+			],
 			[
 				'Namespace Inheritance\Base is forbidden, no inheritance sub base',
-				13,
+				14,
 			],
 			[
 				'Namespace Framework\SomeInterface is forbidden, no framework some [Framework\SomeInterface matches Framew*rk\Some*]',
-				13,
+				14,
 				'Work more on your frames',
 			],
 			[
 				'Trait Traits\TestTrait is forbidden, no TestTrait',
-				16,
+				17,
 			],
 			[
 				'Class Waldo\Quux\blade is forbidden, no blade [Waldo\Quux\blade matches Waldo\Quux\Blade]',
-				23,
+				24,
 			],
 			[
 				'Namespace Inheritance\Sub is forbidden, no inheritance sub base',
-				31,
+				32,
 			],
 			[
 				'Class Waldo\Foo\Bar is forbidden, no FooBar [Waldo\Foo\Bar matches Waldo\Foo\bar]',
-				37,
+				38,
 			],
 			[
 				'Class Waldo\Foo\Bar is forbidden, no FooBar [Waldo\Foo\Bar matches Waldo\Foo\bar]',
-				43,
+				44,
+			],
+			[
+				'Class ZipArchive is forbidden, use clippy instead of zippy',
+				50,
 			],
 		]);
 		$this->analyse([__DIR__ . '/../src/disallowed-allow/namespaceUsages.php'], []);
diff --git a/tests/Usages/SuperglobalUsagesTest.php b/tests/Usages/SuperglobalUsagesTest.php
index 52e6855..eae3078 100644
--- a/tests/Usages/SuperglobalUsagesTest.php
+++ b/tests/Usages/SuperglobalUsagesTest.php
@@ -38,6 +38,14 @@ class SuperglobalUsagesTest extends RuleTestCase
 						'../src/*-allow/*.*',
 					],
 				],
+				// test disallowed paths
+				[
+					'superglobal' => '$_REQUEST',
+					'message' => 'so $_GET or $_POST?',
+					'disallowIn' => [
+						'../src/disallowed/*.php',
+					],
+				],
 			])
 		);
 	}
@@ -66,6 +74,10 @@ class SuperglobalUsagesTest extends RuleTestCase
 				'Using $_POST is forbidden, the cake is a lie',
 				13,
 			],
+			[
+				'Using $_REQUEST is forbidden, so $_GET or $_POST?',
+				26,
+			],
 		]);
 		$this->analyse([__DIR__ . '/../src/disallowed-allow/superglobalUsages.php'], []);
 	}
diff --git a/tests/libs/Blade.php b/tests/libs/Blade.php
index 251a8f1..dee7ebd 100644
--- a/tests/libs/Blade.php
+++ b/tests/libs/Blade.php
@@ -37,4 +37,9 @@ class Blade
 	{
 	}
 
+
+	public function andSorcery(): void
+	{
+	}
+
 }
diff --git a/tests/src/disallowed-allow/constantUsages.php b/tests/src/disallowed-allow/constantUsages.php
index f26af28..1865a8e 100644
--- a/tests/src/disallowed-allow/constantUsages.php
+++ b/tests/src/disallowed-allow/constantUsages.php
@@ -35,3 +35,6 @@ Base::class;
  */
 $none = PhpOption\None::create();
 $none::NAME;
+
+// not disallowed by path
+PHP_EOL;
diff --git a/tests/src/disallowed-allow/methodCalls.php b/tests/src/disallowed-allow/methodCalls.php
index 138be82..a2979c8 100644
--- a/tests/src/disallowed-allow/methodCalls.php
+++ b/tests/src/disallowed-allow/methodCalls.php
@@ -63,3 +63,6 @@ $blade->sequel();
 $blade->Sequel();
 $blade->trinity();
 $blade->Trinity();
+
+// not disallowed by path
+$blade->andSorcery();
diff --git a/tests/src/disallowed/constantUsages.php b/tests/src/disallowed/constantUsages.php
index 821cc44..0e50d92 100644
--- a/tests/src/disallowed/constantUsages.php
+++ b/tests/src/disallowed/constantUsages.php
@@ -35,3 +35,6 @@ Base::class;
  */
 $none = PhpOption\None::create();
 $none::NAME;
+
+// disallowed by path
+PHP_EOL;
diff --git a/tests/src/disallowed/methodCalls.php b/tests/src/disallowed/methodCalls.php
index b6afc87..7f2bd20 100644
--- a/tests/src/disallowed/methodCalls.php
+++ b/tests/src/disallowed/methodCalls.php
@@ -63,3 +63,6 @@ $blade->sequel();
 $blade->Sequel();
 $blade->trinity();
 $blade->Trinity();
+
+// disallowed by path
+$blade->andSorcery();
diff --git a/tests/src/disallowed/namespaceUsages.php b/tests/src/disallowed/namespaceUsages.php
index daac758..edee8f6 100644
--- a/tests/src/disallowed/namespaceUsages.php
+++ b/tests/src/disallowed/namespaceUsages.php
@@ -9,6 +9,7 @@ use Inheritance\Sub;
 use Traits\TestTrait;
 use Waldo\Foo\Bar;
 use Waldo\Quux\blade;
+use ZipArchive;
 
 class Service extends Base implements SomeInterface
 {
@@ -43,4 +44,10 @@ class Service extends Base implements SomeInterface
 		return new Bar();
 	}
 
+
+	public function disallowedByPath()
+	{
+		return ZipArchive::EM_TRAD_PKWARE;
+	}
+
 }
diff --git a/tests/src/disallowed/superglobalUsages.php b/tests/src/disallowed/superglobalUsages.php
index 28ced5e..7488600 100644
--- a/tests/src/disallowed/superglobalUsages.php
+++ b/tests/src/disallowed/superglobalUsages.php
@@ -19,3 +19,9 @@ function useNonGlobalVariable()
 	$randomVar = 'foo';
 	echo $randomVar;
 }
+
+
+function disallowedByPath()
+{
+	$foo = $_REQUEST;
+}