X-Git-Url: http://www.aleph1.co.uk/gitweb/?p=yaffs-website;a=blobdiff_plain;f=vendor%2Fgabordemooij%2Fredbean%2Ftesting%2FRedUNIT%2FBase%2FAliasing.php;fp=vendor%2Fgabordemooij%2Fredbean%2Ftesting%2FRedUNIT%2FBase%2FAliasing.php;h=ee9bda685ed56dac7970b3483f5d233aef83ab74;hp=0000000000000000000000000000000000000000;hb=eba34333e3c89f208d2f72fa91351ad019a71583;hpb=a2bd1bf0c2c1f1a17d188f4dc0726a45494cefae diff --git a/vendor/gabordemooij/redbean/testing/RedUNIT/Base/Aliasing.php b/vendor/gabordemooij/redbean/testing/RedUNIT/Base/Aliasing.php new file mode 100644 index 000000000..ee9bda685 --- /dev/null +++ b/vendor/gabordemooij/redbean/testing/RedUNIT/Base/Aliasing.php @@ -0,0 +1,439 @@ +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 ); + } +}