+++ /dev/null
-<?php
-
-namespace RedUNIT\Base;
-
-use RedUNIT\Base as Base;
-use RedBeanPHP\Facade as R;
-use RedBeanPHP\RedException as RedException;
-use RedBeanPHP\OODBBean as OODBBean;
-
-/**
- * Aliasing
- *
- * Tests aliasing functionality, i.e. fetching beans as,
- * inferring correct type and retrieving lists as alias.
- *
- * @file RedUNIT/Base/Aliasing.php
- * @desc Tests for nested beans with aliases, i.e. teacher alias for person etc.
- * @author Gabor de Mooij and the RedBeanPHP Community
- * @license New BSD/GPLv2
- *
- * (c) G.J.G.T. (Gabor) de Mooij and the RedBeanPHP Community.
- * This source file is subject to the New BSD/GPLv2 License that is bundled
- * with this source code in the file license.txt.
- */
-class Aliasing extends Base
-{
- /**
- * Tests automatic resolvement of parent beans
- * without fetchAs() using inferFetchType (foreign keys).
- *
- * @return void
- */
- public function testAutoResolver()
- {
- R::nuke();
- list( $project, $teacher, $student ) = R::dispenseAll( 'project,person,person' );
- $teacher->name = 'teacher';
- $student->name = 'student';
- $project->teacher = $teacher;
- $project->student = $student;
- R::store( $project );
- $project = $project->fresh();
- asrt( ( $project->teacher instanceof OODBBean), TRUE );
- asrt( ( $project->student instanceof OODBBean), TRUE );
- asrt( $project->teacher->name, 'teacher' );
- asrt( $project->student->name, 'student' );
- $project2 = R::dispense( 'project' );
- $teacher2 = R::dispense( 'person' );
- $teacher2->name = 'teacher2';
- $project2->teacher = $teacher2;
- R::store( $project2 );
- $project2 = $project2->fresh();
- asrt( ( $project2->teacher instanceof OODBBean), TRUE );
- asrt( $project2->teacher->name, 'teacher2' );
- asrt( is_null( $project2->student ), TRUE );
- $project = $project->fresh();
- asrt( ( $project->fetchAs('person')->teacher instanceof OODBBean), TRUE );
- asrt( ( $project->fetchAs('person')->student instanceof OODBBean), TRUE );
- asrt( $project->fetchAs('person')->teacher->name, 'teacher' );
- asrt( $project->fetchAs('person')->student->name, 'student' );
- $project = $project->fresh();
- $export = R::exportAll( array( $project ), TRUE );
- asrt( isset( $export[0]['teacher']['name'] ), TRUE );
- asrt( isset( $export[0]['student']['name'] ), TRUE );
- asrt( $export[0]['teacher']['name'], 'teacher' );
- asrt( $export[0]['student']['name'], 'student' );
- //Also test the default implementation...
- $nullWriter = new \NullWriter( R::getDatabaseAdapter() );
- asrt( is_null( $nullWriter->inferFetchType( 'test', 'test' ) ), TRUE );
- //Realteacher should take precedence over fetchAs-teacher, name conventions first!
- //also: ensure we do not use autoresolv for anything except when truly necessary! (performance)
- $realTeacher = R::dispense( 'teacher' );
- $realTeacher->name = 'real';
- R::store( $realTeacher );
- //ID must be same
- asrt( $realTeacher->id, $teacher->id );
- $project = $project->fresh();
- asrt( $project->teacher->name, 'real' );
- }
-
- /**
- * Test for aliasing issue for LTS version.
- *
- * @return void
- */
- public function testIssueAliasingForLTSVersion() {
- $person = R::dispense('person');
- $pro = R::dispense('project');
- $c = R::dispense('course');
- $person->name = 'x';
- $person->alias('teacher')->ownProject[] = $pro;
- $person->alias('student')->ownCourse[] = $c;
- R::store($person);
- asrt($c->fresh()->fetchAs('person')->student->name, 'x');
- asrt($pro->fresh()->fetchAs('person')->teacher->name, 'x');
- $person = $person->fresh();
- $person->alias('teacher')->ownProject = array();
- $person->alias('student')->ownCourse = array();
- R::store($person);
- asrt($c->fresh()->fetchAs('person')->student, NULL);
- asrt($pro->fresh()->fetchAs('person')->teacher, NULL);
- }
-
- /**
- * Describing how clearing state of bean works.
- * Every method returning somthing (except getID)
- * clears prefix-method-state (anything set by withCond,with,alias,fetchAs).
- *
- * @return void
- */
- public function clearStateAdditionalTests()
- {
- list( $project1, $project2 ) = R::dispense( 'project', 2 );
- list( $irene, $ilse ) = R::dispense('person', 2);
- $project1->developer = $ilse;
- $project1->designer = $irene;
- $ilse->name = 'Ilse';
- $irene->name = 'Irene';
- $project2->developer = $ilse;
- R::storeAll( array( $project1, $project2 ) );
- $ilse = R::load( 'person', $ilse->id );
- asrt( count( $ilse->alias( 'developer' )->ownProject ), 2);
- //cached - same list
- asrt( count( $ilse->ownProject ), 2);
- asrt( count( $ilse->alias( 'designer' )->ownProject ), 0);
- //cached - same list
- asrt( count( $ilse->ownProject ), 0);
- //now test state
- asrt( count( $ilse->setAttr( 'a', 'b' )->alias( 'developer' )->ownProject ), 2);
- //now test state
- $ilse = $ilse->fresh();
- //attr clears state...
- asrt( count( $ilse->alias( 'developer' )->setAttr( 'a', 'b' )->ownProject ), 0);
- //but getID() does not!
- $ilse = $ilse->fresh();
- $ilse->alias('developer');
- $ilse->getID();
- asrt( count( $ilse->ownProject ), 2 );
- }
-
- /**
- * Can switch fetchAs().
- * Also checks shadow by storing.
- *
- * @return void
- */
- public function canSwitchParentBean()
- {
- list( $project1, $project2 ) = R::dispense( 'project', 2 );
- list( $irene, $ilse ) = R::dispense('person', 2);
- $project1->developer = $ilse;
- $project1->designer = $irene;
- $ilse->name = 'Ilse';
- $irene->name = 'Irene';
- $project2->developer = $ilse;
- R::storeAll( array( $project1, $project2 ) );
- $project1 = R::load( 'project', $project1->id );
- asrt( $project1->fetchAs('person')->developer->name, 'Ilse' );
- asrt( $project1->fetchAs('person')->designer->name, 'Irene' );
- R::store( $project1 );
- $project1 = R::load( 'project', $project1->id );
- asrt( $project1->fetchAs('person')->designer->name, 'Irene' );
- asrt( $project1->fetchAs('person')->developer->name, 'Ilse' );
- R::store( $project1 );
- asrt( $project1->fetchAs('person')->developer->name, 'Ilse' );
- asrt( $project1->fetchAs('person')->designer->name, 'Irene' );
- asrt( $project1->fetchAs('person')->developer->name, 'Ilse' );
- }
-
- /**
- * Switching aliases (->alias) should not change other list during
- * storage.
- *
- * @return void
- */
- public function testShadow()
- {
- list( $project1, $project2 ) = R::dispense( 'project', 2 );
- list( $irene, $ilse ) = R::dispense('person', 2);
- $project1->developer = $ilse;
- $project1->designer = $irene;
- $project2->developer = $ilse;
- R::storeAll( array( $project1, $project2 ) );
- $ilse = R::load( 'person', $ilse->id );
- $irene = R::load( 'person', $irene->id );
- asrt( count( $ilse->alias('developer')->ownProject ), 2 );
- asrt( count( $ilse->alias('designer')->ownProject ), 0 );
- R::store( $ilse );
- $ilse = R::load( 'person', $ilse->id );
- $irene = R::load( 'person', $irene->id );
- asrt( count( $ilse->alias('designer')->ownProject ), 0 );
- asrt( count( $ilse->alias('developer')->ownProject ), 2 );
- R::storeAll( array( $ilse, $irene) );
- $ilse = R::load( 'person', $ilse->id );
- $irene = R::load( 'person', $irene->id );
- asrt( count( $ilse->alias('designer')->ownProject ), 0 );
- asrt( count( $ilse->alias('developer')->ownProject ), 2 );
- asrt( count( $irene->alias('designer')->ownProject), 1 );
- asrt( count( $irene->alias('developer')->ownProject), 0 );
- R::storeAll( array( $ilse, $irene) );
- $ilse = R::load( 'person', $ilse->id );
- $irene = R::load( 'person', $irene->id );
- asrt( count( $ilse->alias('designer')->ownProject ), 0 );
- asrt( count( $ilse->alias('developer')->ownProject ), 2 );
- asrt( count( $irene->alias('designer')->ownProject), 1 );
- asrt( count( $irene->alias('developer')->ownProject), 0 );
- }
-
- /**
- * Issue 291. State not cleared.
- *
- * @return void
- */
- public function testFetchTypeConfusionIssue291()
- {
- list( $teacher, $student ) = R::dispense( 'person', 2 ) ;
- $teacher->name = 'jimmy' ;
- $student->name = 'jacko' ;
- R::store( $teacher ) ;
- R::store( $student ) ;
- $client = R::dispense( 'client' ) ;
- $client->firm = 'bean AG' ;
- R::store( $client ) ;
- $project = R::dispense( 'project' ) ;
- $project->teacher = $teacher ;
- $project->student = $student ;
- $project->client = $client ;
- R::store( $project ) ;
- unset( $project->student ) ;
- R::store( $project ) ;
- $project = R::load( 'project', 1 ) ;
- $teacher = $project->fetchAs( 'person' )->teacher ;
- $student = $project->fetchAs( 'person' )->student ;
- $client = $project->client ; // this will select from "person" instead of "client"
- asrt( $client->firm, 'bean AG' );
- }
-
- /**
- * Test switching alias (also issue #291).
- *
- * @return void
- */
- public function testAliasSwitch()
- {
- $student = R::dispense( 'person' );
- $project = R::dispense( 'project' );
- $project->student = $student;
- R::store( $project );
- $person = R::load( 'person', $student->id );
- asrt( count( $person->alias( 'student' )->ownProject ), 1);
- asrt( count( $person->alias( 'teacher' )->ownProject ), 0);
- }
-
- /**
- * Associating two beans, then loading the associated bean
- *
- * @return void
- */
- public function testAssociated()
- {
- $person = R::dispense( 'person' );
- $person->name = 'John';
- R::store( $person );
- $course = R::dispense( 'course' );
- $course->name = 'Math';
-
- R::store( $course );
- $course->teacher = $person;
- $id = R::store( $course );
- $course = R::load( 'course', $id );
- $teacher = $course->fetchAs( 'person' )->teacher;
- asrt( $teacher->name, 'John' );
-
- //Trying to load a property that has an invalid name
- $book = R::dispense( 'book' );
- $page = R::dispense( 'page' );
- $book->wrongProperty = array( $page );
- try {
- $book->wrongProperty[] = $page;
- R::store( $book );
- fail();
- } catch ( RedException $e ) {
- pass();
- } catch ( \Exception $e ) {
- fail();
- }
- }
-
- /**
- * Test for quick detect change.
- *
- * @return void
- */
- public function basic()
- {
- $book = R::dispense( 'book' );
-
- asrt( isset( $book->prop ), FALSE ); //not a very good test
- asrt( in_array( 'prop', array_keys( $book->export() ) ), FALSE ); //better...
-
- $book = R::dispense( 'book' );
- $page = R::dispense( 'page' );
-
- $book->paper = $page;
-
- $id = R::store( $book );
- $book = R::load( 'book', $id );
-
- asrt( FALSE, ( isset( $book->paper ) ) );
- asrt( FALSE, ( isset( $book->page ) ) );
-
- /**
- * The following tests try to store various things that aren't
- * beans (which is expected) with the own* and shared* properties
- * which only accept beans as assignments, so they're expected to fail
- */
- foreach ( array( 'a string', 1928, TRUE, NULL, array()) as $value ) {
- try {
- $book->ownPage[] = $value;
- R::store( $book );
- $book->sharedPage[] = $value;
- R::store( $book );
- fail();
- } catch ( RedException $e ) {
- pass();
- } catch ( \Exception $e ) {
- fail();
- }
- }
- }
-
- /**
- * Finding $person beans that have been aliased into various roles
- *
- * @return void
- */
- public function testAliasedFinder()
- {
- $message = R::dispense( 'message' );
- $message->subject = 'Roommate agreement';
- list( $sender, $recipient ) = R::dispense( 'person', 2 );
- $sender->name = 'Sheldon';
- $recipient->name = 'Leonard';
- $message->sender = $sender;
- $message->recipient = $recipient;
- $id = R::store( $message );
- $message = R::load( 'message', $id );
- asrt( $message->fetchAs( 'person' )->sender->name, 'Sheldon' );
- asrt( $message->fetchAs( 'person' )->recipient->name, 'Leonard' );
- $otherRecipient = R::dispense( 'person' );
- $otherRecipient->name = 'Penny';
- $message->recipient = $otherRecipient;
- R::store( $message );
- $message = R::load( 'message', $id );
- asrt( $message->fetchAs( 'person' )->sender->name, 'Sheldon' );
- asrt( $message->fetchAs( 'person' )->recipient->name, 'Penny' );
- }
-
- /**
- * Test Basic Fetch AS functionality.
- */
- public function testBasicFetchAs()
- {
- $project = R::dispense( 'project' );
- $project->name = 'Mutant Project';
- list( $teacher, $student ) = R::dispense( 'person', 2 );
- $teacher->name = 'Charles Xavier';
- $project->student = $student;
- $project->student->name = 'Wolverine';
- $project->teacher = $teacher;
- $id = R::store( $project );
- $project = R::load( 'project', $id );
- asrt( $project->fetchAs( 'person' )->teacher->name, 'Charles Xavier' );
- asrt( $project->fetchAs( 'person' )->student->name, 'Wolverine' );
- }
-
- /**
- * Test Basic list variations.
- *
- * @return void
- */
- public function testBasicListVariations()
- {
- $farm = R::dispense( 'building' );
- $village = R::dispense( 'village' );
- $farm->name = 'farm';
- $village->name = 'Dusty Mountains';
- $farm->village = $village;
- $id = R::store( $farm );
- $farm = R::load( 'building', $id );
- asrt( $farm->name, 'farm' );
- asrt( $farm->village->name, 'Dusty Mountains' );
- $village = R::dispense( 'village' );
- list( $mill, $tavern ) = R::dispense( 'building', 2 );
- $mill->name = 'Mill';
- $tavern->name = 'Tavern';
- $village->ownBuilding = array( $mill, $tavern );
- $id = R::store( $village );
- $village = R::load( 'village', $id );
- asrt( count( $village->ownBuilding ), 2 );
- $village2 = R::dispense( 'village' );
- $army = R::dispense( 'army' );
- $village->sharedArmy[] = $army;
- $village2->sharedArmy[] = $army;
- $id1 = R::store( $village );
- $id2 = R::store( $village2 );
- $village1 = R::load( 'village', $id1 );
- $village2 = R::load( 'village', $id2 );
- asrt( count( $village1->sharedArmy ), 1 );
- asrt( count( $village2->sharedArmy ), 1 );
- asrt( count( $village1->ownArmy ), 0 );
- asrt( count( $village2->ownArmy ), 0 );
- }
-
- /**
- * Tests whether aliasing plays nice with beautification.
- * Ensure that aliased column aren't beautified
- *
- * @return void
- */
- public function testAliasWithBeautify()
- {
- $points = R::dispense( 'point', 2 );
- $line = R::dispense( 'line' );
- $line->pointA = $points[0];
- $line->pointB = $points[1];
- R::store( $line );
- $line2 = R::dispense( 'line' );
- $line2->pointA = $line->fetchAs('point')->pointA;
- $line2->pointB = R::dispense( 'point' );
- R::store( $line2 );
-
- //now we have two points per line (1-to-x)
- //I want to know which lines cross A:
- $a = R::load( 'point', $line->pointA->id ); //reload A
- $lines = $a->alias( 'pointA' )->ownLine;
- asrt( count( $lines ), 2 );
- }
-}