Skip to content

Commit 25cc68c

Browse files
Macro::initPhpDoc() will save original docblock if present. (#1116)
* `Macro::initPhpDoc()` will save original docblock if present. * Added `MacroTest::testInitPhpDocClosureWithoutDocBlock()`. * Mock class rename. * Code cleanup.
1 parent 36c4406 commit 25cc68c

File tree

2 files changed

+153
-10
lines changed

2 files changed

+153
-10
lines changed

src/Macro.php

+12-10
Original file line numberDiff line numberDiff line change
@@ -33,23 +33,25 @@ public function __construct(
3333
*/
3434
protected function initPhpDoc($method)
3535
{
36-
$this->phpdoc = new DocBlock('/** */');
36+
$this->phpdoc = new DocBlock($method);
3737

3838
$this->addLocationToPhpDoc();
3939

40-
// Add macro parameters
41-
foreach ($method->getParameters() as $parameter) {
42-
$type = $parameter->hasType() ? $parameter->getType()->getName() : 'mixed';
43-
$type .= $parameter->hasType() && $parameter->getType()->allowsNull() ? '|null' : '';
40+
// Add macro parameters if they are missed in original docblock
41+
if (!$this->phpdoc->hasTag('param')) {
42+
foreach ($method->getParameters() as $parameter) {
43+
$type = $parameter->hasType() ? $parameter->getType()->getName() : 'mixed';
44+
$type .= $parameter->hasType() && $parameter->getType()->allowsNull() ? '|null' : '';
4445

45-
$name = $parameter->isVariadic() ? '...' : '';
46-
$name .= '$' . $parameter->getName();
46+
$name = $parameter->isVariadic() ? '...' : '';
47+
$name .= '$' . $parameter->getName();
4748

48-
$this->phpdoc->appendTag(Tag::createInstance("@param {$type} {$name}"));
49+
$this->phpdoc->appendTag(Tag::createInstance("@param {$type} {$name}"));
50+
}
4951
}
5052

51-
// Add macro return type
52-
if ($method->hasReturnType()) {
53+
// Add macro return type if it missed in original docblock
54+
if ($method->hasReturnType() && !$this->phpdoc->hasTag('return')) {
5355
$builder = EloquentBuilder::class;
5456
$return = $method->getReturnType();
5557

tests/MacroTest.php

+141
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,147 @@ function (): EloquentBuilder {
4646
);
4747
}
4848

49+
/**
50+
* @covers ::initPhpDoc
51+
* @throws \ReflectionException
52+
*/
53+
public function testInitPhpDocClosureWithoutDocBlock(): void
54+
{
55+
$phpdoc = (new MacroMock())->getPhpDoc(
56+
new ReflectionFunction(
57+
function (int $a = null): int {
58+
return 0;
59+
}
60+
)
61+
);
62+
63+
$this->assertNotNull($phpdoc);
64+
$this->assertEmpty($phpdoc->getText());
65+
$this->assertEquals('@param int|null $a', $this->tagsToString($phpdoc, 'param'));
66+
$this->assertEquals('@return int', $this->tagsToString($phpdoc, 'return'));
67+
$this->assertTrue($phpdoc->hasTag('see'));
68+
}
69+
70+
/**
71+
* @covers ::initPhpDoc
72+
* @throws \ReflectionException
73+
*/
74+
public function testInitPhpDocClosureWithArgsAndReturnType(): void
75+
{
76+
$phpdoc = (new MacroMock())->getPhpDoc(
77+
new ReflectionFunction(
78+
/**
79+
* Test docblock.
80+
*/
81+
function (int $a = null): int {
82+
return 0;
83+
}
84+
)
85+
);
86+
87+
$this->assertNotNull($phpdoc);
88+
$this->assertStringContainsString('Test docblock', $phpdoc->getText());
89+
$this->assertEquals('@param int|null $a', $this->tagsToString($phpdoc, 'param'));
90+
$this->assertEquals('@return int', $this->tagsToString($phpdoc, 'return'));
91+
$this->assertTrue($phpdoc->hasTag('see'));
92+
}
93+
94+
/**
95+
* @covers ::initPhpDoc
96+
* @throws \ReflectionException
97+
*/
98+
public function testInitPhpDocClosureWithArgs(): void
99+
{
100+
$phpdoc = (new MacroMock())->getPhpDoc(
101+
new ReflectionFunction(
102+
/**
103+
* Test docblock.
104+
*/
105+
function (int $a = null) {
106+
return 0;
107+
}
108+
)
109+
);
110+
111+
$this->assertNotNull($phpdoc);
112+
$this->assertStringContainsString('Test docblock', $phpdoc->getText());
113+
$this->assertEquals('@param int|null $a', $this->tagsToString($phpdoc, 'param'));
114+
$this->assertFalse($phpdoc->hasTag('return'));
115+
$this->assertTrue($phpdoc->hasTag('see'));
116+
}
117+
118+
/**
119+
* @covers ::initPhpDoc
120+
* @throws \ReflectionException
121+
*/
122+
public function testInitPhpDocClosureWithReturnType(): void
123+
{
124+
$phpdoc = (new MacroMock())->getPhpDoc(
125+
new ReflectionFunction(
126+
/**
127+
* Test docblock.
128+
*/
129+
function (): int {
130+
return 0;
131+
}
132+
)
133+
);
134+
135+
$this->assertNotNull($phpdoc);
136+
$this->assertStringContainsString('Test docblock', $phpdoc->getText());
137+
$this->assertFalse($phpdoc->hasTag('param'));
138+
$this->assertEquals('@return int', $this->tagsToString($phpdoc, 'return'));
139+
$this->assertTrue($phpdoc->hasTag('see'));
140+
}
141+
142+
/**
143+
* @covers ::initPhpDoc
144+
*/
145+
public function testInitPhpDocParamsAddedOnlyNotPresent(): void
146+
{
147+
$phpdoc = (new MacroMock())->getPhpDoc(
148+
new ReflectionFunction(
149+
/**
150+
* Test docblock.
151+
*
152+
* @param \stdClass|null $a aaaaa
153+
*/
154+
function ($a = null): int {
155+
return 0;
156+
}
157+
)
158+
);
159+
160+
$this->assertNotNull($phpdoc);
161+
$this->assertStringContainsString('Test docblock', $phpdoc->getText());
162+
$this->assertEquals('@param \stdClass|null $a aaaaa', $this->tagsToString($phpdoc, 'param'));
163+
$this->assertEquals('@return int', $this->tagsToString($phpdoc, 'return'));
164+
}
165+
166+
/**
167+
* @covers ::initPhpDoc
168+
*/
169+
public function testInitPhpDocReturnAddedOnlyNotPresent(): void
170+
{
171+
$phpdoc = (new MacroMock())->getPhpDoc(
172+
new ReflectionFunction(
173+
/**
174+
* Test docblock.
175+
*
176+
* @return \stdClass|null rrrrrrr
177+
*/
178+
function ($a = null): int {
179+
return 0;
180+
}
181+
)
182+
);
183+
184+
$this->assertNotNull($phpdoc);
185+
$this->assertStringContainsString('Test docblock', $phpdoc->getText());
186+
$this->assertEquals('@param mixed $a', $this->tagsToString($phpdoc, 'param'));
187+
$this->assertEquals('@return \stdClass|null rrrrrrr', $this->tagsToString($phpdoc, 'return'));
188+
}
189+
49190
protected function tagsToString(DocBlock $docBlock, string $name)
50191
{
51192
$tags = $docBlock->getTagsByName($name);

0 commit comments

Comments
 (0)