Completed
Push — master ( bcc930...059858 )
by Guillermo
11s
created

EnumTester   A

Complexity

Total Complexity 12

Size/Duplication

Total Lines 126
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 3

Importance

Changes 0
Metric Value
wmc 12
lcom 1
cbo 3
dl 0
loc 126
rs 10
c 0
b 0
f 0

8 Methods

Rating   Name   Duplication   Size   Complexity  
enumClass() 0 1 ?
A invalidConstructor() 0 13 1
A callInvalidStaticMethod() 0 13 1
A callInvalidMethod() 0 15 1
A staticAccessByPhpDoc() 0 15 3
A accessByPhpDoc() 0 21 4
A createValidEnum() 0 6 1
A snakeCaseToCamelCase() 0 6 1
1
<?php
2
3
namespace Atrapalo\PHPTools\Tester\Enum;
4
5
use Atrapalo\PHPTools\Enum\Enum;
6
use Atrapalo\PHPTools\Parser\PHPDocClass;
7
8
/**
9
 * Class EnumPHPDocTester
10
 * @package Atrapalo\PHPTools\Enum
11
 *
12
 * @author Guillermo González <[email protected]>
13
 */
14
trait EnumTester
15
{
16
    /**
17
     * @return string
18
     */
19
    abstract protected function enumClass(): string;
20
21
    /**
22
     * @test
23
     */
24
    public function invalidConstructor()
25
    {
26
        /** @var Enum $enumClass */
27
        $enumClass = $this->enumClass();
28
        $value = md5(openssl_random_pseudo_bytes(32));
29
30
        $exception = $enumClass::customInvalidValueException($value);
31
32
        $this->expectException(get_class($exception));
0 ignored issues
show
Bug introduced by
It seems like expectException() must be provided by classes using this trait. How about adding it as abstract method to this trait?

This check looks for methods that are used by a trait but not required by it.

To illustrate, let’s look at the following code example

trait Idable {
    public function equalIds(Idable $other) {
        return $this->getId() === $other->getId();
    }
}

The trait Idable provides a method equalsId that in turn relies on the method getId(). If this method does not exist on a class mixing in this trait, the method will fail.

Adding the getId() as an abstract method to the trait will make sure it is available.

Loading history...
33
        $this->expectExceptionMessage($exception->getMessage());
0 ignored issues
show
Bug introduced by
It seems like expectExceptionMessage() must be provided by classes using this trait. How about adding it as abstract method to this trait?

This check looks for methods that are used by a trait but not required by it.

To illustrate, let’s look at the following code example

trait Idable {
    public function equalIds(Idable $other) {
        return $this->getId() === $other->getId();
    }
}

The trait Idable provides a method equalsId that in turn relies on the method getId(). If this method does not exist on a class mixing in this trait, the method will fail.

Adding the getId() as an abstract method to the trait will make sure it is available.

Loading history...
34
35
        new $enumClass($value);
36
    }
37
38
    /**
39
     * @test
40
     */
41
    public function callInvalidStaticMethod()
42
    {
43
        /** @var Enum $enumClass */
44
        $enumClass = $this->enumClass();
45
        $method = md5(openssl_random_pseudo_bytes(32));
46
47
        $exception = $enumClass::customUnknownStaticMethodException($method);
48
49
        $this->expectException(get_class($exception));
0 ignored issues
show
Bug introduced by
It seems like expectException() must be provided by classes using this trait. How about adding it as abstract method to this trait?

This check looks for methods that are used by a trait but not required by it.

To illustrate, let’s look at the following code example

trait Idable {
    public function equalIds(Idable $other) {
        return $this->getId() === $other->getId();
    }
}

The trait Idable provides a method equalsId that in turn relies on the method getId(). If this method does not exist on a class mixing in this trait, the method will fail.

Adding the getId() as an abstract method to the trait will make sure it is available.

Loading history...
50
        $this->expectExceptionMessage($exception->getMessage());
0 ignored issues
show
Bug introduced by
It seems like expectExceptionMessage() must be provided by classes using this trait. How about adding it as abstract method to this trait?

This check looks for methods that are used by a trait but not required by it.

To illustrate, let’s look at the following code example

trait Idable {
    public function equalIds(Idable $other) {
        return $this->getId() === $other->getId();
    }
}

The trait Idable provides a method equalsId that in turn relies on the method getId(). If this method does not exist on a class mixing in this trait, the method will fail.

Adding the getId() as an abstract method to the trait will make sure it is available.

Loading history...
51
52
        call_user_func([$enumClass, $method]);
53
    }
54
55
    /**
56
     * @test
57
     */
58
    public function callInvalidMethod()
59
    {
60
        /** @var Enum $enumClass */
61
        $enumClass = $this->enumClass();
62
63
        $enum = $this->createValidEnum($enumClass);
64
        $method = md5(openssl_random_pseudo_bytes(32));
65
66
        $exception = $enumClass::customUnknownMethodException($method);
67
68
        $this->expectException(get_class($exception));
0 ignored issues
show
Bug introduced by
It seems like expectException() must be provided by classes using this trait. How about adding it as abstract method to this trait?

This check looks for methods that are used by a trait but not required by it.

To illustrate, let’s look at the following code example

trait Idable {
    public function equalIds(Idable $other) {
        return $this->getId() === $other->getId();
    }
}

The trait Idable provides a method equalsId that in turn relies on the method getId(). If this method does not exist on a class mixing in this trait, the method will fail.

Adding the getId() as an abstract method to the trait will make sure it is available.

Loading history...
69
        $this->expectExceptionMessage($exception->getMessage());
0 ignored issues
show
Bug introduced by
It seems like expectExceptionMessage() must be provided by classes using this trait. How about adding it as abstract method to this trait?

This check looks for methods that are used by a trait but not required by it.

To illustrate, let’s look at the following code example

trait Idable {
    public function equalIds(Idable $other) {
        return $this->getId() === $other->getId();
    }
}

The trait Idable provides a method equalsId that in turn relies on the method getId(). If this method does not exist on a class mixing in this trait, the method will fail.

Adding the getId() as an abstract method to the trait will make sure it is available.

Loading history...
70
71
        $enum->$method();
72
    }
73
74
    /**
75
     * @test
76
     */
77
    public function staticAccessByPhpDoc()
78
    {
79
        $className = $this->enumClass();
80
81
        $staticMethods = PHPDocClass::staticMethods($className);
82
        if (!empty($staticMethods)) {
83
            foreach ($staticMethods as $staticMethod) {
84
                $data = call_user_func([$className, $staticMethod->name()]);
85
86
                $this->assertInstanceOf($className, $data);
0 ignored issues
show
Bug introduced by
It seems like assertInstanceOf() must be provided by classes using this trait. How about adding it as abstract method to this trait?

This check looks for methods that are used by a trait but not required by it.

To illustrate, let’s look at the following code example

trait Idable {
    public function equalIds(Idable $other) {
        return $this->getId() === $other->getId();
    }
}

The trait Idable provides a method equalsId that in turn relies on the method getId(). If this method does not exist on a class mixing in this trait, the method will fail.

Adding the getId() as an abstract method to the trait will make sure it is available.

Loading history...
87
            }
88
        } else {
89
            $this->markTestSkipped('Skipped because no static methods were found for '.get_called_class());
0 ignored issues
show
Bug introduced by
It seems like markTestSkipped() must be provided by classes using this trait. How about adding it as abstract method to this trait?

This check looks for methods that are used by a trait but not required by it.

To illustrate, let’s look at the following code example

trait Idable {
    public function equalIds(Idable $other) {
        return $this->getId() === $other->getId();
    }
}

The trait Idable provides a method equalsId that in turn relies on the method getId(). If this method does not exist on a class mixing in this trait, the method will fail.

Adding the getId() as an abstract method to the trait will make sure it is available.

Loading history...
90
        }
91
    }
92
93
    /**
94
     * @test
95
     */
96
    public function accessByPhpDoc()
97
    {
98
        $className = $this->enumClass();
99
100
        $methods = PHPDocClass::methods($className);
101
        if (!empty($methods)) {
102
103
            $enum = $this->createValidEnum($className);
104
            $actualMethod = $this->snakeCaseToCamelCase("IS_".$enum->key());
105
            foreach ($methods as $method) {
106
                $methodName = $method->name();
107
                if ($methodName === $actualMethod) {
108
                    $this->assertTrue($enum->$methodName());
0 ignored issues
show
Bug introduced by
It seems like assertTrue() must be provided by classes using this trait. How about adding it as abstract method to this trait?

This check looks for methods that are used by a trait but not required by it.

To illustrate, let’s look at the following code example

trait Idable {
    public function equalIds(Idable $other) {
        return $this->getId() === $other->getId();
    }
}

The trait Idable provides a method equalsId that in turn relies on the method getId(). If this method does not exist on a class mixing in this trait, the method will fail.

Adding the getId() as an abstract method to the trait will make sure it is available.

Loading history...
109
                } else {
110
                    $this->assertFalse($enum->$methodName());
0 ignored issues
show
Bug introduced by
It seems like assertFalse() must be provided by classes using this trait. How about adding it as abstract method to this trait?

This check looks for methods that are used by a trait but not required by it.

To illustrate, let’s look at the following code example

trait Idable {
    public function equalIds(Idable $other) {
        return $this->getId() === $other->getId();
    }
}

The trait Idable provides a method equalsId that in turn relies on the method getId(). If this method does not exist on a class mixing in this trait, the method will fail.

Adding the getId() as an abstract method to the trait will make sure it is available.

Loading history...
111
                }
112
            }
113
        } else {
114
            $this->markTestSkipped('Skipped because no methods were found for '.get_called_class());
0 ignored issues
show
Bug introduced by
It seems like markTestSkipped() must be provided by classes using this trait. How about adding it as abstract method to this trait?

This check looks for methods that are used by a trait but not required by it.

To illustrate, let’s look at the following code example

trait Idable {
    public function equalIds(Idable $other) {
        return $this->getId() === $other->getId();
    }
}

The trait Idable provides a method equalsId that in turn relies on the method getId(). If this method does not exist on a class mixing in this trait, the method will fail.

Adding the getId() as an abstract method to the trait will make sure it is available.

Loading history...
115
        }
116
    }
117
118
    /**
119
     * @param Enum|string $className
120
     * @return Enum
121
     */
122
    private function createValidEnum($className)
123
    {
124
        $values = $className::toArray();
125
126
        return new $className($values[array_rand($values)]);
127
    }
128
129
    /**
130
     * @param string $string
131
     * @return string
132
     */
133
    private function snakeCaseToCamelCase(string $string): string
134
    {
135
        return preg_replace_callback('/_(.?)/', function($matches) {
136
            return ucfirst($matches[1]);
137
        }, strtolower($string));
138
    }
139
}