Skip to content

Commit

Permalink
Starts fixing halfpastfouram#32.
Browse files Browse the repository at this point in the history
Adds some assertArraySubset due to recursive retrieval of fields.
  • Loading branch information
gbonnema committed Dec 29, 2016
1 parent e2db8fa commit de02d1a
Show file tree
Hide file tree
Showing 9 changed files with 244 additions and 55 deletions.
2 changes: 1 addition & 1 deletion src/ChartOwned.php
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ public function setOwner( ChartInterface $chart )
/**
* @return ChartInterface
*/
public function getOwner()
public function owner()
{
return $this->owner;
}
Expand Down
2 changes: 1 addition & 1 deletion src/ChartOwnedInterface.php
Original file line number Diff line number Diff line change
Expand Up @@ -18,5 +18,5 @@ public function setOwner( ChartInterface $chart );
/**
* @return ChartInterface
*/
public function getOwner();
public function owner();
}
58 changes: 29 additions & 29 deletions src/Delegate/ArraySerializable.php
Original file line number Diff line number Diff line change
Expand Up @@ -17,37 +17,37 @@ public function getArrayCopy()
{
$data = [];

$properties = get_class_vars( self::class );
$reflectionClass = new \Zend_Reflection_Class( $this );
foreach( $properties as $property => $value ) {
// Skip property if it is not accessible
if( !$reflectionClass->hasProperty( $property ) ) continue;

// Only process properties that aren't null
if( !is_null( $this->$property ) ) {
// Gather phpdoc from property
$phpDoc = $reflectionClass->getProperty( $property )->getDocComment();
$type = $phpDoc->getTag( 'var' )->getDescription();
$object = false;

// Prepend 'get' to the getter method.
$getter = 'get' . ucfirst( $property );
// We want the classes from top to bottom
// So that subclass attributes will overwrite superclass attributes
// with the same name
$hierarchy = [];
$reflectionClass = new \ReflectionClass( $this );
while ($reflectionClass) {
array_push($hierarchy, $reflectionClass);
$reflectionClass = $reflectionClass->getParentClass();
}

// Determine whether the getter method is equal to the property name or is prepended by 'is' or 'get'
if( strcmp( $type, 'bool' ) === 0 || strcmp( $type, 'boolean' ) === 0 ) {
// Prepend 'is' to the getter method
$getter = 'is' . ucfirst( $property );
} else if ( method_exists( $this, $property ) && is_object( $this->$property ) ) {
// The getter method is equal to the property name and the value is an actual object
$getter = $property;
$object = true;
/**
* Fill the array with attributes and values, for each level in the hierarchy
* dropping to the most specialized subclass.
*/
foreach($hierarchy as $reflectionClass) {
$reflectionProperties = $reflectionClass->getProperties();
/** @var \Zend_Reflection_Property $reflectionProperty */
foreach($reflectionProperties as $reflectionProperty) {
$property = $reflectionProperty->getName();
$phpDoc = $reflectionProperty->getDocComment();
$phpDocClass = new \Zend_Reflection_Docblock($phpDoc);
$tag = $phpDocClass->getTag('var');
$type = $tag->getDescription();
$getter = strcmp($type, 'bool') === 0 || strcmp($type, 'boolean') === 0 ?
'is' . ucfirst($property) : 'get' . ucfirst($property);
// Only if the method exists
if (method_exists( $this, $getter )) {
// Assign the contents of the property to the data array
$data[ $property ] =
is_object($this->$getter()) ? $this->$getter()->getArrayCopy() : $this->$getter();
}

// Abort if the method does not exist
if( !method_exists( $this, $getter ) ) continue;

// Assign the contents of the property to the data array
$data[ $property ] = $object ? $this->$getter()->getArrayCopy() : $this->$getter();
}
}

Expand Down
21 changes: 10 additions & 11 deletions test/unit/DataSetTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@
use Halfpastfour\PHPChartJS\ChartOwnedInterface;
use Halfpastfour\PHPChartJS\Collection\Data;
use Halfpastfour\PHPChartJS\DataSet;
use Zend\Json\Json;

require_once __DIR__ . '/../../vendor/autoload.php';

Expand Down Expand Up @@ -41,14 +40,14 @@ public function testOwner()
{
$dataSet = new DataSet();

$this->assertNull( $dataSet->getOwner(), 'The dataset has no owner' );
$this->assertNull( $dataSet->owner(), 'The dataset has no owner' );

$chart = new Bar();
$chart->addDataSet( $dataSet );

$this->assertEquals( $chart, $dataSet->getOwner(), 'The owner of the dataSet is set and returned correctly' );
$this->assertEquals( $chart, $dataSet->owner(), 'The owner of the dataSet is set and returned correctly' );
$this->assertInstanceOf(
ChartInterface::class, $dataSet->getOwner(),
ChartInterface::class, $dataSet->owner(),
'The owner of the dataSet implements the correct interface'
);
}
Expand Down Expand Up @@ -194,20 +193,20 @@ public function testAxes()

$this->assertInstanceOf( DataSet::class, $dataSet->setXAxisID( 'myXAxis' ) );
$this->assertEquals( 'myXAxis', $dataSet->getXAxisID(), 'The correct value is returned' );
$this->assertEquals( [ 'xAxisID' => 'myXAxis' ], $dataSet->getArrayCopy() );
$this->assertEquals(
Json::encode( [ 'xAxisID' => 'myXAxis' ] ), $dataSet->jsonSerialize(), 'The serialized data is correct'
$this->assertArraySubset( [ 'xAxisID' => 'myXAxis' ], $dataSet->getArrayCopy() );
$this->assertArraySubset(
[ 'xAxisID' => 'myXAxis' ] , json_decode($dataSet->jsonSerialize(), true), 'Serialized data is not correct'
);

$this->assertNull( $dataSet->getYAxisID(), 'The yAxisID value is not set' );

$this->assertInstanceOf( DataSet::class, $dataSet->setYAxisID( 'myYAxis' ) );
$this->assertEquals( 'myYAxis', $dataSet->getYAxisID(), 'The correct value is returned' );
$this->assertEquals(
Json::encode( [
$this->assertEquals( 'myYAxis', $dataSet->getYAxisID(), 'The correct value is not returned' );
$this->assertArraySubset(
[
'xAxisID' => 'myXAxis',
'yAxisID' => 'myYAxis'
] ), $dataSet->jsonSerialize(), 'The serialized data is correct'
], json_decode($dataSet->jsonSerialize(), true), 'The serialized data is not correct'
);
}

Expand Down
184 changes: 184 additions & 0 deletions test/unit/Delegate/ArraySerializableTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,184 @@
<?php

namespace Test\Delegate;

require_once __DIR__ . '/../../../vendor/autoload.php';

use Halfpastfour\PHPChartJS\Delegate\ArraySerializable;


/**
* Class ArraySerializableTest
* @package Test\Delegate
*/
class ArraySerializableTest extends \PHPUnit_Framework_TestCase
{
/**
* @var A
*/
private $classA;

/**
* @var B
*/
private $classB;

/**
*
*/
public function setUp() {
$this->classA = new A(1, 2);
$this->classB = new B(3, 4, 5, 6);
}

/**
*
*/
public function testSuperclass() {
$expected = ['a' => 1, 'b' => 2];
ksort($expected);
$result = $this->classA->getArrayCopy();
ksort($result);
self::assertSame($expected, $result);
}

/**
*
*/
public function testSubclass() {
$expected = ['a' => 3, 'b' => 4, 'c' => 5, 'd' => 6];
ksort($expected);
$result = $this->classB->getArrayCopy();
ksort($result);
self::assertSame($expected, $result);
}

}

/**
* Class A
* @package Delegate
*/
class A
{
use ArraySerializable;

/**
* @var int
*/
private $a;

/**
* @var int
*/
private $b;

/**
* A constructor.
*
* @param $a int
* @param $b int
*/
public function __construct( $a, $b)
{
$this->a = $a;
$this->b = $b;
}

/**
* @return int
*/
public function getA()
{
return $this->a;
}

/**
* @param int $a
*/
public function setA( $a )
{
$this->a = $a;
}

/**
* @return int
*/
public function getB()
{
return $this->b;
}

/**
* @param int $b
*/
public function setB( $b )
{
$this->b = $b;
}

}

/**
* Class B
* @package Delegate
*/
class B extends A
{
/**
* @var int
*/
private $c;

/**
* @var int
*/
private $d;

/**
* B constructor.
*
* @param $a int
* @param $b int
* @param $c int
* @param $d int
*/
public function __construct( $a, $b, $c, $d )
{
parent::__construct( $a, $b );
$this->c = $c;
$this->d = $d;
}

/**
* @return int
*/
public function getC()
{
return $this->c;
}

/**
* @param int $c
*/
public function setC( $c )
{
$this->c = $c;
}

/**
* @return int
*/
public function getD()
{
return $this->d;
}

/**
* @param int $d
*/
public function setD( $d )
{
$this->d = $d;
}
}
2 changes: 1 addition & 1 deletion test/unit/Options/Layout/PaddingTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,6 @@ public function testJsonSerialize()
{
$this->padding->setTop( 20 );
$result = json_decode( $this->padding->jsonSerialize(), true );
self::assertSame( [ 'top' => 20 ], $result );
self::assertArraySubset( [ 'top' => 20 ], $result );
}
}
9 changes: 6 additions & 3 deletions test/unit/Options/Legend/LabelsTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,8 @@ class LabelsTest extends \PHPUnit_Framework_TestCase
'usePointStyle' => true,
];

private $scratch_input_data_1 = [];

/**
* @var array
*/
Expand Down Expand Up @@ -123,13 +125,14 @@ public function testExpr()
*/
public function testJsonSerializeWithoutExpr()
{
array_walk( $this->input_data_1, function($value, $key) {
$this->scratch_input_data_1 = $this->input_data_1;
array_walk( $this->scratch_input_data_1, function($value, $key) {
if (is_null($value)) {
unset($this->input_data_1[$key]);
unset($this->scratch_input_data_1[$key]);
}
});
$expected = $this->input_data_1;
TestUtils::setAttributes( $this->labels, $this->input_data_1 );
TestUtils::setAttributes( $this->labels, $this->scratch_input_data_1 );
$result = json_decode( $this->labels->jsonSerialize(), true );
self::assertEquals( $expected, $result );
}
Expand Down
9 changes: 6 additions & 3 deletions test/unit/Options/Scales/TicksTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,8 @@ class TicksTest extends \PHPUnit_Framework_TestCase
'reverse' => null,
];

private $scratch_input_data_1 = [];

/**
*
*/
Expand Down Expand Up @@ -157,13 +159,14 @@ public function testExpr()
*/
public function testJsonSerializeWithoutExpr()
{
array_walk( $this->input_data_1, function($value, $key) {
$this->scratch_input_data_1 = $this->input_data_1;
array_walk( $this->scratch_input_data_1, function($value, $key) {
if (is_null($value)) {
unset($this->input_data_1[$key]);
unset($this->scratch_input_data_1[$key]);
}
});
$expected = $this->input_data_1;
TestUtils::setAttributes( $this->ticks, $this->input_data_1 );
TestUtils::setAttributes( $this->ticks, $this->scratch_input_data_1 );
$result = json_decode( $this->ticks->jsonSerialize(), true );
self::assertEquals( $expected, $result );
}
Expand Down
Loading

0 comments on commit de02d1a

Please sign in to comment.