Completed
Push — master ( ec1aed...07def2 )
by Robbie
13s
created

DataObjectAnnotatorTest::testAnnotateObject()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 6
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 3
nc 1
nop 0
dl 0
loc 6
rs 9.4285
c 0
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 View Code Duplication
    protected function setUp()
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
42
    {
43
        parent::setUp();
44
        Config::modify()->set(DataObjectAnnotator::class, 'enabled', true);
45
        Config::modify()->set(DataObjectAnnotator::class, 'enabled_modules', ['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
        ];
79
        $classes = $this->annotator->getClassesForModule('ideannotator');
80
81
        $this->assertEquals($expectedClasses, $classes);
82
    }
83
84
85
    /**
86
     * As below, as we don't want to actively change the mocks, so enable mysite
87
     */
88
    public function testAnnotateObject()
89
    {
90
        $this->assertFalse($this->annotator->annotateObject(DataObject::class));
91
92
        Config::modify()->set(DataObjectAnnotator::class, 'enabled_modules', ['ideannotator', 'mysite']);
93
        $this->assertTrue($this->annotator->annotateObject(PageController::class));
94
    }
95
96
    /**
97
     * Not testing existing modules, as it wil actively alter the mock files, so enable mysite
98
     */
99
    public function testAnnotateModule()
100
    {
101
        $noModule = $this->annotator->annotateModule('');
102
        $this->assertFalse($noModule);
103
        $noModule = $this->annotator->annotateModule('mysite');
104
        $this->assertFalse($noModule);
105
        // Enable 'mysite' for testing
106
        Config::modify()->set(DataObjectAnnotator::class, 'enabled_modules', ['ideannotator', 'mysite']);
107
108
        $module = $this->annotator->annotateModule('mysite');
109
        $this->assertTrue($module);
110
    }
111
112
    /**
113
     * Test if the correct annotations are generated
114
     * for all database fields, relations and extensions
115
     * and that the start and end tags are present
116
     */
117
    public function testFileContentWithAnnotations()
118
    {
119
        $classInfo = new AnnotateClassInfo(Team::class);
120
        $filePath = $classInfo->getClassFilePath();
121
122
        $content = $this->annotator->getGeneratedFileContent(file_get_contents($filePath), Team::class);
123
124
        // ClassName title
125
        $this->assertContains(' * Class \SilverLeague\IDEAnnotator\Tests\Team', $content);
126
127
        // database fields
128
        $this->assertContains('@property string $Title', $content);
129
        $this->assertContains('@property int $VisitCount', $content);
130
        $this->assertContains('@property float $Price', $content);
131
132
        // has_one ID
133
        $this->assertContains('@property int $CaptainID', $content);
134
        // has_one relation
135
        $this->assertContains('@method \SilverLeague\IDEAnnotator\Tests\Player Captain()', $content);
136
        // has_many relation
137
        $this->assertContains(
138
            '@method \SilverStripe\ORM\DataList|\SilverLeague\IDEAnnotator\Tests\SubTeam[] SubTeams()',
139
            $content
140
        );
141
        // many_many relation
142
        $this->assertContains(
143
            '@method \SilverStripe\ORM\ManyManyList|\SilverLeague\IDEAnnotator\Tests\Player[] Players()',
144
            $content
145
        );
146
        $this->assertContains(
147
            '@method \SilverStripe\ORM\ManyManyList|\SilverLeague\IDEAnnotator\Tests\Player[] Reserves()',
148
            $content
149
        );
150
151
        // DataExtension
152
        $this->assertContains('@mixin \SilverLeague\IDEAnnotator\Tests\Team_Extension', $content);
153
    }
154
155 View Code Duplication
    public function testInversePlayerRelationOfTeam()
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
156
    {
157
        $classInfo = new AnnotateClassInfo(Player::class);
158
        $filePath = $classInfo->getClassFilePath();
159
160
        $content = $this->annotator->getGeneratedFileContent(file_get_contents($filePath), Player::class);
161
162
        $this->assertContains('@property boolean $IsRetired', $content);
163
        $this->assertContains('@property string $ShirtNumber', $content);
164
        $this->assertContains('@property int $FavouriteTeamID', $content);
165
        $this->assertContains('@method \SilverLeague\IDEAnnotator\Tests\Team FavouriteTeam()', $content);
166
167
        $this->assertContains(
168
            '@method \SilverStripe\ORM\ManyManyList|\SilverLeague\IDEAnnotator\Tests\Team[] TeamPlayer()',
169
            $content
170
        );
171
        $this->assertContains(
172
            '@method \SilverStripe\ORM\ManyManyList|\SilverLeague\IDEAnnotator\Tests\Team[] TeamReserve()',
173
            $content
174
        );
175
    }
176
177
    public function testExistingMethodsWillNotBeTagged()
178
    {
179
        $classInfo = new AnnotateClassInfo(Team::class);
180
        $filePath = $classInfo->getClassFilePath();
181
182
        $content = $this->annotator->getGeneratedFileContent(file_get_contents($filePath), Team::class);
183
        $this->assertNotContains(
184
            '@method \SilverStripe\ORM\ManyManyList|\SilverLeague\IDEAnnotator\Tests\SubTeam[] SecondarySubTeams()',
185
            $content
186
        );
187
    }
188
189
    /**
190
     * Test that multiple annotation runs won't generate ducplicate docblocks
191
     */
192 View Code Duplication
    public function testNothingHasChangedAfterSecondAnnotation()
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
193
    {
194
        $classInfo = new AnnotateClassInfo(Team::class);
195
        $filePath = $classInfo->getClassFilePath();
196
        $original = file_get_contents($filePath);
197
        $firstRun = $this->annotator->getGeneratedFileContent($original, Team::class);
198
        $secondRun = $this->annotator->getGeneratedFileContent($firstRun, Team::class);
199
        $this->assertEquals($firstRun, $secondRun);
200
    }
201
202
    /**
203
     * Test that root (non-namespaced) classes get annotated
204
     */
205 View Code Duplication
    public function testRootAnnotations()
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
206
    {
207
        $classInfo = new AnnotateClassInfo(RootTeam::class);
208
        $filePath = $classInfo->getClassFilePath();
209
        $run = $this->annotator->getGeneratedFileContent(file_get_contents($filePath), RootTeam::class);
210
        $this->assertContains('@property string $Title', $run);
211
    }
212
213
    /**
214
     * Test the generation of annotations for a DataExtension
215
     */
216 View Code Duplication
    public function testAnnotateDataExtension()
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
217
    {
218
        $classInfo = new AnnotateClassInfo(Team_Extension::class);
219
        $filePath = $classInfo->getClassFilePath();
220
        $original = file_get_contents($filePath);
221
        $annotated = $this->annotator->getGeneratedFileContent($original, Team_Extension::class);
222
223
        $this->assertContains(
224
            '@property \SilverLeague\IDEAnnotator\Tests\Team|\SilverLeague\IDEAnnotator\Tests\Team_Extension $owner',
225
            $annotated
226
        );
227
        $this->assertContains('@property string $ExtendedVarcharField', $annotated);
228
        $this->assertContains('@property int $ExtendedIntField', $annotated);
229
        $this->assertContains('@property int $ExtendedHasOneRelationshipID', $annotated);
230
        $this->assertContains(
231
            '@method \SilverLeague\IDEAnnotator\Tests\Player ExtendedHasOneRelationship()',
232
            $annotated
233
        );
234
    }
235
236
    /**
237
     *
238
     */
239 View Code Duplication
    public function testTwoClassesInOneFile()
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
240
    {
241
        $classInfo = new AnnotateClassInfo(DoubleDataObjectInOneFile1::class);
242
        $filePath = $classInfo->getClassFilePath();
243
        $original = file_get_contents($filePath);
244
        $annotated = $this->annotator->getGeneratedFileContent($original, DoubleDataObjectInOneFile1::class);
245
246
        $this->assertContains('@property string $Title', $annotated);
247
248
        $annotated = $this->annotator->getGeneratedFileContent($annotated, DoubleDataObjectInOneFile2::class);
249
250
        $this->assertContains('@property string $Name', $annotated);
251
    }
252
253
    public function tearDown()
254
    {
255
        parent::tearDown();
256
    }
257
}
258