Completed
Pull Request — master (#106)
by Simon
02:25 queued 32s
created

DataObjectAnnotatorTest::setUp()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 8
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Importance

Changes 2
Bugs 0 Features 0
Metric Value
cc 1
eloc 5
nc 1
nop 0
dl 0
loc 8
rs 9.4285
c 2
b 0
f 0
1
<?php
2
3
namespace SilverLeague\IDEAnnotator\Tests;
4
5
use PageController;
6
use PHPUnit_Framework_TestCase;
7
use RootTeam;
8
use SilverLeague\IDEAnnotator\Annotatable;
9
use SilverLeague\IDEAnnotator\AnnotateClassInfo;
10
use SilverLeague\IDEAnnotator\AnnotatePermissionChecker;
11
use SilverLeague\IDEAnnotator\DataObjectAnnotator;
12
use SilverStripe\Control\Director;
13
use SilverStripe\Core\Config\Config;
14
use SilverStripe\Core\Injector\Injector;
15
use SilverStripe\Dev\SapphireTest;
16
use SilverStripe\ORM\DataObject;
17
18
/**
19
 * Class DataObjectAnnotatorTest
20
 *
21
 * Several tests to make sure the Annotator does it's job correctly
22
 *
23
 * @mixin PHPUnit_Framework_TestCase
24
 */
25
class DataObjectAnnotatorTest extends SapphireTest
26
{
27
28
    /**
29
     * @var MockDataObjectAnnotator
30
     */
31
    private $annotator;
32
33
    /**
34
     * @var AnnotatePermissionChecker $permissionChecker
35
     */
36
    private $permissionChecker;
37
38
    /**
39
     * Setup Defaults
40
     */
41
    protected function setUp()
42
    {
43
        parent::setUp();
44
        Config::modify()->set(DataObjectAnnotator::class, 'enabled', true);
45
        Config::modify()->set(DataObjectAnnotator::class, 'enabled_modules', ['silverleague/ideannotator']);
46
47
        $this->annotator = Injector::inst()->get(MockDataObjectAnnotator::class);
48
        $this->permissionChecker = Injector::inst()->get(AnnotatePermissionChecker::class);
49
    }
50
51
    public function testIsEnabled()
52
    {
53
        $this->assertTrue(DataObjectAnnotator::isEnabled());
54
    }
55
56
    /**
57
     * Test the expected classes show up in the Classes for Module
58
     */
59
    public function testGetClassesForModule()
60
    {
61
        $expectedClasses = [
62
            Team::class                             => Director::baseFolder() . DIRECTORY_SEPARATOR . 'ideannotator' . DIRECTORY_SEPARATOR . 'tests' . DIRECTORY_SEPARATOR . 'mock' . DIRECTORY_SEPARATOR . 'DataObjectAnnotatorTest_Team.php',
63
            TeamChanged::class                      => Director::baseFolder() . DIRECTORY_SEPARATOR . 'ideannotator' . DIRECTORY_SEPARATOR . 'tests' . DIRECTORY_SEPARATOR . 'mock' . DIRECTORY_SEPARATOR . 'DataObjectAnnotatorTest_TeamChanged.php',
64
            TeamComment::class                      => Director::baseFolder() . DIRECTORY_SEPARATOR . 'ideannotator' . DIRECTORY_SEPARATOR . 'tests' . DIRECTORY_SEPARATOR . 'mock' . DIRECTORY_SEPARATOR . 'DataObjectAnnotatorTest_TeamComment.php',
65
            DocBlockMockWithDocBlock::class         => Director::baseFolder() . DIRECTORY_SEPARATOR . 'ideannotator' . DIRECTORY_SEPARATOR . 'tests' . DIRECTORY_SEPARATOR . 'mock' . DIRECTORY_SEPARATOR . 'DocBlockMockWithDocBlock.php',
66
            OtherDocBlockMockWithDocBlock::class    => Director::baseFolder() . DIRECTORY_SEPARATOR . 'ideannotator' . DIRECTORY_SEPARATOR . 'tests' . DIRECTORY_SEPARATOR . 'mock' . DIRECTORY_SEPARATOR . 'DocBlockMockWithDocBlock.php',
67
            DataObjectWithOldStyleTagMarkers::class => Director::baseFolder() . DIRECTORY_SEPARATOR . 'ideannotator' . DIRECTORY_SEPARATOR . 'tests' . DIRECTORY_SEPARATOR . 'mock' . DIRECTORY_SEPARATOR . 'DocBlockMockWithDocBlock.php',
68
            DoubleDataObjectInOneFile1::class       => Director::baseFolder() . DIRECTORY_SEPARATOR . 'ideannotator' . DIRECTORY_SEPARATOR . 'tests' . DIRECTORY_SEPARATOR . 'mock' . DIRECTORY_SEPARATOR . 'DoubleDataObjectInOneFile.php',
69
            DoubleDataObjectInOneFile2::class       => Director::baseFolder() . DIRECTORY_SEPARATOR . 'ideannotator' . DIRECTORY_SEPARATOR . 'tests' . DIRECTORY_SEPARATOR . 'mock' . DIRECTORY_SEPARATOR . 'DoubleDataObjectInOneFile.php',
70
            SubTeam::class                          => Director::baseFolder() . DIRECTORY_SEPARATOR . 'ideannotator' . DIRECTORY_SEPARATOR . 'tests' . DIRECTORY_SEPARATOR . 'mock' . DIRECTORY_SEPARATOR . 'DataObjectAnnotatorTest_SubTeam.php',
71
            Player::class                           => Director::baseFolder() . DIRECTORY_SEPARATOR . 'ideannotator' . DIRECTORY_SEPARATOR . 'tests' . DIRECTORY_SEPARATOR . 'mock' . DIRECTORY_SEPARATOR . 'DataObjectAnnotatorTest_Player.php',
72
            Team_Extension::class                   => Director::baseFolder() . DIRECTORY_SEPARATOR . 'ideannotator' . DIRECTORY_SEPARATOR . 'tests' . DIRECTORY_SEPARATOR . 'mock' . DIRECTORY_SEPARATOR . 'DataObjectAnnotatorTest_Team_Extension.php',
73
            Annotatable::class                      => Director::baseFolder() . DIRECTORY_SEPARATOR . 'ideannotator' . DIRECTORY_SEPARATOR . 'src' . DIRECTORY_SEPARATOR . 'Extensions' . DIRECTORY_SEPARATOR . 'Annotatable.php',
74
            AnnotatorPageTest_Extension::class      => Director::baseFolder() . DIRECTORY_SEPARATOR . 'ideannotator' . DIRECTORY_SEPARATOR . 'tests' . DIRECTORY_SEPARATOR . 'mock' . DIRECTORY_SEPARATOR . 'AnnotatorPageTest.php',
75
            RootTeam::class                         => Director::baseFolder() . DIRECTORY_SEPARATOR . 'ideannotator' . DIRECTORY_SEPARATOR . 'tests' . DIRECTORY_SEPARATOR . 'mock' . DIRECTORY_SEPARATOR . 'RootTeam.php',
76
            AnnotatorPageTest::class                => Director::baseFolder() . DIRECTORY_SEPARATOR . 'ideannotator' . DIRECTORY_SEPARATOR . 'tests' . DIRECTORY_SEPARATOR . 'mock' . DIRECTORY_SEPARATOR . 'AnnotatorPageTest.php',
77
            AnnotatorPageTestController::class      => Director::baseFolder() . DIRECTORY_SEPARATOR . 'ideannotator' . DIRECTORY_SEPARATOR . 'tests' . DIRECTORY_SEPARATOR . 'mock' . DIRECTORY_SEPARATOR . 'AnnotatorPageTest.php',
78
            TeamSupporter::class                    => Director::baseFolder() . DIRECTORY_SEPARATOR . 'ideannotator' . DIRECTORY_SEPARATOR . 'tests' . DIRECTORY_SEPARATOR . 'mock' . DIRECTORY_SEPARATOR . 'TeamsSupporter.php',
79
        ];
80
        $classes = $this->annotator->getClassesForModule('silverleague/ideannotator');
81
82
        $this->assertEquals($expectedClasses, $classes);
83
    }
84
85
86
    /**
87
     * As below, as we don't want to actively change the mocks, so enable mysite
88
     */
89
    public function testAnnotateObject()
90
    {
91
        $this->assertFalse($this->annotator->annotateObject(DataObject::class));
92
93
        Config::modify()->set(DataObjectAnnotator::class, 'enabled_modules', ['ideannotator', 'mysite']);
94
        $this->assertTrue($this->annotator->annotateObject(PageController::class));
95
    }
96
97
    /**
98
     * Not testing existing modules, as it wil actively alter the mock files, so enable mysite
99
     */
100
    public function testAnnotateModule()
101
    {
102
        $noModule = $this->annotator->annotateModule('');
103
        $this->assertFalse($noModule);
104
        $noModule = $this->annotator->annotateModule('mysite');
105
        $this->assertFalse($noModule);
106
        // Enable 'mysite' for testing
107
        Config::modify()->set(DataObjectAnnotator::class, 'enabled_modules', ['ideannotator', 'mysite']);
108
109
        $module = $this->annotator->annotateModule('mysite');
110
        $this->assertTrue($module);
111
    }
112
113
    /**
114
     * Test if the correct annotations are generated
115
     * for all database fields, relations and extensions
116
     * and that the start and end tags are present
117
     */
118
    public function testFileContentWithAnnotations()
119
    {
120
        $classInfo = new AnnotateClassInfo(Team::class);
121
        $filePath = $classInfo->getClassFilePath();
122
123
        $content = $this->annotator->getGeneratedFileContent(file_get_contents($filePath), Team::class);
124
125
        // ClassName title
126
        $this->assertContains(' * Class \SilverLeague\IDEAnnotator\Tests\Team', $content);
127
128
        // database fields
129
        $this->assertContains('@property string $Title', $content);
130
        $this->assertContains('@property int $VisitCount', $content);
131
        $this->assertContains('@property float $Price', $content);
132
133
        // has_one ID
134
        $this->assertContains('@property int $CaptainID', $content);
135
        // has_one relation
136
        $this->assertContains('@method \SilverLeague\IDEAnnotator\Tests\Player Captain()', $content);
137
        // has_many relation
138
        $this->assertContains(
139
            '@method \SilverStripe\ORM\DataList|\SilverLeague\IDEAnnotator\Tests\SubTeam[] SubTeams()',
140
            $content
141
        );
142
        // many_many relation
143
        $this->assertContains(
144
            '@method \SilverStripe\ORM\ManyManyList|\SilverLeague\IDEAnnotator\Tests\Player[] Players()',
145
            $content
146
        );
147
        $this->assertContains(
148
            '@method \SilverStripe\ORM\ManyManyList|\SilverLeague\IDEAnnotator\Tests\Player[] Reserves()',
149
            $content
150
        );
151
        $this->assertContains(
152
            '@method \SilverStripe\ORM\DataList|\SilverLeague\IDEAnnotator\Tests\TeamSupporter[] Supporters()',
153
            $content
154
        );
155
156
        // DataExtension
157
        $this->assertContains('@mixin \SilverLeague\IDEAnnotator\Tests\Team_Extension', $content);
158
    }
159
160
    public function testInversePlayerRelationOfTeam()
161
    {
162
        $classInfo = new AnnotateClassInfo(Player::class);
163
        $filePath = $classInfo->getClassFilePath();
164
165
        $content = $this->annotator->getGeneratedFileContent(file_get_contents($filePath), Player::class);
166
167
        $this->assertContains('@property boolean $IsRetired', $content);
168
        $this->assertContains('@property string $ShirtNumber', $content);
169
        $this->assertContains('@property int $FavouriteTeamID', $content);
170
        $this->assertContains('@method \SilverLeague\IDEAnnotator\Tests\Team FavouriteTeam()', $content);
171
172
        $this->assertContains(
173
            '@method \SilverStripe\ORM\ManyManyList|\SilverLeague\IDEAnnotator\Tests\Team[] TeamPlayer()',
174
            $content
175
        );
176
        $this->assertContains(
177
            '@method \SilverStripe\ORM\ManyManyList|\SilverLeague\IDEAnnotator\Tests\Team[] TeamReserve()',
178
            $content
179
        );
180
    }
181
182
    public function testExistingMethodsWillNotBeTagged()
183
    {
184
        $classInfo = new AnnotateClassInfo(Team::class);
185
        $filePath = $classInfo->getClassFilePath();
186
187
        $content = $this->annotator->getGeneratedFileContent(file_get_contents($filePath), Team::class);
188
        $this->assertNotContains(
189
            '@method \SilverStripe\ORM\ManyManyList|\SilverLeague\IDEAnnotator\Tests\SubTeam[] SecondarySubTeams()',
190
            $content
191
        );
192
    }
193
194
    /**
195
     * Test that multiple annotation runs won't generate ducplicate docblocks
196
     */
197
    public function testNothingHasChangedAfterSecondAnnotation()
198
    {
199
        $classInfo = new AnnotateClassInfo(Team::class);
200
        $filePath = $classInfo->getClassFilePath();
201
        $original = file_get_contents($filePath);
202
        $firstRun = $this->annotator->getGeneratedFileContent($original, Team::class);
203
        $secondRun = $this->annotator->getGeneratedFileContent($firstRun, Team::class);
204
        $this->assertEquals($firstRun, $secondRun);
205
    }
206
207
    /**
208
     * Test that root (non-namespaced) classes get annotated
209
     */
210
    public function testRootAnnotations()
211
    {
212
        $classInfo = new AnnotateClassInfo(RootTeam::class);
213
        $filePath = $classInfo->getClassFilePath();
214
        $run = $this->annotator->getGeneratedFileContent(file_get_contents($filePath), RootTeam::class);
215
        $this->assertContains('@property string $Title', $run);
216
    }
217
218
    /**
219
     * Test the generation of annotations for a DataExtension
220
     */
221
    public function testAnnotateDataExtension()
222
    {
223
        $classInfo = new AnnotateClassInfo(Team_Extension::class);
224
        $filePath = $classInfo->getClassFilePath();
225
        $original = file_get_contents($filePath);
226
        $annotated = $this->annotator->getGeneratedFileContent($original, Team_Extension::class);
227
228
        $this->assertContains(
229
            '@property \SilverLeague\IDEAnnotator\Tests\Team|\SilverLeague\IDEAnnotator\Tests\Team_Extension $owner',
230
            $annotated
231
        );
232
        $this->assertContains('@property string $ExtendedVarcharField', $annotated);
233
        $this->assertContains('@property int $ExtendedIntField', $annotated);
234
        $this->assertContains('@property int $ExtendedHasOneRelationshipID', $annotated);
235
        $this->assertContains(
236
            '@method \SilverLeague\IDEAnnotator\Tests\Player ExtendedHasOneRelationship()',
237
            $annotated
238
        );
239
    }
240
241
    /**
242
     *
243
     */
244
    public function testTwoClassesInOneFile()
245
    {
246
        $classInfo = new AnnotateClassInfo(DoubleDataObjectInOneFile1::class);
247
        $filePath = $classInfo->getClassFilePath();
248
        $original = file_get_contents($filePath);
249
        $annotated = $this->annotator->getGeneratedFileContent($original, DoubleDataObjectInOneFile1::class);
250
251
        $this->assertContains('@property string $Title', $annotated);
252
253
        $annotated = $this->annotator->getGeneratedFileContent($annotated, DoubleDataObjectInOneFile2::class);
254
255
        $this->assertContains('@property string $Name', $annotated);
256
    }
257
258
    public function tearDown()
259
    {
260
        parent::tearDown();
261
    }
262
}
263