Newer
Older
* Piwik - free/libre analytics platform
*
* @link http://piwik.org
* @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later
*/
use Piwik\Common;
use Piwik\DataTable\Manager;
use Piwik\DataTable\Row;
use Piwik\Timer;
Thomas Steur
a validé
use Symfony\Component\VarDumper\Cloner\Data;
Thomas Steur
a validé
* @group DataTable
* @group Core
class DataTableTest extends \PHPUnit_Framework_TestCase
{
public function testApplyFilter()
{
$table = $this->_getDataTable1ForTest();
$this->assertEquals(4, $table->getRowsCount());
$table->filter('Limit', array(2, 2));
$table->filter('Limit', array(0, 1));
$table = new DataTable;
array(Row::COLUMNS => array('label' => 'ten', 'count' => 10)),
array(Row::COLUMNS => array('label' => 'ninety', 'count' => 90)),
array(Row::COLUMNS => array('label' => 'hundred', 'count' => 100)),
DataTable::ID_SUMMARY_ROW => array(Row::COLUMNS => array('label' => 'summary', 'count' => 200))
public function testRenameColumn()
{
$table = $this->_getSimpleTestDataTable();
$this->assertEquals(array(10, 90, 100, 200), $table->getColumn('count'));
$table->renameColumn('count', 'renamed');
$this->assertEquals(array(false, false, false, false), $table->getColumn('count'));
$this->assertEquals(array(10, 90, 100, 200), $table->getColumn('renamed'));
}
public function testDeleteColumn()
{
$table = $this->_getSimpleTestDataTable();
$this->assertEquals(array(10, 90, 100, 200), $table->getColumn('count'));
$table->deleteColumn('count');
$this->assertEquals(array(false, false, false, false), $table->getColumn('count'));
}
public function testDeleteRow()
{
$table = $this->_getSimpleTestDataTable();
// normal row
$idToDelete = 1;
$this->assertEquals(2, count($table->getRowFromId($idToDelete)->getColumns()));
$table->deleteRow($idToDelete);
$this->assertFalse($table->getRowFromId($idToDelete));
// summary row special case
$idToDelete = DataTable::ID_SUMMARY_ROW;
$this->assertEquals(2, count($table->getRowFromId($idToDelete)->getColumns()));
$table->deleteRow($idToDelete);
$this->assertFalse($table->getRowFromId($idToDelete));
}
public function testGetLastRow()
{
$table = $this->_getSimpleTestDataTable();
$rowsCount = $table->getRowsCount();
$this->assertEquals($table->getLastRow(), $table->getRowFromId(DataTable::ID_SUMMARY_ROW));
$table->deleteRow(DataTable::ID_SUMMARY_ROW);
$this->assertEquals($table->getLastRow(), $table->getRowFromId($rowsCount - 2));
public function testGetRowFromIdSubDataTable()
{
$table1 = $this->_getDataTable1ForTest();
$idTable1 = $table1->getId();
$table2 = $this->_getDataTable2ForTest();
$this->assertFalse($table2->getRowFromIdSubDataTable($idTable1));
$table2->getFirstRow()->setSubtable($table1);
$this->assertEquals($table2->getRowFromIdSubDataTable($idTable1), $table2->getFirstRow());
$table3 = $this->_getDataTable1ForTest();
$idTable3 = $table3->getId();
$table2->getLastRow()->setSubtable($table3);
$this->assertEquals($table2->getRowFromIdSubDataTable($idTable3), $table2->getLastRow());
}
Thomas Steur
a validé
public function test_clone_shouldIncreasesTableId()
{
$table = new DataTable;
$rows = array(
array(Row::COLUMNS => array('label' => 'google')),
);
$table->addRowsFromArray($rows);
$table2 = clone $table;
$this->assertSame($table2->getId(), $table->getId() + 1);
}
/**
* we test the count rows and the count rows recursive version
* on a Simple array (1 level only)
*/
$table = new DataTable;
$idcol = Row::COLUMNS;
$rows = array(
array($idcol => array('label' => 'google')),
array($idcol => array('label' => 'ask')),
array($idcol => array('label' => 'piwik')),
array($idcol => array('label' => 'yahoo')),
array($idcol => array('label' => 'amazon')),
array($idcol => array('label' => '238975247578949')),
Thomas Steur
a validé
array($idcol => array('label' => 'Q*(%&*("$&%*(&"$*")"))'))
);
$table->addRowsFromArray($rows);
Thomas Steur
a validé
$this->assertEquals(7, $table->getRowsCount());
$this->assertEquals(7, $table->getRowsCountRecursive());
/**
* we test the count rows and the count rows recursive version
* on a Complex array (rows with 2 and 3 levels only)
*
* the recursive count returns
* the sum of the number of rows of all the subtables
$idcol = Row::COLUMNS;
$idsubtable = Row::DATATABLE_ASSOCIATED;
$tableSubOfSubOfRow1 = new DataTable;
array($idcol => array('label' => 'google')),
array($idcol => array('label' => 'google78')),
array($idcol => array('label' => 'googlaegge')),
array($idcol => array('label' => 'gogeoggle')),
array($idcol => array('label' => 'goaegaegaogle')),
array($idcol => array('label' => 'ask')),
array($idcol => array('label' => '238975247578949')),
$tableSubOfSubOfRow1->addRowsFromArray($rows1sub);
$tableSubOfRow1 = new DataTable;
array($idcol => array('label' => 'google'), $idsubtable => $tableSubOfSubOfRow1),
array($idcol => array('label' => 'ask')),
array($idcol => array('label' => '238975247578949')),
$tableSubOfRow1->addRowsFromArray($rows1);
$tableSubOfRow2 = new DataTable;
array($idcol => array('label' => 'google')),
array($idcol => array('label' => 'ask')),
array($idcol => array('label' => '238975247578949')),
array($idcol => array('label' => 'agaegaesk')),
array($idcol => array('label' => '23g 8975247578949')),
$tableSubOfRow2->addRowsFromArray($rows2);
$table = new DataTable;
array($idcol => array('label' => 'row1')),
array($idcol => array('label' => 'row2'),
$idsubtable => $tableSubOfRow1),
array($idcol => array('label' => 'row3'),
$idsubtable => $tableSubOfRow2),
$table->addRowsFromArray($rows);
Thomas Steur
a validé
$this->assertEquals(3, $table->getRowsCount());
$this->assertEquals(18, $table->getRowsCountRecursive());
$columns = array('test_column' => 145,
Thomas Steur
a validé
92582495 => new Timer,
'super' => array('this column has an array value, amazing'));
$metadata = array('logo' => 'piwik.png',
'super' => array('this column has an array value, amazing'));
Row::COLUMNS => $columns,
Row::METADATA => $metadata,
'fake useless key' => 38959,
43905724897 => 'value');
$row = new Row($arrayRow);
$this->assertEquals($columns, $row->getColumns());
$this->assertEquals($metadata, $row->getMetadata());
$this->assertNull($row->getIdSubDataTable());
$columns = array('test_int' => 145,
'test_float' => 145.5,
'test_float3' => 1.5,
'test_stringint' => "145",
"test" => 'string fake',
'integerArrayToSum' => array(1 => 1, 2 => 10.0, 3 => array(1 => 2, 2 => 3)),
);
$metadata = array('logo' => 'piwik.png',
'super' => array('this column has an array value, amazing'));
Row::COLUMNS => $columns,
Row::METADATA => $metadata,
'fake useless key' => 38959,
Thomas Steur
a validé
'43905724897' => 'value');
$row1 = new Row($arrayRow);
$columns2 = array('test_int' => 5,
'test_float' => 4.5,
'test_float2' => 14.5,
'test_stringint' => "5",
Thomas Steur
a validé
925824 => 'toto',
'integerArrayToSum' => array(1 => 5, 2 => 5.5, 3 => array(2 => 4)),
);
$finalRow = new Row(array(Row::COLUMNS => $columns2));
$columnsWanted = array('test_int' => 150,
'test_float' => 150.0,
'test_float2' => 14.5,
'test_float3' => 1.5,
'test_stringint' => 150, //add also strings!!
'test' => 'string fake',
'integerArrayToSum' => array(1 => 6, 2 => 15.5, 3 => array(1 => 2, 2 => 7)),
Thomas Steur
a validé
925824 => 'toto',
);
// Also testing that metadata is copied over
$rowWanted = new Row(array(Row::COLUMNS => $columnsWanted, Row::METADATA => $metadata));
$this->assertTrue(Row::isEqual($rowWanted, $finalRow));
// testing that, 'sumRow' does not result in extra unwanted attributes being serialized
Thomas Steur
a validé
$expectedRow = 'a:3:{i:0;a:8:{s:8:"test_int";i:150;s:10:"test_float";d:150;s:11:"test_float2";d:14.5;s:14:"test_stringint";i:150;i:925824;s:4:"toto";s:17:"integerArrayToSum";a:3:{i:1;i:6;i:2;d:15.5;i:3;a:2:{i:2;i:7;i:1;i:2;}}s:11:"test_float3";d:1.5;s:4:"test";s:11:"string fake";}i:1;a:2:{s:4:"logo";s:9:"piwik.png";s:5:"super";a:1:{i:0;s:39:"this column has an array value, amazing";}}i:3;N;}';
$this->assertEquals($expectedRow, serialize($finalRow->export()));
// Testing sumRow with disabled metadata sum
$rowWanted = new Row(array(Row::COLUMNS => $columnsWanted)); // no metadata
$finalRow = new Row(array(Row::COLUMNS => $columns2));
$finalRow->sumRow($row1, $enableCopyMetadata = false);
$this->assertTrue(Row::isEqual($rowWanted, $finalRow));
}
mattab
a validé
/**
Thomas Steur
a validé
* @dataProvider unserializeTestsDataProvider
mattab
a validé
*/
public function test_unserializeWorks_WithAllDataTableFormats($indexToRead, $label, $column2, $subtable)
{
Thomas Steur
a validé
$serializedDatatable = array();
// Prior Piwik 2.13, we serialized the actual Row or DataTableSummaryRow instances, afterwards only arrays
require PIWIK_INCLUDE_PATH . "/tests/resources/DataTables-archived-different-formats.php";
require_once PIWIK_INCLUDE_PATH . "/core/DataTable/Bridges.php";
Thomas Steur
a validé
$table = $serializedDatatable[$indexToRead];
$this->assertTrue(strlen($table) > 1000);
$table = DataTable::fromSerializedArray($table);
$row1 = $table->getFirstRow();
$this->assertTrue($row1 instanceof \Piwik\DataTable\Row);
$this->assertFalse($row1 instanceof \Piwik\DataTable\Row\DataTableSummaryRow); // we convert summary rows to Row instances
Thomas Steur
a validé
$this->assertEquals($label, $row1->getColumn('label'));
$this->assertEquals($column2, $row1->getColumn(2));
$this->assertEquals($subtable, $row1->getIdSubDataTable());
}
public function testSumRowMetadata_CustomAggregationOperation()
{
$metadata1 = array('mytest' => 'value1');
$metadata2 = array('mytest' => 'value2');
Thomas Steur
a validé
$self = $this;
$row1 = new Row(array(Row::COLUMNS => array('test_int' => 145), Row::METADATA => $metadata1));
$finalRow = new Row(array(Row::COLUMNS => array('test_int' => 5), Row::METADATA => $metadata2));
Thomas Steur
a validé
$finalRow->sumRowMetadata($row1, array('mytest' => function ($thisValue, $otherValue, $thisRow, $otherRow) use ($self, $row1, $finalRow) {
$self->assertEquals('value2', $thisValue);
$self->assertEquals('value1', $otherValue);
$self->assertSame($thisRow, $finalRow);
$self->assertSame($otherRow, $row1);
if (!is_array($thisValue)) {
$thisValue = array($thisValue);
}
$thisValue[] = $otherValue;
return $thisValue;
}));
$this->assertEquals(array('value2', 'value1'), $finalRow->getMetadata('mytest'));
}
public function testSumRow_CustomAggregationOperation()
{
$columns = array('test_int' => 145, 'test_float' => 145.5);
$row1 = new Row(array(Row::COLUMNS => $columns));
$columns2 = array('test_int' => 5);
$finalRow = new Row(array(Row::COLUMNS => $columns2));
Thomas Steur
a validé
$self = $this;
$finalRow->sumRow($row1, $copyMetadata = true, $operation = array('test_int' => function ($thisValue, $otherValue, $thisRow, $otherRow) use ($self, $row1, $finalRow) {
$self->assertEquals(5, $thisValue);
$self->assertEquals(145, $otherValue);
$self->assertSame($thisRow, $finalRow);
$self->assertSame($otherRow, $row1);
if (!is_array($thisValue)) {
$thisValue = array($thisValue);
}
$thisValue[] = $otherValue;
return $thisValue;
}));
$this->assertEquals(array(5, 145), $finalRow->getColumn('test_int'));
}
/**
* @expectedException \Exception
* @expectedExceptionMessage Unknown operation 'foobarinvalid'
*/
public function testSumRow_ShouldThrowExceptionIfInvalidOperationIsGiven()
{
$row1 = new Row(array(Row::COLUMNS => array('test_int' => 145)));
$finalRow = new Row(array(Row::COLUMNS => array('test_int' => 5)));
$finalRow->sumRow($row1, $copyMetadata = true, $operation = array('test_int' => 'fooBarInvalid'));
$this->assertEquals(array(5, 145), $finalRow->getColumn('test_int'));
}
Thomas Steur
a validé
public function unserializeTestsDataProvider()
{
return array(
array($index = 0, $label = 'piwik.org', $column2 = 10509, $idSubtable = 1581), // pre Piwik 2.0 (without namespaces, Piwik_DataTable_Row)
array($index = 1, $label = 'piwikactions.org', $column2 = 10508, $idSubtable = 1581), // pre Piwik 2.0 Actions (without namespaces, Piwik_DataTable_Row_DataTableSummary)
array($index = 2, $label = 'start', $column2 = 89, $idSubtable = 2260), // >= Piwik 2.0 < Piwik 2.13 Actions (DataTableSummaryRow)
array($index = 3, $label = 'Ask', $column2 = 11, $idSubtable = 3335), // >= Piwik 2.0 < Piwik 2.13 Referrers (Row)
array($index = 4, $label = 'MyLabel Test', $column2 = 447, $idSubtable = 1), // >= Piwik 2.0 < Piwik 2.13 Referrers (Row)
Thomas Steur
a validé
);
/**
* Test that adding two string column values results in an exception.
*/
public function testSumRow_stringException()
{
$columns = array(
'super' => array('this column has an array string that will be 0 when algorithm sums the value'),
);
$row1 = new Row(array(Row::COLUMNS => $columns));
$columns2 = array(
'super' => array('this column has geagaean array value, amazing'),
);
$row2 = new Row(array(Row::COLUMNS => $columns2));
$this->assertTrue($noException = true);
/**
* Test serialize with an infinite recursion (a row linked to a table in the parent hierarchy)
* After 100 recursion must throw an exception
public function testSerializeWithInfiniteRecursion()
Thomas Steur
a validé
$table->addRowFromArray(array(Row::COLUMNS => array('visits' => 245, 'visitors' => 245),
Row::DATATABLE_ASSOCIATED => $table));
public function testFilterQueueSortString()
{
$idcol = Row::COLUMNS;
$table = new DataTable;
array($idcol => array('label' => 'google')), //0
array($idcol => array('label' => 'tsk')), //1
array($idcol => array('label' => 'Q*(%&*("$&%*(&"$*")"))')), //2
);
$table->addRowsFromArray($rows);
$expectedtable = new DataTable;
array($idcol => array('label' => 'google')), //0
array($idcol => array('label' => 'Q*(%&*("$&%*(&"$*")"))')), //2
array($idcol => array('label' => 'tsk')), //1
);
$expectedtable->addRowsFromArray($rows);
$expectedtableReverse = new DataTable;
$expectedtableReverse->addRowsFromArray(array_reverse($rows));
$this->assertTrue(DataTable::isEqual($tableCopy, $table));
// queue the filter and check the table didnt change
$table->queueFilter("Sort", array('label', 'asc'));
$this->assertTrue(DataTable::isEqual($tableCopy, $table));
// apply filter and check the table is sorted
$table->applyQueuedFilters();
$this->assertTrue(DataTable::isEqual($expectedtable, $table));
// apply one more filter check it hasnt changed
$table->queueFilter("Sort", array('label', 'desc'));
$this->assertTrue(DataTable::isEqual($expectedtable, $table));
// now apply the second sort and check it is correctly sorted
$table->applyQueuedFilters();
$this->assertTrue(DataTable::isEqual($expectedtableReverse, $table));
// do one more time to make sure it doesnt change
$table->applyQueuedFilters();
$this->assertTrue(DataTable::isEqual($expectedtableReverse, $table));
/**
* General tests that tries to test the normal behaviour of DataTable
* We create some tables, add rows, some of the rows link to sub tables
* Then we serialize everything, and we check that the unserialize give the same object back
*/
{
/*
* create some fake tables to make sure that the serialized array of the first TABLE
* does not take in consideration those tables
*/
Thomas Steur
a validé
$useless1 = $this->createDataTable(array(array(13,)));
$table = new DataTable;
$subtable = new DataTable;
/*
* create some fake tables to make sure that the serialized array of the first TABLE
* does not take in consideration those tables
* -> we check that the DataTable_Manager is not impacting DataTable
$useless1->addRowFromArray(array(Row::COLUMNS => array(8487,),));
Thomas Steur
a validé
$useless3 = $this->createDataTable(array(array(8487)));
$row = array(Row::COLUMNS => array(0 => 1554, 1 => 42, 2 => 657, 3 => 155744,),
Row::METADATA => array('logo' => 'test.png'));
$row = new Row($row);
$table->addRowFromArray(array(Row::COLUMNS => array(0 => 1554, 1 => 42,),
Row::METADATA => array('url' => 'piwik.org')));
$table->addRowFromArray(array(Row::COLUMNS => array(0 => 787877888787,),
Row::METADATA => array('url' => 'OUPLA ADDED'),
Row::DATATABLE_ASSOCIATED => $subtable));
*/
$row = array(Row::COLUMNS => array(0 => 1554,),
Row::METADATA => array('searchengine' => 'google'),
$row = array(Row::COLUMNS => array(0 => 84894,),
Row::METADATA => array('searchengine' => 'yahoo'),
$row = array(Row::COLUMNS => array(0 => 4898978989,),
Row::METADATA => array('searchengine' => 'ask'),
$subsubtable = new DataTable;
$subsubtable->addRowFromArray(array(Row::COLUMNS => array(245),
Row::METADATA => array('yes' => 'subsubmetadata1'),)
);
$subsubtable->addRowFromArray(array(Row::COLUMNS => array(13,),
Row::METADATA => array('yes' => 'subsubmetadata2'),)
);
$row = array(Row::COLUMNS => array(0 => 666666666666666,),
Row::METADATA => array('url' => 'NEW ROW ADDED'),
Row::DATATABLE_ASSOCIATED => $subsubtable);
Thomas Steur
a validé
$serialized = $table->getSerialized();
Thomas Steur
a validé
$this->assertEquals(array_keys($serialized), array(2, 1, 0)); // subtableIds are now consecutive
// In the next test we compare an unserialized datatable with its original instance.
// The unserialized datatable rows will have positive DATATABLE_ASSOCIATED ids.
// Positive DATATABLE_ASSOCIATED ids mean that the associated sub-datatables are not loaded in memory.
// In this case, this is NOT true: we know that the sub-datatable is loaded in memory.
// HOWEVER, because of datatable id conflicts happening in the datatable manager, it is not yet
// possible to know, after unserializing a datatable, if its sub-datatables are loaded in memory.
$expectedTableRows = array();
Thomas Steur
a validé
$i = 0;
foreach ($table->getRows() as $currentRow) {
$expectedTableRow = clone $currentRow;
Thomas Steur
a validé
$currentRowAssociatedDatatableId = $currentRow->subtableId;
if ($currentRowAssociatedDatatableId != null) {
Thomas Steur
a validé
$expectedTableRow->setNonLoadedSubtableId(++$i); // subtableIds are consecutive
}
$expectedTableRows[] = $expectedTableRow;
}
$tableAfter = new DataTable;
$this->assertEquals($expectedTableRows, $tableAfter->getRows());
$subsubtableAfter = new DataTable;
Thomas Steur
a validé
$subsubtableAfter->addRowsFromSerializedArray($serialized[$consecutiveSubtableId = 2]);
$this->assertEquals($subsubtable->getRows(), $subsubtableAfter->getRows());
Thomas Steur
a validé
$this->assertEquals($subsubtable->getRows(), DataTable::fromSerializedArray($serialized[$consecutiveSubtableId = 2])->getRows());
$this->assertTrue($subsubtable->getRowsCount() > 0);
$this->assertEquals($table, Manager::getInstance()->getTable($idtable));
$this->assertEquals($subsubtable, Manager::getInstance()->getTable($idsubsubtable));
Thomas Steur
a validé
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
public function test_getSerialized_shouldCreateConsecutiveSubtableIds()
{
$numRowsInRoot = 10;
$numRowsInSubtables = 5;
$rootTable = new DataTable();
$this->addManyRows($rootTable, 100);
foreach ($rootTable->getRows() as $row) {
$subtable = new DataTable();
$this->addManyRows($subtable, 100);
$row->setSubtable($subtable);
foreach ($subtable->getRows() as $subRow) {
$subRow->setSubtable(new DataTable());
}
}
// we want to make sure the tables have high ids but we will ignore them and just give them Ids starting from 0
$recentId = Manager::getInstance()->getMostRecentTableId();
$this->assertGreaterThanOrEqual(5000, $recentId);
$tables = $rootTable->getSerialized($numRowsInRoot, $numRowsInSubtables);
// make sure subtableIds are consecutive. Why "-1"? Because if we want 10 rows, there will be 9 subtables + 1 summary row which won't have a subtable
$sumSubTables = ($numRowsInRoot - 1) + (($numRowsInRoot - 1) * ($numRowsInSubtables - 1));
$subtableIds = array_keys($tables);
sort($subtableIds);
$this->assertEquals(range(0, $sumSubTables), $subtableIds);
// make sure the rows subtableId were updated as well.
foreach ($tables as $index => $serializedRows) {
$rows = unserialize($serializedRows);
$this->assertTrue(is_array($rows));
Thomas Steur
a validé
if (0 === $index) {
// root table, make sure correct amount of rows are in subtables
$this->assertCount($numRowsInRoot, $rows);
}
foreach ($rows as $row) {
$this->assertTrue(is_array($row));
Thomas Steur
a validé
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
$subtableId = $row[Row::DATATABLE_ASSOCIATED];
if ($row[Row::COLUMNS]['label'] === DataTable::LABEL_SUMMARY_ROW) {
$this->assertNull($subtableId);
} else {
$this->assertLessThanOrEqual($sumSubTables, $subtableId); // make sure row was actually updated
$this->assertGreaterThanOrEqual(0, $subtableId);
$subrows = unserialize($tables[$subtableId]);
// this way we make sure the rows point to the correct subtable. only 2nd level rows have actually
// subtables. All 3rd level datatables do not have a row see table creation further above
if ($index === 0) {
$this->assertCount($numRowsInSubtables, $subrows);
} else {
$this->assertCount(0, $subrows);
}
}
}
}
}
public function test_getSerialized_shouldExportOnlyTheSerializedArrayOfAllTableRows()
{
$rootTable = new DataTable();
$this->addManyRows($rootTable, 2);
foreach ($rootTable->getRows() as $row) {
$subtable = new DataTable();
$this->addManyRows($subtable, 2);
$row->setSubtable($subtable);
}
$tables = $rootTable->getSerialized();
// we also make sure it actually handles the subtableIds correct etc
$this->assertEquals(array(
0 => 'a:2:{i:0;a:3:{i:0;a:1:{s:5:"label";s:6:"label0";}i:1;a:0:{}i:3;i:1;}i:1;a:3:{i:0;a:1:{s:5:"label";s:6:"label1";}i:1;a:0:{}i:3;i:2;}}',
1 => 'a:2:{i:0;a:3:{i:0;a:1:{s:5:"label";s:6:"label0";}i:1;a:0:{}i:3;N;}i:1;a:3:{i:0;a:1:{s:5:"label";s:6:"label1";}i:1;a:0:{}i:3;N;}}',
2 => 'a:2:{i:0;a:3:{i:0;a:1:{s:5:"label";s:6:"label0";}i:1;a:0:{}i:3;N;}i:1;a:3:{i:0;a:1:{s:5:"label";s:6:"label1";}i:1;a:0:{}i:3;N;}}',
), $tables);
}
private function addManyRows(DataTable $table, $numRows)
{
for ($i = 0; $i < $numRows; $i++) {
$table->addRowFromArray(array(Row::COLUMNS => array('label' => 'label' . $i)));
}
}
/**
* for all datatable->addDatatable tests we check that
* - row uniqueness is based on the label + presence of the SUBTABLE id
* => the label is the criteria used to match 2 rows in 2 datatable
* - no metadata are lost in the first datatable rows that have been changed
* - when a subtable
*/
/**
* add an empty datatable to a normal datatable
*/
public function testAddSimpleNoRowTable2()
{
$table = $this->_getDataTable1ForTest();
$tableEmpty = new DataTable;
$tableAfter = clone $table;
$tableAfter->addDataTable($tableEmpty);
$this->assertTrue(DataTable::isEqual($table, $tableAfter));
/**
* add a normal datatable to an empty datatable
*/
public function testAddSimpleNoRowTable1()
{
$table = $this->_getDataTable1ForTest();
$tableEmpty = new DataTable;
$this->assertTrue(DataTable::isEqual($tableEmpty, $table));
}
/**
* add to the datatable another datatable// they don't have any row in common
*/
public function testAddSimpleNoCommonRow()
{
$table1 = $this->_getDataTable1ForTest();
$table2 = $this->_getDataTable2ForTest();
$rowsExpected = array_merge($this->_getRowsDataTable1ForTest(), $this->_getRowsDataTable2ForTest());
$tableExpected = new DataTable;
$tableExpected->addRowsFromArray($rowsExpected);
$this->assertTrue(DataTable::isEqual($table1, $tableExpected));
/**
* add 2 datatable with some common rows
*/
public function testAddSimpleSomeCommonRow()
{
$idcol = Row::COLUMNS;
array($idcol => array('label' => 'google', 'visits' => 1)),
array($idcol => array('label' => 'ask', 'visits' => 2)),
array($idcol => array('label' => '123', 'visits' => 2)),
DataTable::ID_SUMMARY_ROW => array($idcol => array('label' => DataTable::LABEL_SUMMARY_ROW, 'visits' => 7))
$table = new DataTable;
$table->addRowsFromArray($rows);
array($idcol => array('label' => 'test', 'visits' => 1)),
array($idcol => array('label' => 'ask', 'visits' => 111)),
array($idcol => array('label' => ' google ', 'visits' => 5)),
array($idcol => array('label' => '123', 'visits' => 2)),
);
$table2 = new DataTable;
$table2->addRowsFromArray($rows2);
array($idcol => array('label' => 'google', 'visits' => 1)),
array($idcol => array('label' => 'ask', 'visits' => 113)),
array($idcol => array('label' => '123', 'visits' => 4)),
array($idcol => array('label' => 'test', 'visits' => 1)),
array($idcol => array('label' => ' google ', 'visits' => 5)),
DataTable::ID_SUMMARY_ROW => array($idcol => array('label' => DataTable::LABEL_SUMMARY_ROW, 'visits' => 7))
$tableExpected = new DataTable;
$tableExpected->addRowsFromArray($rowsExpected);
$this->assertTrue(DataTable::isEqual($table, $tableExpected));
/**
* add 2 datatable with only common rows
*/
public function testAddSimpleAllCommonRow()
{
$idcol = Row::COLUMNS;
array($idcol => array('label' => 'google', 'visits' => 1)),
array($idcol => array('label' => 'ask', 'visits' => 2)),
array($idcol => array('label' => '123', 'visits' => 2)),
DataTable::ID_SUMMARY_ROW => array($idcol => array('label' => DataTable::LABEL_SUMMARY_ROW, 'visits' => 7))
$table = new DataTable;
$table->addRowsFromArray($rows);
array($idcol => array('label' => 'google', 'visits' => -1)),
array($idcol => array('label' => 'ask', 'visits' => 0)),
array($idcol => array('label' => '123', 'visits' => 1.5)),
DataTable::ID_SUMMARY_ROW => array($idcol => array('label' => DataTable::LABEL_SUMMARY_ROW, 'visits' => 8))
$table2 = new DataTable;
$table2->addRowsFromArray($rows2);
array($idcol => array('label' => 'google', 'visits' => 0)),
array($idcol => array('label' => 'ask', 'visits' => 2)),
array($idcol => array('label' => '123', 'visits' => 3.5)),
DataTable::ID_SUMMARY_ROW => array($idcol => array('label' => DataTable::LABEL_SUMMARY_ROW, 'visits' => 15))
$tableExpected = new DataTable;
$tableExpected->addRowsFromArray($rowsExpected);
$this->assertTrue(DataTable::isEqual($table, $tableExpected));
/**
* test add 2 different tables to the same table
*/
public function testAddDataTable2times()
{
$idcol = Row::COLUMNS;
array($idcol => array('label' => 'google', 'visits' => 1)),
array($idcol => array('label' => 'ask', 'visits' => 0)),
array($idcol => array('label' => '123', 'visits' => 2)),
DataTable::ID_SUMMARY_ROW => array($idcol => array('label' => DataTable::LABEL_SUMMARY_ROW, 'visits' => 1))
$table = new DataTable;
$table->addRowsFromArray($rows);
array($idcol => array('label' => 'google2', 'visits' => -1)),
array($idcol => array('label' => 'ask', 'visits' => 100)),
array($idcol => array('label' => '123456', 'visits' => 1.5)),
);
$table2 = new DataTable;
$table2->addRowsFromArray($rows2);
array($idcol => array('label' => 'google2', 'visits' => -1)),
array($idcol => array('label' => 'ask', 'visits' => -10)),
array($idcol => array('label' => '123ab', 'visits' => 1.5)),
DataTable::ID_SUMMARY_ROW => array($idcol => array('label' => DataTable::LABEL_SUMMARY_ROW, 'visits' => 3))
$table3 = new DataTable;
$table3->addRowsFromArray($rows3);
// add the 2 tables
$table->addDataTable($table2);
$table->addDataTable($table3);
array($idcol => array('label' => 'google', 'visits' => 1)),
array($idcol => array('label' => 'ask', 'visits' => 90)),
array($idcol => array('label' => '123', 'visits' => 2)),
array($idcol => array('label' => 'google2', 'visits' => -2)),
array($idcol => array('label' => '123456', 'visits' => 1.5)),
array($idcol => array('label' => '123ab', 'visits' => 1.5)),
DataTable::ID_SUMMARY_ROW => array($idcol => array('label' => DataTable::LABEL_SUMMARY_ROW, 'visits' => 4))
$tableExpected = new DataTable;
$tableExpected->addRowsFromArray($rowsExpected);
$this->assertTrue(DataTable::isEqual($table, $tableExpected));
}
public function testUnrelatedDataTableNotDestructed()
{
$mockedDataTable = $this->getMock('\Piwik\DataTable', array('__destruct'));
$mockedDataTable->expects($this->never())->method('__destruct');
$rowBeingDestructed = new Row();
// we simulate the fact that the value of Row::DATATABLE_ASSOCIATED retrieved
// from the database is in conflict with one of the Manager managed table identifiers.
// This is a rare but legitimate case as identifiers are not thoroughly synchronized
// when the expanded parameter is false.
Thomas Steur
a validé
$rowBeingDestructed->subtableId = $mockedDataTable->getId();
Common::destroy($rowBeingDestructed);
Thomas Steur
a validé
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
/**
* @group Core
*/
public function test_disableFilter_DoesActuallyDisableAFilter()
{
$dataTable = DataTable::makeFromSimpleArray(array_fill(0, 100, array()));
$this->assertSame(100, $dataTable->getRowsCount());
$dataTable2 = clone $dataTable;
// verify here the filter is applied
$dataTable->filter('Limit', array(10, 10));
$this->assertSame(10, $dataTable->getRowsCount());
// verify here the filter is not applied as it is disabled
$dataTable2->disableFilter('Limit');
$dataTable2->filter('Limit', array(10, 10));
$this->assertSame(100, $dataTable2->getRowsCount());
// passing a whole className is expected to work. This way we also make sure not all filters are disabled
// and it only blocks the given one
$dataTable2->filter('Piwik\DataTable\Filter\Limit', array(10, 10));
$this->assertSame(10, $dataTable2->getRowsCount());
}
/**
* @group Core
*/
public function testSubDataTableIsDestructed()
{
$mockedDataTable = $this->getMock('\Piwik\DataTable', array('__destruct'));
$mockedDataTable->expects($this->once())->method('__destruct');
$rowBeingDestructed = new Row();
$rowBeingDestructed->setSubtable($mockedDataTable);
Common::destroy($rowBeingDestructed);
mattab
a validé
public function test_serializeFails_onSubTableNotFound()
{
// create a simple table with a subtable
$table1 = $this->_getDataTable1ForTest();
$table2 = $this->_getDataTable2ForTest();
$table2->getFirstRow()->setSubtable($table1);
Thomas Steur
a validé
$idSubtable = 1; // subtableIds are consecutive, we cannot use $table->getId()
mattab
a validé
/* Check it looks good:
$renderer = DataTable\Renderer::factory('xml');
$renderer->setTable($table2);
$renderer->setRenderSubTables(true);
echo $renderer->render();
*/
// test serialize:
// - subtable is serialized as expected
$serializedStrings = $table2->getSerialized();
// both the main table and the sub table are serialized
$this->assertEquals(sizeof($serializedStrings), 2);
// the serialized string references the id subtable
Thomas Steur
a validé
$unserialized = unserialize($serializedStrings[0]);
$this->assertSame($idSubtable, $unserialized[0][3], "not found the id sub table in the serialized, not expected");
mattab
a validé
// KABOOM, we delete the subtable, reproducing a "random data issue"
Thomas Steur
a validé
Manager::getInstance()->deleteTable($table1->getId());
mattab
a validé
// Now we will serialize this "broken datatable" and check it works.
// - it does not throw an exception
$serializedStrings = $table2->getSerialized();
// - the serialized table does NOT contain the sub table
$this->assertEquals(sizeof($serializedStrings), 1); // main table only is serialized
Thomas Steur
a validé
$unserialized = unserialize($serializedStrings[0]);
mattab
a validé
// - the serialized string does NOT contain the id subtable (the row was cleaned up as expected)
Thomas Steur
a validé
$this->assertNull($unserialized[0][3], "found the id sub table in the serialized, not expected");
}
public function testMergeSubtablesKeepsMetadata()
{
$dataTable = $this->_getDataTable1ForTest();
$dataTable->setMetadata('additionalMetadata', 'test');
$dataTable = $dataTable->mergeSubtables();
$this->assertEquals('test', $dataTable->getMetadata('additionalMetadata'));
}
Thomas Steur
a validé
private function createDataTable($rows)
{
$useless1 = new DataTable;
foreach ($rows as $row) {
$useless1->addRowFromArray(array(Row::COLUMNS => $row));
}
mattab
a validé
Thomas Steur
a validé
return $useless1;
mattab
a validé
}
protected function _getDataTable1ForTest()
$table = new DataTable;
$table->addRowsFromArray($rows);
return $table;
}
protected function _getDataTable2ForTest()
{
$rows = $this->_getRowsDataTable2ForTest();
$table = new DataTable;
$table->addRowsFromArray($rows);