Skip to content

Commit 68315fc

Browse files
wip
1 parent 575f131 commit 68315fc

File tree

10 files changed

+85
-52
lines changed

10 files changed

+85
-52
lines changed

src/Expression/ForClasses/DependsOnlyOnTheseNamespaces.php

Lines changed: 16 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -17,9 +17,13 @@ class DependsOnlyOnTheseNamespaces implements Expression
1717
/** @var array<string> */
1818
private array $namespaces;
1919

20-
public function __construct(string ...$namespace)
20+
/** @var array<string> */
21+
private array $exclude;
22+
23+
public function __construct(array $namespaces = [], array $exclude = [])
2124
{
22-
$this->namespaces = $namespace;
25+
$this->namespaces = $namespaces;
26+
$this->exclude = $exclude;
2327
}
2428

2529
public function describe(ClassDescription $theClass, string $because): Description
@@ -35,11 +39,16 @@ public function evaluate(ClassDescription $theClass, Violations $violations, str
3539

3640
/** @var ClassDependency $dependency */
3741
foreach ($dependencies as $dependency) {
38-
if (
39-
'' === $dependency->getFQCN()->namespace()
40-
|| $theClass->namespaceMatches($dependency->getFQCN()->namespace())
41-
) {
42-
continue;
42+
if ('' === $dependency->getFQCN()->namespace()) {
43+
continue; // skip root namespace
44+
}
45+
46+
if ($theClass->namespaceMatches($dependency->getFQCN()->namespace())) {
47+
continue; // skip classes in the same namespace
48+
}
49+
50+
if ($dependency->matchesOneOf(...$this->exclude)) {
51+
continue; // skip excluded namespaces
4352
}
4453

4554
if (!$dependency->matchesOneOf(...$this->namespaces)) {

src/Expression/ForClasses/NotDependsOnTheseNamespaces.php

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,9 +17,13 @@ class NotDependsOnTheseNamespaces implements Expression
1717
/** @var array<string> */
1818
private array $namespaces;
1919

20-
public function __construct(string ...$namespace)
20+
/** @var array<string> */
21+
private array $exclude;
22+
23+
public function __construct(array $namespaces, array $exclude = [])
2124
{
22-
$this->namespaces = $namespace;
25+
$this->namespaces = $namespaces;
26+
$this->exclude = $exclude;
2327
}
2428

2529
public function describe(ClassDescription $theClass, string $because): Description
@@ -36,7 +40,11 @@ public function evaluate(ClassDescription $theClass, Violations $violations, str
3640
/** @var ClassDependency $dependency */
3741
foreach ($dependencies as $dependency) {
3842
if ('' === $dependency->getFQCN()->namespace()) {
39-
continue;
43+
continue; // skip root namespace
44+
}
45+
46+
if ($dependency->matchesOneOf(...$this->exclude)) {
47+
continue; // skip excluded namespaces
4048
}
4149

4250
if ($dependency->matchesOneOf(...$this->namespaces)) {

src/RuleBuilders/Architecture/Architecture.php

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -90,13 +90,13 @@ public function rules(string $because = 'of component architecture'): iterable
9090
$forbiddenComponents = array_diff($layerNames, [$name], $this->allowedDependencies[$name]);
9191

9292
if (!empty($forbiddenComponents)) {
93-
$forbiddenSelectors = array_map(function (string $componentName): string {
93+
$forbiddenSelectors = array_values(array_map(function (string $componentName): string {
9494
return $this->componentSelectors[$componentName];
95-
}, $forbiddenComponents);
95+
}, $forbiddenComponents));
9696

9797
yield Rule::allClasses()
9898
->that(new ResideInOneOfTheseNamespaces($selector))
99-
->should(new NotDependsOnTheseNamespaces(...$forbiddenSelectors))
99+
->should(new NotDependsOnTheseNamespaces($forbiddenSelectors))
100100
->because($because);
101101
}
102102
}
@@ -105,13 +105,13 @@ public function rules(string $because = 'of component architecture'): iterable
105105
continue;
106106
}
107107

108-
$allowedDependencies = array_map(function (string $componentName): string {
108+
$allowedDependencies = array_values(array_map(function (string $componentName): string {
109109
return $this->componentSelectors[$componentName];
110-
}, $this->componentDependsOnlyOnTheseNamespaces[$name]);
110+
}, $this->componentDependsOnlyOnTheseNamespaces[$name]));
111111

112112
yield Rule::allClasses()
113113
->that(new ResideInOneOfTheseNamespaces($selector))
114-
->should(new DependsOnlyOnTheseNamespaces(...$allowedDependencies))
114+
->should(new DependsOnlyOnTheseNamespaces($allowedDependencies))
115115
->because($because);
116116
}
117117
}

tests/E2E/_fixtures/configDependenciesLeak.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212

1313
$rule_1 = Rule::allClasses()
1414
->that(new ResideInOneOfTheseNamespaces('App\DependenciesLeak\SecondModule'))
15-
->should(new NotDependsOnTheseNamespaces('App\DependenciesLeak\FirstModule'))
15+
->should(new NotDependsOnTheseNamespaces(['App\DependenciesLeak\FirstModule']))
1616
->because('modules should be independent');
1717

1818
$config

tests/E2E/_fixtures/configIgnoreBaselineLineNumbers.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
$rules = [
1616
Rule::allClasses()
1717
->that(new ResideInOneOfTheseNamespaces('App\Application'))
18-
->should(new DependsOnlyOnTheseNamespaces('App\Application'))
18+
->should(new DependsOnlyOnTheseNamespaces(['App\Application']))
1919
->because('That is how I want it'),
2020
];
2121

tests/Integration/CheckAttributeDependencyTest.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ public function test_assertion_should_fail_on_invalid_dependency(): void
2121

2222
$rule = Rule::allClasses()
2323
->that(new ResideInOneOfTheseNamespaces('App'))
24-
->should(new NotDependsOnTheseNamespaces('App\Invalid'))
24+
->should(new NotDependsOnTheseNamespaces(['App\Invalid']))
2525
->because('i said so');
2626

2727
$runner->run($dir, $rule);

tests/Unit/Analyzer/FileVisitorTest.php

Lines changed: 22 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ public function __construct(Request $request)
5959

6060
$violations = new Violations();
6161

62-
$dependsOnTheseNamespaces = new DependsOnlyOnTheseNamespaces('Foo');
62+
$dependsOnTheseNamespaces = new DependsOnlyOnTheseNamespaces(['Foo']);
6363
$dependsOnTheseNamespaces->evaluate($fp->getClassDescriptions()[0], $violations, 'because');
6464

6565
self::assertCount(2, $violations);
@@ -231,7 +231,7 @@ public function __construct(Request $request)
231231

232232
$violations = new Violations();
233233

234-
$dependsOnTheseNamespaces = new DependsOnlyOnTheseNamespaces('Foo', 'Symfony', 'Doctrine');
234+
$dependsOnTheseNamespaces = new DependsOnlyOnTheseNamespaces(['Foo', 'Symfony', 'Doctrine']);
235235
$dependsOnTheseNamespaces->evaluate($cd[0], $violations, 'we want to add this rule for our software');
236236

237237
self::assertCount(0, $violations);
@@ -300,7 +300,7 @@ public function __construct()
300300

301301
$violations = new Violations();
302302

303-
$dependsOnTheseNamespaces = new DependsOnlyOnTheseNamespaces('Foo', 'Symfony', 'Doctrine');
303+
$dependsOnTheseNamespaces = new DependsOnlyOnTheseNamespaces(['Foo', 'Symfony', 'Doctrine']);
304304
$dependsOnTheseNamespaces->evaluate($cd[0], $violations, 'we want to add this rule for our software');
305305

306306
self::assertCount(0, $violations);
@@ -679,7 +679,7 @@ class ApplicationLevelDto
679679

680680
$violations = new Violations();
681681

682-
$notHaveDependencyOutsideNamespace = new DependsOnlyOnTheseNamespaces('MyProject\AppBundle\Application');
682+
$notHaveDependencyOutsideNamespace = new DependsOnlyOnTheseNamespaces(['MyProject\AppBundle\Application']);
683683
$notHaveDependencyOutsideNamespace->evaluate($cd[0], $violations, 'we want to add this rule for our software');
684684

685685
self::assertCount(1, $violations);
@@ -707,7 +707,7 @@ class ApplicationLevelDto
707707

708708
$violations = new Violations();
709709

710-
$notHaveDependencyOutsideNamespace = new DependsOnlyOnTheseNamespaces('MyProject\AppBundle\Application');
710+
$notHaveDependencyOutsideNamespace = new DependsOnlyOnTheseNamespaces(['MyProject\AppBundle\Application']);
711711
$notHaveDependencyOutsideNamespace->evaluate($cd[0], $violations, 'we want to add this rule for our software');
712712

713713
self::assertCount(1, $violations);
@@ -801,7 +801,7 @@ class ApplicationLevelDto
801801

802802
$violations = new Violations();
803803

804-
$notHaveDependencyOutsideNamespace = new DependsOnlyOnTheseNamespaces('MyProject\AppBundle\Application');
804+
$notHaveDependencyOutsideNamespace = new DependsOnlyOnTheseNamespaces(['MyProject\AppBundle\Application']);
805805
$notHaveDependencyOutsideNamespace->evaluate($cd[0], $violations, 'we want to add this rule for our software');
806806

807807
self::assertCount(1, $violations);
@@ -831,7 +831,7 @@ class ApplicationLevelDto
831831

832832
$violations = new Violations();
833833

834-
$notHaveDependencyOutsideNamespace = new DependsOnlyOnTheseNamespaces('MyProject\AppBundle\Application');
834+
$notHaveDependencyOutsideNamespace = new DependsOnlyOnTheseNamespaces(['MyProject\AppBundle\Application']);
835835
$notHaveDependencyOutsideNamespace->evaluate($cd[0], $violations, 'we want to add this rule for our software');
836836

837837
self::assertCount(1, $violations);
@@ -894,7 +894,7 @@ class ApplicationLevelDto
894894

895895
$violations = new Violations();
896896

897-
$dependsOnTheseNamespaces = new DependsOnlyOnTheseNamespaces('MyProject\AppBundle\Application');
897+
$dependsOnTheseNamespaces = new DependsOnlyOnTheseNamespaces(['MyProject\AppBundle\Application']);
898898
$dependsOnTheseNamespaces->evaluate($cd[0], $violations, 'we want to add this rule for our software');
899899

900900
self::assertCount(1, $violations);
@@ -920,7 +920,7 @@ public function getBookList(): QueryBuilder;
920920

921921
$violations = new Violations();
922922

923-
$dependsOnTheseNamespaces = new DependsOnlyOnTheseNamespaces('MyProject\AppBundle\Application');
923+
$dependsOnTheseNamespaces = new DependsOnlyOnTheseNamespaces(['MyProject\AppBundle\Application']);
924924
$dependsOnTheseNamespaces->evaluate($cd[0], $violations, 'we want to add this rule for our software');
925925

926926
self::assertCount(1, $violations);
@@ -991,7 +991,7 @@ public function getRequest(): Request //the violations is reported here
991991

992992
$violations = new Violations();
993993

994-
$dependsOnTheseNamespaces = new DependsOnlyOnTheseNamespaces('Foo', 'Symfony', 'Doctrine');
994+
$dependsOnTheseNamespaces = new DependsOnlyOnTheseNamespaces(['Foo', 'Symfony', 'Doctrine']);
995995
$dependsOnTheseNamespaces->evaluate($cd[0], $violations, 'we want to add this rule for our software');
996996

997997
self::assertCount(0, $violations);
@@ -1020,7 +1020,7 @@ class ApplicationLevelDto
10201020

10211021
$violations = new Violations();
10221022

1023-
$dependsOnlyOnTheseNamespaces = new DependsOnlyOnTheseNamespaces('MyProject\AppBundle\Application');
1023+
$dependsOnlyOnTheseNamespaces = new DependsOnlyOnTheseNamespaces(['MyProject\AppBundle\Application']);
10241024
$dependsOnlyOnTheseNamespaces->evaluate($cd[0], $violations, 'we want to add this rule for our software');
10251025

10261026
self::assertCount(0, $violations);
@@ -1079,7 +1079,7 @@ class MyClass
10791079

10801080
$violations = new Violations();
10811081

1082-
$dependsOnTheseNamespaces = new DependsOnlyOnTheseNamespaces('Domain');
1082+
$dependsOnTheseNamespaces = new DependsOnlyOnTheseNamespaces(['Domain']);
10831083
$dependsOnTheseNamespaces->evaluate($cd[0], $violations, 'we want to add this rule for our software');
10841084

10851085
self::assertCount(1, $violations);
@@ -1109,7 +1109,7 @@ class MyClass
11091109

11101110
$violations = new Violations();
11111111

1112-
$dependsOnTheseNamespaces = new DependsOnlyOnTheseNamespaces('Domain');
1112+
$dependsOnTheseNamespaces = new DependsOnlyOnTheseNamespaces(['Domain']);
11131113
$dependsOnTheseNamespaces->evaluate($cd[0], $violations, 'we want to add this rule for our software');
11141114

11151115
self::assertCount(1, $violations);
@@ -1139,7 +1139,7 @@ class MyClass
11391139

11401140
$violations = new Violations();
11411141

1142-
$dependsOnTheseNamespaces = new DependsOnlyOnTheseNamespaces('Domain');
1142+
$dependsOnTheseNamespaces = new DependsOnlyOnTheseNamespaces(['Domain']);
11431143
$dependsOnTheseNamespaces->evaluate($cd[0], $violations, 'we want to add this rule for our software');
11441144

11451145
self::assertCount(1, $violations);
@@ -1171,7 +1171,7 @@ public function __construct(array $dtoList)
11711171

11721172
$violations = new Violations();
11731173

1174-
$dependsOnTheseNamespaces = new DependsOnlyOnTheseNamespaces('Domain');
1174+
$dependsOnTheseNamespaces = new DependsOnlyOnTheseNamespaces(['Domain']);
11751175
$dependsOnTheseNamespaces->evaluate($cd[0], $violations, 'we want to add this rule for our software');
11761176

11771177
self::assertCount(1, $violations);
@@ -1203,7 +1203,7 @@ public function __construct(array $dtoList)
12031203

12041204
$violations = new Violations();
12051205

1206-
$dependsOnTheseNamespaces = new DependsOnlyOnTheseNamespaces('Domain');
1206+
$dependsOnTheseNamespaces = new DependsOnlyOnTheseNamespaces(['Domain']);
12071207
$dependsOnTheseNamespaces->evaluate($cd[0], $violations, 'we want to add this rule for our software');
12081208

12091209
self::assertCount(1, $violations);
@@ -1235,7 +1235,7 @@ public function __construct(array $dtoList)
12351235

12361236
$violations = new Violations();
12371237

1238-
$dependsOnTheseNamespaces = new DependsOnlyOnTheseNamespaces('Domain');
1238+
$dependsOnTheseNamespaces = new DependsOnlyOnTheseNamespaces(['Domain']);
12391239
$dependsOnTheseNamespaces->evaluate($cd[0], $violations, 'we want to add this rule for our software');
12401240

12411241
self::assertCount(1, $violations);
@@ -1270,7 +1270,7 @@ public function __construct(string $var1, array $dtoList, $var2, array $voList)
12701270

12711271
$violations = new Violations();
12721272

1273-
$dependsOnTheseNamespaces = new DependsOnlyOnTheseNamespaces('Domain');
1273+
$dependsOnTheseNamespaces = new DependsOnlyOnTheseNamespaces(['Domain']);
12741274
$dependsOnTheseNamespaces->evaluate($cd[0], $violations, 'we want to add this rule for our software');
12751275

12761276
self::assertCount(1, $violations);
@@ -1303,7 +1303,7 @@ public function getList(): array
13031303

13041304
$violations = new Violations();
13051305

1306-
$dependsOnTheseNamespaces = new DependsOnlyOnTheseNamespaces('Domain');
1306+
$dependsOnTheseNamespaces = new DependsOnlyOnTheseNamespaces(['Domain']);
13071307
$dependsOnTheseNamespaces->evaluate($cd[0], $violations, 'we want to add this rule for our software');
13081308

13091309
self::assertCount(1, $violations);
@@ -1336,7 +1336,7 @@ public function getList(): array
13361336

13371337
$violations = new Violations();
13381338

1339-
$dependsOnTheseNamespaces = new DependsOnlyOnTheseNamespaces('Domain');
1339+
$dependsOnTheseNamespaces = new DependsOnlyOnTheseNamespaces(['Domain']);
13401340
$dependsOnTheseNamespaces->evaluate($cd[0], $violations, 'we want to add this rule for our software');
13411341

13421342
self::assertCount(1, $violations);
@@ -1369,7 +1369,7 @@ public function getList(): array
13691369

13701370
$violations = new Violations();
13711371

1372-
$dependsOnTheseNamespaces = new DependsOnlyOnTheseNamespaces('Domain');
1372+
$dependsOnTheseNamespaces = new DependsOnlyOnTheseNamespaces(['Domain']);
13731373
$dependsOnTheseNamespaces->evaluate($cd[0], $violations, 'we want to add this rule for our software');
13741374

13751375
self::assertCount(1, $violations);
@@ -1398,7 +1398,7 @@ public function getBookList(): QueryBuilder
13981398

13991399
$violations = new Violations();
14001400

1401-
$dependsOnTheseNamespaces = new DependsOnlyOnTheseNamespaces('MyProject\AppBundle\Application');
1401+
$dependsOnTheseNamespaces = new DependsOnlyOnTheseNamespaces(['MyProject\AppBundle\Application']);
14021402
$dependsOnTheseNamespaces->evaluate($cd[0], $violations, 'we want to add this rule for our software');
14031403

14041404
self::assertCount(1, $violations);

tests/Unit/Architecture/ArchitectureTest.php

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -28,11 +28,11 @@ public function test_layered_architecture(): void
2828
$expectedRules = [
2929
Rule::allClasses()
3030
->that(new ResideInOneOfTheseNamespaces('App\*\Domain\*'))
31-
->should(new NotDependsOnTheseNamespaces('App\*\Application\*', 'App\*\Infrastructure\*'))
31+
->should(new NotDependsOnTheseNamespaces(['App\*\Application\*', 'App\*\Infrastructure\*']))
3232
->because('of component architecture'),
3333
Rule::allClasses()
3434
->that(new ResideInOneOfTheseNamespaces('App\*\Application\*'))
35-
->should(new NotDependsOnTheseNamespaces('App\*\Infrastructure\*'))
35+
->should(new NotDependsOnTheseNamespaces(['App\*\Infrastructure\*']))
3636
->because('of component architecture'),
3737
];
3838

@@ -50,7 +50,7 @@ public function test_layered_architecture_with_depends_only_on_components(): voi
5050
$expectedRules = [
5151
Rule::allClasses()
5252
->that(new ResideInOneOfTheseNamespaces('App\*\Domain\*'))
53-
->should(new DependsOnlyOnTheseNamespaces('App\*\Domain\*'))
53+
->should(new DependsOnlyOnTheseNamespaces(['App\*\Domain\*']))
5454
->because('of component architecture'),
5555
];
5656

0 commit comments

Comments
 (0)