Completed
Push — master ( 4ad6bd...3873e4 )
by Ingo
11:53
created

ExtensionTestState::setUpOnce()   C

Complexity

Conditions 16
Paths 48

Size

Total Lines 62
Code Lines 34

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 16
eloc 34
nc 48
nop 1
dl 0
loc 62
rs 6.1338
c 0
b 0
f 0

How to fix   Long Method    Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
3
namespace SilverStripe\Dev\State;
4
5
use LogicException;
6
use SilverStripe\Core\Extension;
7
use SilverStripe\Core\Injector\Injector;
8
use SilverStripe\Dev\Debug;
9
use SilverStripe\Dev\SapphireTest;
10
use SilverStripe\ORM\DataObject;
11
12
/**
13
 * Manages illegal and required extensions for sapphiretest
14
 */
15
class ExtensionTestState implements TestState
16
{
17
    /**
18
     * @var array
19
     */
20
    protected $extensionsToReapply = [];
21
22
    /**
23
     * @var array
24
     */
25
    protected $extensionsToRemove = [];
26
27
    /**
28
     * Called on setup
29
     *
30
     * @param SapphireTest $test
31
     */
32
    public function setUp(SapphireTest $test)
33
    {
34
    }
35
36
    public function tearDown(SapphireTest $test)
37
    {
38
    }
39
40
    public function setUpOnce($class)
41
    {
42
        // May be altered by another class
43
        $isAltered = false;
44
        $this->extensionsToReapply = [];
45
        $this->extensionsToRemove = [];
46
47
        /** @var string|SapphireTest $class */
48
        /** @var string|DataObject $dataClass */
49
        // Remove any illegal extensions that are present
50
        foreach ($class::getIllegalExtensions() as $dataClass => $extensions) {
51
            if (!class_exists($dataClass)) {
52
                continue;
53
            }
54
            if ($extensions === '*') {
55
                $extensions = $dataClass::get_extensions();
56
            }
57
            foreach ($extensions as $extension) {
58
                if (!class_exists($extension) || !$dataClass::has_extension($extension)) {
59
                    continue;
60
                }
61
                if (!isset($this->extensionsToReapply[$dataClass])) {
62
                    $this->extensionsToReapply[$dataClass] = [];
63
                }
64
                $this->extensionsToReapply[$dataClass][] = $extension;
65
                $dataClass::remove_extension($extension);
66
                $isAltered = true;
67
            }
68
        }
69
70
        // Add any required extensions that aren't present
71
        foreach ($class::getRequiredExtensions() as $dataClass => $extensions) {
72
            if (!class_exists($dataClass)) {
73
                throw new LogicException("Test {$class} requires dataClass {$dataClass} which doesn't exist");
74
            }
75
            foreach ($extensions as $extension) {
76
                $extension = Extension::get_classname_without_arguments($extension);
77
                if (!class_exists($extension)) {
78
                    throw new LogicException("Test {$class} requires extension {$extension} which doesn't exist");
79
                }
80
                if (!$dataClass::has_extension($extension)) {
81
                    if (!isset($this->extensionsToRemove[$dataClass])) {
82
                        $this->extensionsToRemove[$dataClass] = [];
83
                    }
84
                    $this->extensionsToRemove[$dataClass][] = $extension;
85
                    $dataClass::add_extension($extension);
86
                    $isAltered = true;
87
                }
88
            }
89
        }
90
91
        // clear singletons, they're caching old extension info
92
        // which is used in DatabaseAdmin->doBuild()
93
        Injector::inst()->unregisterObjects(DataObject::class);
94
95
        // If we have altered the schema, but SapphireTest::setUpBeforeClass() would not otherwise
96
        // reset the schema (if there were extra objects) then force a reset
97
        if ($isAltered && empty($class::getExtraDataObjects())) {
98
            DataObject::reset();
99
            $class::resetDBSchema(true, true);
100
        }
101
    }
102
103
    public function tearDownOnce($class)
104
    {
105
        // @todo: This isn't strictly necessary to restore extensions, but only to ensure that
106
        // Object::$extra_methods is properly flushed. This should be replaced with a simple
107
        // flush mechanism for each $class.
108
        /** @var string|DataObject $dataClass */
109
110
        // Remove extensions added for testing
111
        foreach ($this->extensionsToRemove as $dataClass => $extensions) {
112
            foreach ($extensions as $extension) {
113
                $dataClass::remove_extension($extension);
114
            }
115
        }
116
117
        // Reapply ones removed
118
        foreach ($this->extensionsToReapply as $dataClass => $extensions) {
119
            foreach ($extensions as $extension) {
120
                $dataClass::add_extension($extension);
121
            }
122
        }
123
    }
124
}
125