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

FilePathResolver::getApprovalFilePath()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 24
Code Lines 13

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 10
CRAP Score 3.0416

Importance

Changes 2
Bugs 0 Features 0
Metric Value
cc 3
eloc 13
c 2
b 0
f 0
nc 3
nop 1
dl 0
loc 24
ccs 10
cts 12
cp 0.8333
crap 3.0416
rs 9.8333
1
<?php
2
3
declare(strict_types=1);
4
5
namespace AHJ\ApprovalTests;
6
7
use RuntimeException;
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 4
        if (!array_key_exists('tests', $flip)) {
29
            throw new RuntimeException(sprintf(
30
                'Failed to identify the testing directory you are using in "%s", 
31
                expecting testing directory name "/tests".',
32
                $pathToTestFile
33
            ));
34
        }
35
36 4
        $startKey = $flip['tests'];
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 RuntimeException(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