Passed
Push — main ( f0dc87...b2d9cb )
by Alexandra
02:36
created

FilePathResolver   A

Complexity

Total Complexity 10

Size/Duplication

Total Lines 71
Duplicated Lines 0 %

Test Coverage

Coverage 84.85%

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 33
c 1
b 0
f 0
dl 0
loc 71
ccs 28
cts 33
cp 0.8485
rs 10
wmc 10

5 Methods

Rating   Name   Duplication   Size   Complexity  
A resolve() 0 8 1
A getTestPathAndMethodName() 0 15 3
A getApprovalFilePath() 0 24 3
A getApprovalFileName() 0 3 1
A endsWith() 0 8 2
1
<?php
2
3
declare(strict_types=1);
4
5
namespace AHJ\ApprovalTests;
6
7
use Exception;
8
9
final class FilePathResolver
10
{
11
    public const APPROVAL_DIR = 'approval';
12
13 2
    public function resolve(): FilePathResolverResult
14
    {
15 2
        [$pathToTestFile, $testMethodName] = $this->getTestPathAndMethodName();
16
17 2
        $approvalFilePath = $this->getApprovalFilePath($pathToTestFile);
18 2
        $approvalFileName = $this->getApprovalFileName($pathToTestFile, $testMethodName);
19
20 2
        return new FilePathResolverResult($approvalFilePath, $approvalFileName);
21
    }
22
23 4
    public function getApprovalFilePath(string $pathToTestFile): string
24
    {
25 4
        $pathParts = explode('/', pathinfo($pathToTestFile)['dirname']);
26 4
        $flip = array_flip($pathParts);
27
28
        try {
29 4
            $startKey = $flip['tests'];
30
        } catch (Exception $exception) {
31
            throw new Exception(sprintf(
32
                'Failed to identify the testing directory you are using in "%s", 
33
                expecting testing directory name "/tests".',
34
                $pathToTestFile
35
            ));
36
        }
37
38 4
        $endKey = count($pathParts) - 1;
39
40 4
        $approvalFilePath = '';
41
42 4
        for ($i = $startKey; $i <= $endKey; $i++) {
43 4
            $approvalFilePath .= $pathParts[$i] . '/';
44
        }
45
46 4
        return $approvalFilePath . self::APPROVAL_DIR;
47
    }
48
49 4
    public function getApprovalFileName(string $pathToTestFile, string $testMethodName): string
50
    {
51 4
        return pathinfo($pathToTestFile)['filename'] . '.' . $testMethodName;
52
    }
53
54 2
    public function getTestPathAndMethodName(): array
55
    {
56 2
        $traces = debug_backtrace(1);
57
58 2
        foreach ($traces as $key => $trace) {
59 2
            if ($this->endsWith($trace['file'], 'Test.php', true)) {
60 2
                $pathToTestFile = $trace['file'];
61 2
                $testMethodName = $traces[$key + 1]['function'];
62
63 2
                return [$pathToTestFile, $testMethodName];
64
            }
65
        }
66
67
        throw new Exception(sprintf(
68
            'Failed to identify the testing file or method you are using.'
69
        ));
70
    }
71
72 2
    private function endsWith(string $haystack, string $needle, $ignoreCase = false): bool
73
    {
74 2
        if ($ignoreCase) {
75 2
            $haystack = mb_strtolower($haystack);
76 2
            $needle = mb_strtolower($needle);
77
        }
78
79 2
        return mb_substr($haystack, mb_strlen($haystack) - mb_strlen($needle)) === $needle;
80
    }
81
}
82