Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support for target class attributes #1210

Merged
Merged
Show file tree
Hide file tree
Changes from 9 commits
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
29a6407
Updated `TargetClassInterface` to support `getAttributes`.
ohryan Jan 31, 2023
d2d52b5
Added `getAttributes` which returns `\AllowDynamicProperties` to `Un…
rneudorf-godaddy Jan 31, 2023
fe9e0f7
Added a Pass to write attributes to the mock.
rneudorf-godaddy Jan 31, 2023
45d061a
Updated test which fail with php >= 8.2
rneudorf-godaddy Jan 31, 2023
557776b
Updated test which fail with php >= 8.2
rneudorf-godaddy Jan 31, 2023
b3a04e0
Added test for setting dynamic properties on undefined classes in php…
rneudorf-godaddy Jan 31, 2023
a52260c
Apply style fixes.
rneudorf-godaddy Jan 31, 2023
68b4fc3
Added php-cs-fix 3.x compatible config file
rneudorf-godaddy Feb 1, 2023
de75a3a
Code style updates
rneudorf-godaddy Feb 1, 2023
2055462
Merge branch '1.5.x' into 1209/add-support-for-class-attributes
ghostwriter Apr 21, 2023
d90f674
Update ExpectationTest.php
ghostwriter Apr 21, 2023
7616b6d
Update ClassAttributesPassTest.php
ghostwriter Apr 21, 2023
6b8741a
Update ExpectationTest.php
ghostwriter Apr 21, 2023
2325237
Update UndefinedTargetClass.php
ghostwriter Apr 21, 2023
503977f
Update DefinedTargetClass.php
ghostwriter Apr 21, 2023
d8f0815
Update psalm-baseline.xml
ghostwriter Apr 21, 2023
cd39c18
Update psalm.xml.dist
ghostwriter Apr 21, 2023
d2c322c
Update psalm-baseline.xml
ghostwriter Apr 21, 2023
4eda05e
Fix CS issue
ghostwriter Apr 21, 2023
0f8a16e
Add Psalm issue handlers
ghostwriter Apr 21, 2023
da56087
Review PR
ghostwriter Apr 21, 2023
d9ad5a1
Fix CS issue
ghostwriter Apr 21, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
31 changes: 31 additions & 0 deletions .php-cs-fixer.dist.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
<?php

use Symfony\CS\Config\Config;
use Symfony\CS\Finder\DefaultFinder;

if (class_exists('PhpCsFixer\Finder')) { // PHP-CS-Fixer 2.x
$finder = PhpCsFixer\Finder::create()->in([
'library',
'tests',
]);


return (new PhpCsFixer\Config())
->setRules(array(
'@PSR2' => true,
))
->setUsingCache(true)
->setFinder($finder)
;
}

$finder = DefaultFinder::create()->in(
[
'library',
'tests',
]);

return Config::create()
->level('psr2')
->setUsingCache(true)
->finder($finder);
5 changes: 5 additions & 0 deletions library/Mockery/Generator/DefinedTargetClass.php
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,11 @@ public static function factory($name, $alias = null)
return new self(new \ReflectionClass($name), $alias);
}

public function getAttributes()
{
return [];
ghostwriter marked this conversation as resolved.
Show resolved Hide resolved
}

public function getName()
{
return $this->name;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
<?php

namespace Mockery\Generator\StringManipulation\Pass;

use Mockery\Generator\MockConfiguration;

class ClassAttributesPass implements Pass
{
public function apply($code, MockConfiguration $config)
{
$class = $config->getTargetClass();

if (!$class) {
return $code;
}

$attributes = $class->getAttributes();

if (!empty($attributes)) {
$attributes = '#[' . implode(',', $attributes) . ']';
ghostwriter marked this conversation as resolved.
Show resolved Hide resolved

return str_replace(
'class Mock',
$attributes . ' class Mock',
$code
);
}

return $code;
}
}
2 changes: 2 additions & 0 deletions library/Mockery/Generator/StringManipulationGenerator.php
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@
use Mockery\Generator\StringManipulation\Pass\RemoveUnserializeForInternalSerializableClassesPass;
use Mockery\Generator\StringManipulation\Pass\TraitPass;
use Mockery\Generator\StringManipulation\Pass\AvoidMethodClashPass;
use Mockery\Generator\StringManipulation\Pass\ClassAttributesPass;

class StringManipulationGenerator implements Generator
{
Expand All @@ -60,6 +61,7 @@ public static function withDefaultPasses()
new RemoveBuiltinMethodsThatAreFinalPass(),
new RemoveDestructorPass(),
new ConstantsPass(),
new ClassAttributesPass(),
]);
}

Expand Down
8 changes: 8 additions & 0 deletions library/Mockery/Generator/TargetClassInterface.php
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,14 @@ interface TargetClassInterface
*/
public static function factory($name);


/**
* Returns the targetClass's attributes.
*
* @return array
*/
public function getAttributes();

/**
* Returns the targetClass's name.
*
Expand Down
5 changes: 5 additions & 0 deletions library/Mockery/Generator/UndefinedTargetClass.php
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,11 @@ public static function factory($name)
return new self($name);
}

public function getAttributes()
{
return ['\AllowDynamicProperties'];
}

public function getName()
{
return $this->name;
Expand Down
7 changes: 7 additions & 0 deletions phpunit.xml.dist
Original file line number Diff line number Diff line change
Expand Up @@ -12,15 +12,22 @@
<directory suffix="Test.php">./tests</directory>
<exclude>./tests/PHP80</exclude>
<exclude>./tests/PHP81</exclude>
<exclude>./tests/PHP82</exclude>
</testsuite>

<testsuite name="Mockery Test Suite PHP80">
<directory phpVersion="8.0.0-dev" phpVersionOperator=">=">./tests</directory>
<exclude>./tests/PHP81</exclude>
<exclude>./tests/PHP82</exclude>
</testsuite>

<testsuite name="Mockery Test Suite PHP81">
<directory phpVersion="8.1.0-dev" phpVersionOperator=">=">./tests</directory>
<exclude>./tests/PHP82</exclude>
</testsuite>

<testsuite name="Mockery Test Suite PHP82">
<directory phpVersion="8.2.0-dev" phpVersionOperator=">=">./tests</directory>
</testsuite>
</testsuites>

Expand Down
2 changes: 2 additions & 0 deletions tests/Mockery/ContainerTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -1506,6 +1506,7 @@ public function __unset($property)
}
}

#[\AllowDynamicProperties]
class MockeryTestFoo
{
public function foo()
Expand All @@ -1514,6 +1515,7 @@ public function foo()
}
}

#[\AllowDynamicProperties]
class MockeryTestFoo2
{
public function foo()
Expand Down
3 changes: 2 additions & 1 deletion tests/Mockery/ExpectationTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ class ExpectationTest extends MockeryTestCase
public function mockeryTestSetUp()
{
parent::mockeryTestSetUp();
$this->mock = mock();
$this->mock = mock('Foo');
ghostwriter marked this conversation as resolved.
Show resolved Hide resolved
}

public function mockeryTestTearDown()
Expand Down Expand Up @@ -2246,6 +2246,7 @@ public function doitWithArgs()
}
}

#[\AllowDynamicProperties]
class MockeryTest_Foo
{
public function foo()
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
<?php

namespace test\Mockery\Generator\StringManipulation\Pass;

use Generator;
use Mockery;
use Mockery\Adapter\Phpunit\MockeryTestCase;
use Mockery\Generator\MockConfiguration;
use Mockery\Generator\StringManipulation\Pass\ClassAttributesPass;
use Mockery\Generator\UndefinedTargetClass;

class ClassAttributesPassTest extends MockeryTestCase
{
const CODE = "namespace Mockery; class Mock {}";

/**
* @dataProvider providerCanApplyClassAttributes
*
* @param array $attributes
* @param string $expected
* @return void
*/
public function testCanApplyClassAttributes(
array $attributes,
string $expected
): void {
$undefinedTargetClass = $this->createPartialMock(UndefinedTargetClass::class, ['getAttributes']);
$undefinedTargetClass->expects($this->once())
->method('getAttributes')
->willReturn($attributes);

$config = $this->createPartialMock(MockConfiguration::class, ['getTargetClass']);
$config->expects($this->once())
->method('getTargetClass')
->willReturn($undefinedTargetClass);

$pass = new ClassAttributesPass();

$code = $pass->apply(static::CODE, $config);

$this->assertTrue(\mb_strpos($code, $expected) !== false);
}

/** @see testCanApplyClassAttributes */
public function providerCanApplyClassAttributes(): Generator
{
yield 'has no attributes' => [
'attributes' => [],
'expected' => '',
];

yield 'has one attribute' => [
'attributes' => [
'Attribute1'
],
'expected' => '#[Attribute1]',
];

yield 'has attributes' => [
'attributes' => [
'Attribute1',
'Attribute2',
'Attribute3()'
],
'expected' => '#[Attribute1,Attribute2,Attribute3()]',
];
}
}
17 changes: 17 additions & 0 deletions tests/PHP82/Php82LanguageFeaturesTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
<?php

namespace test\PHP82;

use Mockery\Adapter\Phpunit\MockeryTestCase;

class Php82LanguageFeaturesTest extends MockeryTestCase
{
public function testCanMockUndefinedClasses()
{
$class = mock('UndefinedClass');

$class->foo = 'bar';

$this->assertSame('bar', $class->foo);
}
}