* @license PHP License * @package WB * @subpackage unittest */ WBClass::load( 'WBException_Datasource' ); /** * Unit Test * * Test table * * @version 0.2.1 * @package WB * @subpackage unittest */ class TestCaseDatasourceTree extends UnitTestCase { /** * tree case insensitive * @var WBDatasource_Tree */ protected $tree; /** * tree case sensitive * @var WBDatasource_Tree */ protected $treecs; /** * tree case sensitive with combined primary key * @var WBDatasource_Tree */ protected $treex; /** * table options * @var array */ protected $options = array(); /** * constructor * * - start objects * - source SQL * */ public function __construct() { WBClass::load('WBUnitTest_SQLUte'); WBUnitTest_SQLUte::source( __FILE__, 'construct' ); $options = $this->options; $this->tree = WBClass::create( 'WBDatasource_Tree', $options ); $options['treetable'] = 'treecs'; $this->treecs = WBClass::create( 'WBDatasource_Tree', $options ); $options['treetable'] = 'treex'; $this->treex = WBClass::create( 'WBDatasource_Tree', $options ); $clause = array(); $clause[] = array( 'field' => 'xid', 'value' => 17 ); $this->treex->setClause( $clause ); $skel = array( 'xid' => 17 ); $this->treex->setSkeleton( $skel ); } /** * destruct * * Remove testing tables */ public function __destruct() { WBUnitTest_SQLUte::source( __FILE__, 'destruct' ); } /** * check instance * */ public function testInit() { $this->assertTrue( class_exists( 'WBDatasource_Tree', false ) ); $this->assertTrue( is_object( $this->tree ) ); $this->assertIsA( $this->tree, 'WBDatasource_Tree' ); $this->assertTrue( is_object( $this->treecs ) ); $this->assertIsA( $this->treecs, 'WBDatasource_Tree' ); $this->assertTrue( is_object( $this->treex ) ); $this->assertIsA( $this->treex, 'WBDatasource_Tree' ); } /** * test root children with additional clause * */ public function testAddRootChildX() { $this->addRootChild($this->treex, true, 42); } /** * add children with additional clause * */ public function testAddChildX() { $this->addChild($this->treex, true, 42); } /** * get child nodes with additional clause * */ public function testGetChildrenX() { $this->getChildren($this->treex); } /** * get child nodes case insesitive * */ public function testGetParentX() { $this->getParentNodes($this->treex); } /** * delete child nodes with additional clause * */ public function testDeleteChildX() { $this->deleteChildNodes($this->treex); } public function testMoveChildrenX() { $this->moveChild($this->treex); } /** * root children case insensitive * */ public function testAddRootChildCI() { $this->addRootChild($this->tree, false); } /** * child nodes case insesitive * */ public function testAddChildCI() { $this->addChild($this->tree, false); } /** * get child nodes case insesitive * */ public function testGetChildrenCI() { $this->getChildren( $this->tree ); } /** * get child nodes case insesitive * */ public function testGetParentCI() { $this->getParentNodes($this->tree); } /** * delete child nodes case insensitive * */ public function testDeleteChildCI() { $this->deleteChildNodes($this->tree); } /** * move children * */ public function testMoveChildrenCI() { $this->moveChild($this->tree); } /** * root children case sensitive * */ public function testAddRootChildCS() { $this->addRootChild($this->treecs); } /** * child nodes case senesitives * */ public function testAddChildCS() { $this->addChild($this->treecs); } /** * get child nodes case sensitive * */ public function testGetChildrenCS() { $this->getChildren($this->treecs); } /** * get child nodes case insesitive * */ public function testGetParentCS() { $this->getParentNodes($this->treecs); } /** * delete child nodes case sensitive * */ public function testDeleteChildCS() { $this->deleteChildNodes($this->treecs); } /** * move children * */ public function testMoveChildrenCS() { $this->moveChild($this->treecs); } /** * test root children with additional clause * */ public function addRootChild($tree, $caseSensitive = true, $x = null) { for( $i = 0; $i < 100; ++$i ) { if ($x) { $data = array( 'xid' => $x, 'payload' => rand( 1, 100000 ) ); $id = $tree->addChild( null, $data ); } $data = array( 'payload' => rand( 1, 100000 ) ); $id = $tree->addChild( null, $data ); $node = $tree->get( $id ); $this->assertEqual( $data['payload'], $node['payload'] ); if ($caseSensitive) { $this->assertBranchSpotCS( $i, $node ); } else { $this->assertBranchSpotCI( $i, $node ); } } } /** * add children with additional clause * */ public function addChild($tree, $caseSensitive = true, $x = null) { // add root child if ($x) { $data = array( 'xid' => $x, 'payload' => rand( 1, 100000 ) ); $id = $tree->addChild( null, $data ); } $data = array( 'payload' => rand( 1, 100000 ) ); $pid = $tree->addChild( null, $data ); $node = $tree->get( $pid ); $this->assertEqual( $data['payload'], $node['payload'] ); $branchPrefix = $node['branch']; for( $i = 0; $i < 200; ++$i ) { if ($x) { $data = array( 'xid' => $x, 'payload' => rand( 1, 100000 ) ); $id = $tree->addChild( null, $data ); } $data = array( 'payload' => rand( 1, 100000 ) ); $id = $tree->addChild( $pid, $data ); $node = $tree->get( $id ); $this->assertEqual( $data['payload'], $node['payload'] ); if ($caseSensitive) { $this->assertBranchSpotCS( $i, $node, $branchPrefix ); } else { $this->assertBranchSpotCI( $i, $node, $branchPrefix ); } } } /** * helper function to get parent nodes * * @param WBDatasource_Tree $tree */ public function getParentNodes( $tree ) { $id = null; $new = null; for( $i = 0; $i < 10; ++$i ) { for( $j = 0; $j< 5; ++$j ) { $data = array( 'payload' => rand( 1, 100000 ) ); $new = $tree->addChild( $id, $data ); $node = $tree->get( $new ); $this->assertEqual( $data['payload'], $node['payload'] ); } $parent = $tree->getParent( $new, 1 ); $parent2 = $tree->getParent( $new, 2 ); $parent3 = $tree->getParent( $new, 3 ); $parents = $tree->getParent( $new, 0 ); if( $id == null ) { $this->assertNull( $parent ); $this->assertNull( $parent2 ); $this->assertNull( $parent3 ); $this->assertNull( $parents ); } else { $this->assertEqual( count( $parent ), 1 ); $this->assertEqual( count( $parents ), $i ); switch( $i ) { case 1: $this->assertEqual( count( $parent2 ), 1 ); $this->assertEqual( count( $parent3 ), 1 ); break; case 2: $this->assertEqual( count( $parent2 ), 2 ); $this->assertEqual( count( $parent3 ), 2 ); break; default: $this->assertEqual( count( $parent2 ), 2 ); $this->assertEqual( count( $parent3 ), 3 ); break; } } $id = $new; } } /** * helper function to get child nodes * * @param WBDatasource_Tree $tree */ public function getChildren( $tree ) { // add root child $data = array( 'payload' => rand( 1, 100000 ) ); $rid = $tree->addChild( null, $data ); $node = $tree->get( $rid ); $this->assertEqual( $data['payload'], $node['payload'] ); // add parent child $data = array( 'payload' => rand( 1, 100000 ) ); $pid = $tree->addChild( $rid, $data ); $node = $tree->get( $pid ); $this->assertEqual( $data['payload'], $node['payload'] ); // add some uncles for( $i = 0; $i < 7; ++$i ) { $data = array( 'payload' => rand( 1, 100000 ) ); $uid = $tree->addChild( $rid, $data ); $node = $tree->get( $uid ); $this->assertEqual( $data['payload'], $node['payload'] ); } // assert $children = $tree->getChildren( $rid ); $this->assertEqual( count( $children ), 8 ); $children = $tree->getChildren( $rid, 2 ); $this->assertEqual( count( $children ), 8 ); $children = $tree->getChildren( $rid, 0 ); $this->assertEqual( count( $children ), 8 ); // add grand child for( $i = 0; $i < 10; ++$i ) { $data = array( 'payload' => rand( 1, 100000 ) ); $cid = $tree->addChild( $pid, $data ); $node = $tree->get( $cid ); $this->assertEqual( $data['payload'], $node['payload'] ); // grand grand children if( $i % 2 ) { for( $j = 0; $j < 5; ++$j ) { $data = array( 'payload' => rand( 1, 100000 ) ); $id = $tree->addChild( $cid, $data ); $node = $tree->get( $id ); $this->assertEqual( $data['payload'], $node['payload'] ); } } } // assert $children = $tree->getChildren( $rid ); $this->assertEqual( count( $children ), 8 ); $children = $tree->getChildren( $rid, 1 ); $this->assertEqual( count( $children ), 8 ); $children = $tree->getChildren( $rid, 2 ); $this->assertEqual( count( $children ), 18 ); $children = $tree->getChildren( $rid, 3 ); $this->assertEqual( count( $children ), 43 ); $children = $tree->getChildren( $rid, 4 ); $this->assertEqual( count( $children ), 43 ); $children = $tree->getChildren( $rid, 0 ); $this->assertEqual( count( $children ), 43 ); $children = $tree->getChildren( $pid ); $this->assertEqual( count( $children ), 10 ); $children = $tree->getChildren( $pid, 1 ); $this->assertEqual( count( $children ), 10 ); $children = $tree->getChildren( $pid, 2 ); $this->assertEqual( count( $children ), 35 ); $children = $tree->getChildren( $pid, 3 ); $this->assertEqual( count( $children ), 35 ); $children = $tree->getChildren( $pid, 0 ); $this->assertEqual( count( $children ), 35 ); } /** * Helper function to remove children * * @param WBDatasource_Tree $tree */ public function deleteChildNodes( $tree ) { // add root child $data = array( 'payload' => rand( 1, 100000 ) ); $rid = $tree->addChild( null, $data ); $node = $tree->get( $rid ); $this->assertEqual( $data['payload'], $node['payload'] ); // add parent child $data = array( 'payload' => rand( 1, 100000 ) ); $pid = $tree->addChild( $rid, $data ); $node = $tree->get( $pid ); $this->assertEqual( $data['payload'], $node['payload'] ); // add some uncles for( $i = 0; $i < 7; ++$i ) { $data = array( 'payload' => rand( 1, 100000 ) ); $uid = $tree->addChild( $rid, $data ); $node = $tree->get( $uid ); $this->assertEqual( $data['payload'], $node['payload'] ); } // add grand child for( $i = 0; $i < 10; ++$i ) { $data = array( 'payload' => rand( 1, 100000 ) ); $cid = $tree->addChild( $pid, $data ); $node = $tree->get( $cid ); $this->assertEqual( $data['payload'], $node['payload'] ); } $this->assertEqual( $tree->delete( $pid ), 11 ); $this->assertEqual( $tree->delete( $rid ), 8 ); } public function moveChild($tree) { // add root child $data = array( 'payload' => rand( 1, 100000 ) ); $pid = $tree->addChild( null, $data ); $node = $tree->get( $pid ); $this->assertEqual( $data['payload'], $node['payload'] ); $branchPrefix = $node['branch']; $src = array(); $des = array(); // add some children for ($i = 0; $i < 10; ++$i) { $data = array( 'payload' => rand( 1, 100000 ) ); $id = $tree->addChild( $pid, $data ); $node = $tree->get( $id ); $this->assertEqual( $data['payload'], $node['payload'] ); // add some grandchildren for ($j=0; $j < 10; ++$j) { $data = array( 'payload' => rand( 1, 100000 ) ); $gid = $tree->addChild( $id, $data ); $node = $tree->get( $gid ); $this->assertEqual( $data['payload'], $node['payload'] ); if ($i == 3 && $j == 3) { $src[] = $id; $src[] = $gid; } if ($i == 2 && $j == 2) { $des[] = $id; $des[] = $gid; } } } // finally test something... for ($i = 0; $i < count($src); ++$i) { $id = $tree->moveChild($src[$i], $des[$i]); $this->assertEqual($id, $src[$i]); // verify parent's id $parent = $tree->getParent($src[$i]); $this->assertEqual($des[$i], $parent[0]['id']); // move the whole lot to root $id = $tree->moveChild($des[$i], null); $this->assertEqual($id, $des[$i]); $parent = $tree->getParent($des[$i]); $this->assertNull($parent[0]['id']); } } /** * asserts for case insensitive trees * * @param int $i * @param array $node * @param string $prefix */ protected function assertBranchSpotCI( $i, $node, $prefix = '' ) { // spot check of some branches switch( $i ) { case 0: $this->assertBranch( '+++', $node, $prefix ); break; case 10: $this->assertBranch( '++6', $node, $prefix ); break; case 20: $this->assertBranch( '++F', $node, $prefix ); break; case 30: $this->assertBranch( '++P', $node, $prefix ); break; case 40: $this->assertBranch( '++Z', $node, $prefix ); break; case 41: $this->assertBranch( '+-+', $node, $prefix ); break; case 50: $this->assertBranch( '+-5', $node, $prefix ); break; case 60: $this->assertBranch( '+-E', $node, $prefix ); break; case 70: $this->assertBranch( '+-O', $node, $prefix ); break; case 80: $this->assertBranch( '+-Y', $node, $prefix ); break; case 82: $this->assertBranch( '+.+', $node, $prefix ); break; case 90: $this->assertBranch( '+.4', $node, $prefix ); break; default: break; } } /** * asserts for case sensitive trees * * @param int $i * @param array $node * @param string $prefix */ protected function assertBranchSpotCS( $i, $node, $prefix = '' ) { // spot check of some branches switch( $i ) { case 0: $this->assertBranch( '+++', $node, $prefix ); break; case 10: $this->assertBranch( '++6', $node, $prefix ); break; case 20: $this->assertBranch( '++F', $node, $prefix ); break; case 30: $this->assertBranch( '++P', $node, $prefix ); break; case 40: $this->assertBranch( '++Z', $node, $prefix ); break; case 41: $this->assertBranch( '++a', $node, $prefix ); break; case 50: $this->assertBranch( '++j', $node, $prefix ); break; case 60: $this->assertBranch( '++t', $node, $prefix ); break; case 66: $this->assertBranch( '++z', $node, $prefix ); break; case 67: $this->assertBranch( '+-+', $node, $prefix ); break; case 70: $this->assertBranch( '+-/', $node, $prefix ); break; case 80: $this->assertBranch( '+-9', $node, $prefix ); break; case 90: $this->assertBranch( '+-I', $node, $prefix ); break; case 133: $this->assertBranch( '+-z', $node, $prefix ); break; case 134: $this->assertBranch( '+.+', $node, $prefix ); break; case 199: $this->assertBranch( '+.y', $node, $prefix ); break; default: break; } } /** * assert branch's path * * @param string $branch * @param array $node * @param string $prefix */ protected function assertBranch( $branch, $node, $prefix = '' ) { $this->assertEqual( $prefix . $branch, $node['branch'] ); } } ?>