Skip to content

Commit 690881b

Browse files
authored
Merge pull request #38 from facile-it/hotfix/properties-stub
Fix property stubs
2 parents 32fd8dc + 02233ec commit 690881b

21 files changed

+460
-130
lines changed

README.md

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -186,6 +186,22 @@ Moka::prophecy(FooInterface::class)
186186
->willReturn($something);
187187
```
188188

189+
**Warning:** this workaround cannot be used with methods having the same name as a previously stubbed property:
190+
191+
```php
192+
Moka::prophecy(FooInterface::class, 'foo')->stub([
193+
'$someName' => true
194+
]);
195+
196+
var_dump(Moka::prophecy('foo')->someName);
197+
// bool(true)
198+
199+
Moka::prophecy('foo')
200+
->someName->set(new AnyValuesToken())
201+
->willReturn($something);
202+
// throws \Exception
203+
```
204+
189205
## Plugin development
190206

191207
If you feel a genius and want to create your own mock generator (or add support for an existing one), just implement `Moka\Plugin\PluginInterface` and the relative `Moka\Strategy\MockingStrategyInterface`:

src/Moka/Factory/StubFactory.php

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
use Moka\Exception\InvalidArgumentException;
77
use Moka\Stub\MethodStub;
88
use Moka\Stub\PropertyStub;
9+
use Moka\Stub\StubHelper;
910
use Moka\Stub\StubInterface;
1011
use Moka\Stub\StubSet;
1112

@@ -26,7 +27,7 @@ public static function fromArray(array $namesWithValues): StubSet
2627
$stubSet = new StubSet();
2728
foreach ($namesWithValues as $name => $value) {
2829
try {
29-
$stub = StubInterface::PREFIX_PROPERTY === $name[0]
30+
$stub = StubHelper::isPropertyName($name)
3031
? new PropertyStub($name, $value)
3132
: new MethodStub($name, $value);
3233

src/Moka/Generator/Template/ClassTemplate.php

Lines changed: 5 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
*/
1313
class ClassTemplate implements TemplateInterface
1414
{
15-
const UNSAFE_METHODS = ['__construct', '__destruct', '__call', '__clone'];
15+
const UNSAFE_METHODS = ['__construct', '__destruct', '__call', '__get', '__clone'];
1616

1717
const TEMPLATE_FQCN = 'Moka_%s_%s';
1818

@@ -28,8 +28,6 @@ public function __construct()
2828
%s
2929
}
3030
31-
%s
32-
3331
public function __call(%s $name, %s $arguments)
3432
{
3533
return $this->doCall($name, $arguments);
@@ -39,6 +37,8 @@ public function __get(%s $name)
3937
{
4038
return $this->doGet($name);
4139
}
40+
41+
%s
4242
};
4343
4444
return "%s";
@@ -66,20 +66,16 @@ protected static function doGenerate(\ReflectionClass $class): string
6666

6767
$methods = $class->getMethods(\ReflectionMethod::IS_PUBLIC);
6868
$methodsCode = [];
69-
$methodNames = array_map(function (\ReflectionMethod $method) {
70-
return $method->name;
71-
}, $methods);
7269

7370
$callParametersTypes = array_fill(0, 2, '');
7471
$getNameType = '';
7572

7673
foreach ($properties as $property) {
77-
if (!in_array($property->name, $methodNames)) {
74+
if ($property->isStatic()) {
7875
continue;
7976
}
8077

8178
$propertiesCode[] = PropertyTemplate::generate($property);
82-
8379
$constructorCode[] = PropertyInitializationTemplate::generate($property);
8480
}
8581

@@ -120,10 +116,10 @@ protected static function doGenerate(\ReflectionClass $class): string
120116
ProxyTrait::class,
121117
implode(PHP_EOL, $propertiesCode),
122118
implode(PHP_EOL, $constructorCode),
123-
implode(PHP_EOL, $methodsCode),
124119
$callNameType ?: '',
125120
$callArgumentsType ?: '',
126121
$getNameType,
122+
implode(PHP_EOL, $methodsCode),
127123
$proxyClassName
128124
);
129125
}

src/Moka/Generator/Template/PropertyInitializationTemplate.php

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,9 +10,7 @@
1010
class PropertyInitializationTemplate implements TemplateInterface
1111
{
1212
const TEMPLATE = '
13-
%s%s = function () {
14-
return $this->doGet("%s");
15-
};
13+
unset(%s%s);
1614
';
1715

1816
/**

src/Moka/Plugin/Phake/Matcher/FirstStubMatcher.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,7 @@ public function doArgumentsMatch(array &$arguments)
7373
*/
7474
public function __toString()
7575
{
76-
return '';
76+
return get_class($this);
7777
}
7878

7979
/**

src/Moka/Plugin/Prophecy/Token/AbstractPriorityToken.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,6 @@ public function isLast()
5858
*/
5959
public function __toString()
6060
{
61-
return '';
61+
return get_class($this);
6262
}
6363
}

src/Moka/Proxy/ProxyInterface.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,11 +14,11 @@
1414
interface ProxyInterface
1515
{
1616
/**
17-
* @param array $methodsWithValues
17+
* @param array $namesWithValues
1818
* @return ProxyInterface
1919
*
2020
* @throws InvalidArgumentException
2121
* @throws MockNotCreatedException
2222
*/
23-
public function stub(array $methodsWithValues): ProxyInterface;
23+
public function stub(array $namesWithValues): ProxyInterface;
2424
}

src/Moka/Proxy/ProxyTrait.php

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
use Moka\Exception\InvalidArgumentException;
77
use Moka\Exception\MockNotCreatedException;
88
use Moka\Strategy\MockingStrategyInterface;
9+
use Moka\Stub\StubHelper;
910

1011
/**
1112
* Trait ProxyTrait
@@ -23,6 +24,16 @@ trait ProxyTrait
2324
*/
2425
private $__moka_mockingStrategy;
2526

27+
/**
28+
* @var array
29+
*/
30+
private $__moka_properties = [];
31+
32+
/**
33+
* @var array
34+
*/
35+
private $__moka_methods = [];
36+
2637
/**
2738
* @return object
2839
*/
@@ -62,6 +73,16 @@ public function __moka_setMockingStrategy(MockingStrategyInterface $mockingStrat
6273
*/
6374
public function stub(array $namesWithValues): ProxyInterface
6475
{
76+
foreach ($namesWithValues as $name => $value) {
77+
if (StubHelper::isPropertyName($name)) {
78+
$this->__moka_properties[] = StubHelper::stripName($name);
79+
}
80+
81+
if (StubHelper::isMethodName($name)) {
82+
$this->__moka_methods[] = StubHelper::stripName($name);
83+
}
84+
}
85+
6586
/** @var $this ProxyInterface */
6687
$this->__moka_mockingStrategy->decorate($this->__moka_mock, $namesWithValues);
6788

@@ -94,6 +115,10 @@ protected function doGet(string $name)
94115
return null;
95116
}
96117

118+
if (in_array($name, $this->__moka_properties)) {
119+
return $this->__moka_mockingStrategy->get($this->__moka_mock)->$name;
120+
}
121+
97122
return $this->__moka_mockingStrategy->call($this->__moka_mock, $name);
98123
}
99124
}

src/Moka/Stub/AbstractStub.php

Lines changed: 1 addition & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,6 @@
1111
*/
1212
abstract class AbstractStub implements StubInterface
1313
{
14-
const REGEX_NAME = '/^[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*$/';
15-
1614
/**
1715
* @var string
1816
*/
@@ -32,16 +30,7 @@ abstract class AbstractStub implements StubInterface
3230
*/
3331
public function __construct(string $name, $value)
3432
{
35-
if (!preg_match(self::REGEX_NAME, $name)) {
36-
throw new InvalidArgumentException(
37-
sprintf(
38-
'Name must be a valid variable or method name, "%s" given',
39-
$name
40-
)
41-
);
42-
}
43-
44-
$this->name = $name;
33+
$this->name = StubHelper::stripName($name);
4534
$this->value = $value;
4635
}
4736

src/Moka/Stub/MethodStub.php

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,25 @@
33

44
namespace Moka\Stub;
55

6+
use Moka\Exception\InvalidArgumentException;
7+
68
/**
79
* Class MethodStub
810
* @package Moka\Stub
911
*/
1012
class MethodStub extends AbstractStub
1113
{
14+
/**
15+
* MethodStub constructor.
16+
* @param string $name
17+
* @param mixed $value
18+
*
19+
* @throws InvalidArgumentException
20+
*/
21+
public function __construct(string $name, $value)
22+
{
23+
StubHelper::validateMethodName($name);
24+
25+
parent::__construct($name, $value);
26+
}
1227
}

0 commit comments

Comments
 (0)