4 * Convenience function for test hook.
5 * If you added the proper Writer class, the facade should be able
6 * to automatically load it, i.e. \RedBeanPHP\QueryWriter\MyWriter
10 * @param string $name name of the connection (key)
11 * @param string $dsn DSN to connect
12 * @param string $user username
13 * @param string $pass passwords
15 function add_writer_to_tests( $name, $dsn, $user, $pass )
20 \RedUNIT\Base::addToDriverList( $name );
21 R::addDatabase( $name, $dsn, $user, $pass );
27 * A simple print function that works
28 * both for CLI and HTML.
32 function printtext( $text )
34 if ( $_SERVER["DOCUMENT_ROOT"] ) {
42 * Tests whether a === b. The minimalistic core of this little
43 * unit test framework.
45 * @global integer $tests
47 * @param mixed $a value for A
48 * @param mixed $b value for B
50 function asrt( $a, $b )
57 print( "[" . $tests . "]" );
59 printtext( "FAILED TEST: EXPECTED $b BUT GOT: $a " );
66 * called when a test is passed. prints the test number to the screen.
74 print( "[" . $tests . "]" );
78 * called when a test fails. shows debug info and exits.
82 printtext( "FAILED TEST" );
84 debug_print_backtrace();
90 * prints out the name of the current test pack.
92 * @param string $name name of the test pack
94 function testpack( $name )
96 printtext( "\n\tSub testpack: " . $name . " \n\t" );
100 * prints out the name of the current test pack.
102 * @param string $name name of the test pack
104 function maintestpack( $name )
106 printtext( "\n\nTestpack: " . $name . " \n\t" );
110 * Quickly resolves the formatted table name
112 function tbl( $table )
114 return R::$writer->getFormattedTableName( $table );
118 * Quickly resolves the formatted ID
120 function ID( $table )
122 return R::$writer->getIDField( $table );
126 * Emulates legacy function for use with older tests.
128 function set1toNAssoc( $a, \RedBeanPHP\OODBBean $bean1, \RedBeanPHP\OODBBean $bean2 )
130 $type = $bean1->getMeta( "type" );
132 $a->clearRelations( $bean2, $type );
133 $a->associate( $bean1, $bean2 );
135 if ( count( $a->related( $bean2, $type ) ) === 1 ) {
138 throw new \RedBeanPHP\RedException\SQL( "Failed to enforce 1-N Relation for $type " );
143 * Returns all property values of beans as a
144 * comma separated string sorted.
146 * @param array $beans beans
147 * @param string $property name of the property
149 * @return string $values values
151 function getList( $beans, $property )
155 foreach ( $beans as $bean ) {
156 $items[] = $bean->$property;
161 return implode( ",", $items );
165 * Helper function to test IDs
167 * @param array $array array
169 function testids( $array )
171 foreach ( $array as $key => $bean ) {
172 asrt( intval( $key ), intval( $bean->getID() ) );
177 * Group modifier function. Tests random modifications
178 * of groups of beans. For use with tests that test N:1 relation mapping
181 * @param mixed $book3 book
182 * @param mixed $quotes quotes
183 * @param mixed $pictures pictures
184 * @param mixed $topics topics
186 function modgr( $book3, $quotes, $pictures, $topics )
188 $key = array_rand( $quotes );
190 $quote = $quotes[$key];
192 $keyPic = array_rand( $pictures );
194 $picture = $pictures[$keyPic];
196 $keyTop = array_rand( $topics );
198 $topic = $topics[$keyTop];
200 if ( rand( 0, 1 ) ) {
203 foreach ( $book3->ownQuote as $z ) {
204 if ( $z->note == $quote->note ) {
211 //echo "\n add a quote ";
213 $book3->ownQuote[] = $quote;
217 if ( rand( 0, 1 ) ) {
220 foreach ( $book3->ownPicture as $z ) {
221 if ( $z->note == $picture->note ) {
228 // echo "\n add a picture ";
230 $book3->ownPicture[] = $picture;
234 if ( rand( 0, 1 ) ) {
237 foreach ( $book3->sharedTopic as $z ) {
238 if ( $z->note == $topic->note ) {
246 $book3->sharedTopic[] = $topic;
250 if ( rand( 0, 1 ) && count( $book3->ownQuote ) > 0 ) {
251 $key = array_rand( $book3->ownQuote );
253 unset( $book3->ownQuote[$key] );
256 if ( rand( 0, 1 ) && count( $book3->ownPicture ) > 0 ) {
257 $key = array_rand( $book3->ownPicture );
259 unset( $book3->ownPicture[$key] );
262 if ( rand( 0, 1 ) && count( $book3->sharedTopic ) > 0 ) {
263 $key = array_rand( $book3->sharedTopic );
265 unset( $book3->sharedTopic[$key] );
268 if ( rand( 0, 1 ) && count( $book3->ownPicture ) > 0 ) {
269 $key = array_rand( $book3->ownPicture );
271 $book3->ownPicture[$key]->change = rand( 0, 100 );
274 if ( rand( 0, 1 ) && count( $book3->ownQuote ) > 0 ) {
275 $key = array_rand( $book3->ownQuote );
277 $book3->ownQuote[$key]->change = 'note ch ' . rand( 0, 100 );
280 if ( rand( 0, 1 ) && count( $book3->sharedTopic ) > 0 ) {
281 $key = array_rand( $book3->sharedTopic );
283 $book3->sharedTopic[$key]->change = rand( 0, 100 );
288 * SetGet function, sets a value in a bean and retrieves it again
289 * after storage, useful for tests that want to make sure the same value
290 * that gets in, comes out again.
292 * @param mixed $val the value that needs to be preserved
294 * @return mixed $val the value as returned after storage-retrieval cycle.
296 function setget( $val )
300 $bean = R::dispense( "page" );
304 $id = R::store( $bean );
306 $bean = R::load( "page", $id );
312 * Wrapper function to test BeanCan Server, does the boring
315 * @param mixed $data Data for JSON-RPC request object
316 * @param mixed $params Parameters for JSON-RPC request object
317 * @param string $id Identification of JSON-RPC request to connect to response
319 * @return string $out Output JSON from BeanCan server.
321 function fakeBeanCanServerRequest( $data, $params = NULL, $id = "1234", $whiteList = 'all' )
330 $can = new \RedBeanPHP\Plugin\BeanCan;
332 $request = json_encode( $j );
334 $can->setWhitelist( $whiteList );
336 $out = $can->handleJSONRequest( $request );
342 * Candy Cane Factory. Produces lots of candy canes.
344 * @return array $canes canes
346 function candy_canes()
348 $canes = R::dispense( 'cane', 10 );
352 foreach ( $canes as $k => $cane ) {
353 $canes[$k]->label = 'Cane No. ' . ( $i++ );
356 $canes[0]->cane = $canes[1];
357 $canes[1]->cane = $canes[4];
358 $canes[9]->cane = $canes[4];
359 $canes[6]->cane = $canes[4];
360 $canes[4]->cane = $canes[7];
361 $canes[8]->cane = $canes[7];
367 * Returns an array containing the index names of all
368 * indexes on the specified table name.
370 * @param $tableNoQ table name without quotes or backticks
374 function getIndexes( $tableNoQ )
376 $writer = R::getWriter();
378 if ( ( $writer instanceof \RedBeanPHP\QueryWriter\MySQL ) || ( $writer instanceof \RedBeanPHP\QueryWriter\CUBRID ) ) {
380 $list = R::getAll( "SHOW INDEX FROM `{$tableNoQ}`" );
381 foreach( $list as $listItem ) {
382 $indexes[] = $listItem['Key_name'];
387 if ( ( $writer instanceof \RedBeanPHP\QueryWriter\SQLiteT ) ) {
389 $list = R::getAll( " pragma index_list(`{$tableNoQ}`) " );
390 foreach( $list as $listItem ) {
391 $indexes[] = $listItem['name'];
396 if ( ( $writer instanceof \RedBeanPHP\QueryWriter\PostgreSQL ) ) {
397 return R::getCol( " SELECT indexname FROM pg_indexes WHERE tablename = '{$tableNoQ}' AND schemaname = 'public' " );
403 function are_cols_in_unique( $type, $properties )
406 $propertyFootprint = implode( ',', $properties );
407 $uniques = get_uniques_for_type( $type );
408 foreach( $uniques as $unique ) {
410 $uniqueFootprint = implode( ',', $unique );
411 if ( $uniqueFootprint === $propertyFootprint ) return TRUE;
416 function get_uniques_for_type( $type )
419 $writer = R::getWriter();
420 $adapter = R::getDatabaseAdapter();
421 global $currentDriver;
422 switch( $currentDriver ) {
424 $table = $writer->esc( $type, TRUE );
425 $columns = $adapter->get('
427 information_schema.key_column_usage.constraint_name,
428 information_schema.key_column_usage.column_name
430 information_schema.table_constraints
431 INNER JOIN information_schema.key_column_usage
433 information_schema.table_constraints.constraint_name = information_schema.key_column_usage.constraint_name
434 AND information_schema.table_constraints.constraint_schema = information_schema.key_column_usage.constraint_schema
435 AND information_schema.table_constraints.constraint_catalog = information_schema.key_column_usage.constraint_catalog
438 information_schema.table_constraints.table_schema IN (SELECT DATABASE())
439 AND information_schema.table_constraints.table_name = ?
440 AND information_schema.table_constraints.constraint_type = \'UNIQUE\'
441 ', array( $table ) );
443 foreach( $columns as $column ) {
444 if ( !isset( $uniques[ $column['constraint_name'] ] ) ) $uniques[ $column['constraint_name'] ] = array();
445 $uniques[ $column['constraint_name'] ][] = $column['column_name'];
450 $table = $writer->esc( $type, TRUE );
451 $columns = $adapter->get('
453 information_schema.key_column_usage.constraint_name,
454 information_schema.key_column_usage.column_name
456 information_schema.table_constraints
457 INNER JOIN information_schema.key_column_usage
459 information_schema.table_constraints.constraint_name = information_schema.key_column_usage.constraint_name
460 AND information_schema.table_constraints.constraint_schema = information_schema.key_column_usage.constraint_schema
461 AND information_schema.table_constraints.constraint_catalog = information_schema.key_column_usage.constraint_catalog
464 information_schema.table_constraints.table_catalog = current_database()
465 AND information_schema.key_column_usage.table_schema = ANY( current_schemas( FALSE ) )
466 AND information_schema.table_constraints.table_name = ?
467 AND information_schema.table_constraints.constraint_type = \'UNIQUE\'
468 ', array( $table ) );
470 foreach( $columns as $column ) {
471 if ( !isset( $uniques[ $column['constraint_name'] ] ) ) $uniques[ $column['constraint_name'] ] = array();
472 $uniques[ $column['constraint_name'] ][] = $column['column_name'];
478 $table = $writer->esc( $type, TRUE );
479 $indexes = $adapter->get( "PRAGMA index_list({$table})" );
480 foreach( $indexes as $index ) {
481 if ( $index['unique'] == 1 ) {
482 $info = $adapter->get( "PRAGMA index_info({$index['name']})" );
483 if ( !isset( $uniques[$index['name']] ) ) $uniques[$index['name']] = array();
484 foreach( $info as $piece ) {
485 $uniques[$index['name']][] = $piece['name'];
493 $sqlCode = $adapter->get("SHOW CREATE TABLE `{$type}`");
494 } catch ( \Exception $e ) {
497 if (!isset($sqlCode[0])) return array();
499 preg_match_all('/CONSTRAINT\s+\[([\w_]+)\]\s+UNIQUE\s+KEY\s+\(([^\)]+)\)/', $sqlCode[0]['CREATE TABLE'], $matches);
501 if (!isset($matches[0])) return $list;
502 $max = count($matches[0]);
503 for($i = 0; $i < $max; $i++) {
504 $columns = explode(',', $matches[2][$i]);
505 foreach( $columns as $key => $column ) {
506 $columns[$key] = trim( $column, '[] ');
508 $list[ $matches[1][$i] ] = $columns;