wiki.techinc.nl/tests/phpunit/integration/includes/StubObjectTest.php
DannyS712 bd73c48744 StubObject: add magic __get() and __set()
We will soon be converting $wgUser to be a stub
object wrapping a User, and we want to be able
to access the public properties of that object
(doing so will still trigger deprecation warnings,
but it won't break). This will also work for
non-existent properties that are handled via
the __get() and __set() methods of whatever
inner object the StubObject is wrapping.

Bug: T267861
Change-Id: I4c29c615bcb107d4ef8bf4b8e48db2ecf863e5f7
2021-09-04 05:37:25 +00:00

214 lines
4.6 KiB
PHP

<?php
/**
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
* http://www.gnu.org/copyleft/gpl.html
*
* @file
*/
/**
* Testing the magic for __get(), __set(), and __call() for our
* example global, $wgDummy, which would be an instance
* of DemoStubbed but is wrapped in a StubObject
* @author DannyS712
*
* @covers \StubObject
*/
class StubObjectTest extends MediaWikiIntegrationTestCase {
/** @var int */
private $oldErrorLevel;
protected function setUp(): void {
parent::setUp();
// Make sure deprecation notices are seen
$this->oldErrorLevel = error_reporting( -1 );
global $wgDummy;
$wgDummy = new StubObject(
'wgDummy',
[ __CLASS__, 'factory' ]
);
}
protected function tearDown(): void {
error_reporting( $this->oldErrorLevel );
parent::tearDown();
}
/**
* Static factory method for creating the underlying global, which is
* a DemoStubbed with the starting value of 5
*
* @return DemoStubbed
*/
public static function factory(): DemoStubbed {
return new DemoStubbed( 5 );
}
public function testCallMagic() {
global $wgDummy;
$this->assertInstanceOf(
StubObject::class,
$wgDummy,
'Global starts as stub object'
);
$this->assertSame(
5,
$wgDummy->getNum(),
'__call() based on id set in ::setUp()'
);
$this->assertInstanceOf(
DemoStubbed::class,
$wgDummy,
'__call() resulted in unstubbing'
);
}
public function testGetMagic() {
// StubObject::__get() returning DemoStubbed::$num
global $wgDummy;
$this->assertInstanceOf(
StubObject::class,
$wgDummy,
'Global starts as stub object'
);
$this->assertSame(
5,
$wgDummy->num,
'__get() based on id set in ::setUp()'
);
$this->assertInstanceOf(
DemoStubbed::class,
$wgDummy,
'__get() resulted in unstubbing'
);
}
public function testGetMagic_virtual() {
// StubObject::__get() calling DemoStubbed::__get()
global $wgDummy;
$this->assertInstanceOf(
StubObject::class,
$wgDummy,
'Global starts as stub object'
);
$this->assertSame(
10,
$wgDummy->doubleNum,
'__get() a virtual property based on id set in ::setUp()'
);
$this->assertInstanceOf(
DemoStubbed::class,
$wgDummy,
'__get() resulted in unstubbing'
);
}
public function testSetMagic() {
// StubObject::__set() changing DemoStubbed::$num
global $wgDummy;
$this->assertInstanceOf(
StubObject::class,
$wgDummy,
'Global starts as stub object'
);
$wgDummy->num = 100;
$this->assertInstanceOf(
DemoStubbed::class,
$wgDummy,
'__set() resulted in unstubbing'
);
$this->assertSame(
100,
$wgDummy->num,
'__set() changed the value'
);
}
public function testSetMagic_virtual() {
// StubObject::__set() calling DemoStubbed::__set()
global $wgDummy;
$this->assertInstanceOf(
StubObject::class,
$wgDummy,
'Global starts as stub object'
);
$wgDummy->doubleNum = 100;
$this->assertInstanceOf(
DemoStubbed::class,
$wgDummy,
'__set() resulted in unstubbing'
);
$this->assertSame(
50,
$wgDummy->num,
'__set() changed the value'
);
}
}
/**
* This is the object that we are stubbing so we can test the various magic methods
*/
class DemoStubbed {
/** @var int */
public $num;
/**
* @param int $num
*/
public function __construct( int $num ) {
$this->num = $num;
}
/**
* @return int
*/
public function getNum(): int {
return $this->num;
}
/**
* Magic handling for retrieving fake property "doubleNum"
*
* @param string $field
* @return mixed
*/
public function __get( $field ) {
if ( $field === 'doubleNum' ) {
return ( 2 * $this->num );
}
trigger_error( 'Inaccessible property via __get(): ' . $field, E_USER_NOTICE );
}
/**
* Magic handling for setting fake property "doubleNum"
*
* @param string $field
* @param mixed $value
*/
public function __set( $field, $value ) {
if ( $field === 'doubleNum' ) {
$this->num = (int)( $value / 2 );
return;
}
trigger_error( 'Inaccessible property via __set(): ' . $field, E_USER_NOTICE );
}
}