Skip to content

Commit

Permalink
added tests on abstractness calculation
Browse files Browse the repository at this point in the history
  • Loading branch information
DeGraciaMathieu committed Nov 9, 2024
1 parent ca109e5 commit 7731c7b
Show file tree
Hide file tree
Showing 9 changed files with 93 additions and 30 deletions.
2 changes: 1 addition & 1 deletion app/Application/Analyze/AnalyzeAction.php
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ public function execute(AnalyzeRequest $request, AnalyzePresenter $presenter): v

$dependencyAggregator->calculateInstability();

$dependencyAggregator->calculateAbstraction();
$dependencyAggregator->calculateAbstractness();

$dependencyAggregator->filterClasses($request->only, $request->exclude);

Expand Down
19 changes: 3 additions & 16 deletions app/Domain/Aggregators/DependencyAggregator.php
Original file line number Diff line number Diff line change
Expand Up @@ -52,33 +52,20 @@ public function calculateInstability(): void
}
}

public function calculateAbstraction(): void
public function calculateAbstractness(): void
{
foreach ($this->classes as $givenClass) {

$abstractDependencies = 0;

$afferentCount = $givenClass->getAfferent();

if ($afferentCount === 0) {
$givenClass->setAbstractionLevel(0);
$givenClass->setNumberOfAbstractDependencies(0);
continue;
}

foreach ($givenClass->getDependencies() as $dependency) {

$dependencyClass = $this->get($dependency);

if ($dependencyClass && $dependencyClass->isAbstract()) {
$abstractDependencies++;
$givenClass->incrementNumberOfAbstractDependencies();
}
}

$abstraction = $abstractDependencies / $afferentCount;

$givenClass->setAbstractionLevel($abstraction);
$givenClass->setNumberOfAbstractDependencies($abstractDependencies);
$givenClass->calculateAbstractness();
}
}

Expand Down
22 changes: 16 additions & 6 deletions app/Domain/Entities/ClassDependencies.php
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ class ClassDependencies
public Coupling $afferent;
public Coupling $efferent;
public float $instability = 0;
public float $abstractionLevel = 0;
public float $abstractness = 0;
public int $numberOfAbstractDependencies = 0;

public function __construct(
Expand Down Expand Up @@ -92,6 +92,11 @@ public function getDependencies(): array
return $this->dependencies->getValues();
}

public function getAbstractness(): float
{
return $this->abstractness;
}

public function toArray(): array
{
return [
Expand All @@ -100,19 +105,24 @@ public function toArray(): array
'efferent' => $this->getEfferent(),
'dependencies' => $this->getDependencies(),
'instability' => $this->getRoundedInstability(),
'abstraction_level' => $this->abstractionLevel,
'abstractness' => $this->getAbstractness(),
'abstract' => $this->isAbstract(),
'number_of_abstract_dependencies' => $this->numberOfAbstractDependencies,
];
}

public function setAbstractionLevel(float $abstractionLevel): void
public function hasNoDependencies(): bool
{
return $this->getAfferent() === 0;
}

public function incrementNumberOfAbstractDependencies(): void
{
$this->abstractionLevel = $abstractionLevel;
$this->numberOfAbstractDependencies++;
}

public function setNumberOfAbstractDependencies(int $numberOfAbstractDependencies): void
public function calculateAbstractness(): void
{
$this->numberOfAbstractDependencies = $numberOfAbstractDependencies;
$this->abstractness = $this->numberOfAbstractDependencies / $this->getAfferent();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ public function parse(string $filePath): ClassAnalysis

$this->traverse($ast, $collectors);

return new ClassAnalysisAdapter($collectors['dependencies'], $collectors['type']);
return ClassAnalysisAdapter::fromArray($collectors);
}

private function getFileContent(string $filePath): ?string
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,4 +32,12 @@ public function isAbstract(): bool
{
return $this->classType->isAbstract();
}

public static function fromArray(array $attributes): self
{
return new self(
$attributes['dependencies'],
$attributes['type'],
);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -22,12 +22,12 @@ public function __construct(
private ClassTypeCollector $collector,
) {}

public function beforeTraverse(array $nodes)
public function beforeTraverse(array $nodes): void
{
//
}

public function enterNode(Node $node)
public function enterNode(Node $node): void
{
if ($node instanceof Namespace_) {
$this->collector->namespace = (string) $node->name;
Expand All @@ -45,7 +45,7 @@ public function enterNode(Node $node)
}
}

public function leaveNode(Node $node)
public function leaveNode(Node $node): void
{
//
}
Expand Down
4 changes: 2 additions & 2 deletions tests/Builders/ClassDependenciesBuilder.php
Original file line number Diff line number Diff line change
Expand Up @@ -32,14 +32,14 @@ public function withDependencies(array $dependencies): self
return $this;
}

public function marksAsInterface(): self
public function isInterface(): self
{
$this->isInterface = true;

return $this;
}

public function marksAsAbstract(): self
public function isAbstract(): self
{
$this->isAbstract = true;

Expand Down
38 changes: 38 additions & 0 deletions tests/Unit/Aggregators/DependencyAggregatorTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -54,3 +54,41 @@

expect($dependencies)->toHaveLength(0);
});

test('it calculates the abstractness correctly when class has no dependencies', function () {

$dependencyAggregator = $this->oneDependencyAggregator()
->withManyClassDependencies([
$this->oneClassDependencies()->withFqcn('A')->build(),
])
->build();

$dependencyAggregator->calculateAbstractness();

$metrics = $dependencyAggregator->toArray();

expect($metrics['A'])->toMatchArray([
'name' => 'A',
'abstractness' => 0.0,
]);
});

test('it calculates the abstractness correctly when class has abstract dependencies', function () {

$dependencyAggregator = $this->oneDependencyAggregator()
->withManyClassDependencies([
$this->oneClassDependencies()->withFqcn('A')->withDependencies(['B', 'C'])->build(),
$this->oneClassDependencies()->withFqcn('B')->isAbstract()->build(),
$this->oneClassDependencies()->withFqcn('C')->build(),
])
->build();

$dependencyAggregator->calculateAbstractness();

$metrics = $dependencyAggregator->toArray();

expect($metrics['A'])->toMatchArray([
'name' => 'A',
'abstractness' => 0.5,
]);
});
22 changes: 21 additions & 1 deletion tests/Unit/Entities/ClassDependenciesTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -62,4 +62,24 @@
->build();

expect($classDependencies->hasDependency($b))->toBeTrue();
});
});

test('it calculates the abstractness correctly', function (int $numberOfAbstractDependencies, float $expected) {

$classDependencies = $this->oneClassDependencies()
->withFqcn('A')
->build();

for ($i = 0; $i < $numberOfAbstractDependencies; $i++) {
$classDependencies->incrementNumberOfAbstractDependencies();
}

$classDependencies->calculateAbstractness();

expect($classDependencies->getAbstractness())->toBe($expected);

})->with([
[0, 0.0],
[1, 0.5],
[2, 1.0],
]);

0 comments on commit 7731c7b

Please sign in to comment.