From 7690b0ec7f55b08350ecfd4bdbae7e96f99c7455 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jannis=20Mo=C3=9Fhammer?= Date: Mon, 23 Sep 2013 12:09:40 +0200 Subject: [PATCH] Add basic tests and meta attributes for graphs refs #4614 --- library/Icinga/Chart/Graph/BarGraph.php | 4 +- library/Icinga/Chart/Graph/LineGraph.php | 2 + library/Icinga/Chart/PieChart.php | 4 +- library/Icinga/Chart/Primitive/Animatable.php | 2 +- library/Icinga/Chart/Primitive/Circle.php | 1 + library/Icinga/Chart/Primitive/Line.php | 1 + library/Icinga/Chart/Primitive/Path.php | 1 + library/Icinga/Chart/Primitive/PieSlice.php | 2 + library/Icinga/Chart/Primitive/Rect.php | 1 + library/Icinga/Chart/Primitive/Styleable.php | 24 +++++ library/Icinga/Chart/Primitive/Text.php | 2 +- .../library/Icinga/Chart/GraphChartTest.php | 88 +++++++++++++++++++ .../php/library/Icinga/Chart/PieChartTest.php | 70 +++++++++++++++ test/php/library/Icinga/LibraryLoader.php | 4 + 14 files changed, 201 insertions(+), 5 deletions(-) create mode 100644 test/php/library/Icinga/Chart/GraphChartTest.php create mode 100644 test/php/library/Icinga/Chart/PieChartTest.php diff --git a/library/Icinga/Chart/Graph/BarGraph.php b/library/Icinga/Chart/Graph/BarGraph.php index c3621abf0..a3d9305c9 100644 --- a/library/Icinga/Chart/Graph/BarGraph.php +++ b/library/Icinga/Chart/Graph/BarGraph.php @@ -84,12 +84,14 @@ class BarGraph extends Styleable implements Drawable { $doc = $ctx->getDocument(); $group = $doc->createElement('g'); + $idx = 0; foreach ($this->dataSet as $point) { $rect = new Rect($point[0]-1, $point[1], 2, 100- $point[1]); $rect->setFill($this->fill); $rect->setStrokeWidth($this->strokeWidth); $rect->setStrokeColor('black'); - + $rect->setAttribute('data-icinga-graph-index', $idx++); + $rect->setAttribute('data-icinga-graph-type', 'bar'); $rect->setAdditionalStyle('clip-path: url(#clip);'); $rect->setAnimation( new Animation( diff --git a/library/Icinga/Chart/Graph/LineGraph.php b/library/Icinga/Chart/Graph/LineGraph.php index cb4e7e553..02a4a1e71 100644 --- a/library/Icinga/Chart/Graph/LineGraph.php +++ b/library/Icinga/Chart/Graph/LineGraph.php @@ -144,6 +144,7 @@ class LineGraph extends Styleable implements Drawable $path->setStrokeColor($this->strokeColor); $path->setStrokeWidth($this->strokeWidth); + $path->setAttribute('data-icinga-graph-type', 'line'); if ($this->fill !== 'none') { $firstX = $this->dataset[0][0]; $lastX = $this->dataset[count($this->dataset)-1][0]; @@ -151,6 +152,7 @@ class LineGraph extends Styleable implements Drawable ->append(array($lastX, 100)); $path->setFill($this->fill); } + $path->setAdditionalStyle('clip-path: url(#clip);'); $path->setId($this->id); $group = $path->toSvg($ctx); diff --git a/library/Icinga/Chart/PieChart.php b/library/Icinga/Chart/PieChart.php index 9b1dff185..1123ad895 100644 --- a/library/Icinga/Chart/PieChart.php +++ b/library/Icinga/Chart/PieChart.php @@ -190,7 +190,7 @@ class PieChart extends Chart ->setFill($this->getColorForPieSlice($pie, $idx)); $innerBox->addElement($slice); // add caption if not disabled - if (!$this->noCaption) { + if (!$this->noCaption && isset($pie['labels'])) { $slice->setCaption($pie['labels'][$labelPos++]) ->setLabelGroup($labelBox); @@ -231,7 +231,7 @@ class PieChart extends Chart ->setFill($this->getColorForPieSlice($pie, $idx)) ->setLabelGroup($labelBox); - if (!$this->noCaption) { + if (!$this->noCaption && isset($pie['labels'])) { $slice->setCaption($pie['labels'][$labelPos++]) ->setCaptionOffset($offset) ->setOuterCaptionBound(50); diff --git a/library/Icinga/Chart/Primitive/Animatable.php b/library/Icinga/Chart/Primitive/Animatable.php index 92922a192..1b37d52c7 100644 --- a/library/Icinga/Chart/Primitive/Animatable.php +++ b/library/Icinga/Chart/Primitive/Animatable.php @@ -65,4 +65,4 @@ abstract class Animatable extends Styleable $dom->appendChild($this->animation->toSvg($ctx)); } } -} \ No newline at end of file +} diff --git a/library/Icinga/Chart/Primitive/Circle.php b/library/Icinga/Chart/Primitive/Circle.php index feb12d1ce..69f32f910 100644 --- a/library/Icinga/Chart/Primitive/Circle.php +++ b/library/Icinga/Chart/Primitive/Circle.php @@ -82,6 +82,7 @@ class Circle extends Styleable implements Drawable $circle->setAttribute('cy', $coords[1]); $circle->setAttribute('r', 5); $circle->setAttribute('style', $this->getStyle()); + $this->applyAttributes($circle); return $circle; } } diff --git a/library/Icinga/Chart/Primitive/Line.php b/library/Icinga/Chart/Primitive/Line.php index 56390bf86..2a82b5f77 100644 --- a/library/Icinga/Chart/Primitive/Line.php +++ b/library/Icinga/Chart/Primitive/Line.php @@ -100,6 +100,7 @@ class Line extends Styleable implements Drawable $line->setAttribute('y1', $y1); $line->setAttribute('y2', $y2); $line->setAttribute('style', $this->getStyle()); + $this->applyAttributes($line); return $line; } } diff --git a/library/Icinga/Chart/Primitive/Path.php b/library/Icinga/Chart/Primitive/Path.php index 0bde1bd4a..761e033aa 100644 --- a/library/Icinga/Chart/Primitive/Path.php +++ b/library/Icinga/Chart/Primitive/Path.php @@ -170,6 +170,7 @@ class Path extends Styleable implements Drawable } $path->setAttribute('d', $pathDescription); $path->setAttribute('style', $this->getStyle()); + $this->applyAttributes($path); $group->appendChild($path); return $group; } diff --git a/library/Icinga/Chart/Primitive/PieSlice.php b/library/Icinga/Chart/Primitive/PieSlice.php index 51cd28db1..935a18234 100644 --- a/library/Icinga/Chart/Primitive/PieSlice.php +++ b/library/Icinga/Chart/Primitive/PieSlice.php @@ -288,7 +288,9 @@ class PieSlice extends Animatable implements Drawable $slicePath->setAttribute('d', $this->getPieSlicePath($x, $y, $r)); $slicePath->setAttribute('style', $this->getStyle()); + $slicePath->setAttribute('data-icinga-graph-type', 'pieslice'); + $this->applyAttributes($slicePath); $group->appendChild($slicePath); if ($this->caption != "") { $lblGroup = ($this->labelGroup ? $this->labelGroup : $group); diff --git a/library/Icinga/Chart/Primitive/Rect.php b/library/Icinga/Chart/Primitive/Rect.php index 39f2d6ed6..ba0bce593 100644 --- a/library/Icinga/Chart/Primitive/Rect.php +++ b/library/Icinga/Chart/Primitive/Rect.php @@ -115,6 +115,7 @@ class Rect extends Animatable implements Drawable $rect->setAttribute('height', $height); $rect->setAttribute('style', $this->getStyle()); + $this->applyAttributes($rect); $this->appendAnimation($rect, $ctx); return $rect; diff --git a/library/Icinga/Chart/Primitive/Styleable.php b/library/Icinga/Chart/Primitive/Styleable.php index 6eb8623ee..a0a800994 100644 --- a/library/Icinga/Chart/Primitive/Styleable.php +++ b/library/Icinga/Chart/Primitive/Styleable.php @@ -29,6 +29,8 @@ namespace Icinga\Chart\Primitive; +use DOMElement; + /** * Base class for stylable drawables */ @@ -65,6 +67,13 @@ class Styleable */ public $id = null; + /** + * Additional attributes to be set + * + * @var array + */ + public $attributes = array(); + /** * Set the stroke width for this drawable * @@ -142,4 +151,19 @@ class Styleable $base .= ';' . $this->additionalStyle . ';'; return $base; } + + /** + * Add an additional attribte to this element + */ + public function setAttribute($key, $value) + { + $this->attributes[$key] = $value; + } + + protected function applyAttributes(DOMElement $el) + { + foreach ($this->attributes as $name => $value) { + $el->setAttribute($name, $value); + } + } } diff --git a/library/Icinga/Chart/Primitive/Text.php b/library/Icinga/Chart/Primitive/Text.php index 8ab73462a..472ed92f3 100644 --- a/library/Icinga/Chart/Primitive/Text.php +++ b/library/Icinga/Chart/Primitive/Text.php @@ -152,7 +152,6 @@ class Text extends Styleable implements Drawable { list($x, $y) = $ctx->toAbsolute($this->x, $this->y); $text = $ctx->getDocument()->createElement('text'); - $text->setAttribute('x', $x - 15); $text->setAttribute( 'style', @@ -162,6 +161,7 @@ class Text extends Styleable implements Drawable . 'font-weight: normal; font-style: normal;' . 'text-anchor: ' . $this->alignment ); + $text->setAttribute('y', $y); $text->appendChild(new DOMText($this->text)); return $text; diff --git a/test/php/library/Icinga/Chart/GraphChartTest.php b/test/php/library/Icinga/Chart/GraphChartTest.php new file mode 100644 index 000000000..1eb6c64c9 --- /dev/null +++ b/test/php/library/Icinga/Chart/GraphChartTest.php @@ -0,0 +1,88 @@ + + * @license http://www.gnu.org/licenses/gpl-2.0.txt GPL, version 2 + * @author Icinga Development Team + */ +// {{{ICINGA_LICENSE_HEADER}}} + +namespace Tests\Icinga\Chart; + +use DOMXPath; +use DOMDocument; + +use Icinga\Chart\GridChart; +use Icinga\Test\BaseTestCase; +use Test\Icinga\LibraryLoader; + +// TODO: Use autoloader #4673 +require_once realpath(__DIR__ . '/../../../../../library/Icinga/Test/BaseTestCase.php'); +require_once realpath(BaseTestCase::$testDir . '/library/Icinga/LibraryLoader.php'); + +require_once realpath(BaseTestCase::$libDir . '/Chart/Primitive/Drawable.php'); +require_once realpath(BaseTestCase::$libDir . '/Chart/Primitive/Styleable.php'); +require_once realpath(BaseTestCase::$libDir . '/Chart/Primitive/Animatable.php'); +require_once realpath(BaseTestCase::$libDir . '/Chart/Unit/AxisUnit.php'); +require_once realpath(BaseTestCase::$libDir . '/Chart/Unit/LinearUnit.php'); +LibraryLoader::loadFolder(realpath(BaseTestCase::$libDir . '/Chart')); + +class GraphChartTest extends BaseTestCase +{ + public function testBarChartCreation() + { + $chart = new GridChart(); + $chart->drawBars( + array( + 'label' => 'My bar', + 'color' => 'black', + 'data' => array(array(0, 0), array(1,1), array(1,2)) + ) + ); + $doc = new DOMDocument(); + $doc->preserveWhiteSpace = false; + $doc->loadXML($chart->render()); + $xpath = new DOMXPath($doc); + $xpath->registerNamespace('x', 'http://www.w3.org/2000/svg'); + $path = $xpath->query('//x:rect[@data-icinga-graph-type="bar"]'); + $this->assertEquals(3, $path->length, 'Assert the correct number of datapoints being drawn as SVG bars'); + } + + public function testLineChartCreation() + { + $chart = new GridChart(); + $chart->drawLines( + array( + 'label' => 'My bar', + 'color' => 'black', + 'data' => array(array(0, 0), array(1,1), array(1,2)) + ) + ); + $doc = new DOMDocument(); + $doc->preserveWhiteSpace = false; + $doc->loadXML($chart->render()); + $xpath = new DOMXPath($doc); + $xpath->registerNamespace('x', 'http://www.w3.org/2000/svg'); + $path = $xpath->query('//x:path[@data-icinga-graph-type="line"]'); + $this->assertEquals(1, $path->length, 'Assert the correct number of datapoints being drawn as SVG lines'); + } +} \ No newline at end of file diff --git a/test/php/library/Icinga/Chart/PieChartTest.php b/test/php/library/Icinga/Chart/PieChartTest.php new file mode 100644 index 000000000..66a752180 --- /dev/null +++ b/test/php/library/Icinga/Chart/PieChartTest.php @@ -0,0 +1,70 @@ + + * @license http://www.gnu.org/licenses/gpl-2.0.txt GPL, version 2 + * @author Icinga Development Team + */ +// {{{ICINGA_LICENSE_HEADER}}} + +namespace Tests\Icinga\Chart; + +use DOMXPath; +use DOMDocument; + +use Icinga\Chart\GridChart; +use Icinga\Chart\PieChart; +use Icinga\Test\BaseTestCase; +use Test\Icinga\LibraryLoader; + +// TODO: Use autoloader #4673 +require_once realpath(__DIR__ . '/../../../../../library/Icinga/Test/BaseTestCase.php'); +require_once realpath(BaseTestCase::$testDir . '/library/Icinga/LibraryLoader.php'); + +require_once realpath(BaseTestCase::$libDir . '/Chart/Primitive/Drawable.php'); +require_once realpath(BaseTestCase::$libDir . '/Chart/Primitive/Styleable.php'); +require_once realpath(BaseTestCase::$libDir . '/Chart/Primitive/Animatable.php'); +require_once realpath(BaseTestCase::$libDir . '/Chart/Unit/AxisUnit.php'); +require_once realpath(BaseTestCase::$libDir . '/Chart/Unit/LinearUnit.php'); +LibraryLoader::loadFolder(realpath(BaseTestCase::$libDir . '/Chart')); + +class PieChartTest extends BaseTestCase +{ + public function testPieChartCreation() + { + $chart = new PieChart(); + $chart->drawPie( + array( + 'label' => 'My bar', + 'color' => 'black', 'green', 'red', + 'data' => array(50,50,50) + ) + ); + $doc = new DOMDocument(); + $doc->preserveWhiteSpace = false; + $doc->loadXML($chart->render()); + $xpath = new DOMXPath($doc); + $xpath->registerNamespace('x', 'http://www.w3.org/2000/svg'); + $path = $xpath->query('//x:path[@data-icinga-graph-type="pieslice"]'); + $this->assertEquals(3, $path->length, 'Assert the correct number of datapoints being drawn as SVG bars'); + } +} \ No newline at end of file diff --git a/test/php/library/Icinga/LibraryLoader.php b/test/php/library/Icinga/LibraryLoader.php index fe0806968..3173eed05 100644 --- a/test/php/library/Icinga/LibraryLoader.php +++ b/test/php/library/Icinga/LibraryLoader.php @@ -31,7 +31,11 @@ abstract class LibraryLoader { { $files = scandir($folder); foreach ($files as $file) { + if ($file[0] == '.') { + continue; + } if ($recursive && is_dir(realpath($folder."/".$file))) { + self::loadFolder(realpath($folder."/".$file)); } if (!preg_match('/php$/', $file)) {