MediaWiki  REL1_22
ApiQueryContinueTestBase.php
Go to the documentation of this file.
00001 <?php
00027 require_once 'ApiQueryTestBase.php';
00028 
00029 abstract class ApiQueryContinueTestBase extends ApiQueryTestBase {
00030 
00034     protected $mVerbose = false;
00035 
00039     protected function checkC( $expected, $params, $expectedCount, $id, $continue = true ) {
00040         $result = $this->query( $params, $expectedCount, $id, $continue );
00041         $this->assertResult( $expected, $result, $id );
00042     }
00043 
00053     protected function query( $params, $expectedCount, $id, $useContinue = true ) {
00054         if ( isset( $params['action'] ) ) {
00055             $this->assertEquals( 'query', $params['action'], 'Invalid query action' );
00056         } else {
00057             $params['action'] = 'query';
00058         }
00059         if ( $useContinue && !isset( $params['continue'] ) ) {
00060             $params['continue'] = '';
00061         }
00062         $count = 0;
00063         $result = array();
00064         $continue = array();
00065         do {
00066             $request = array_merge( $params, $continue );
00067             uksort( $request, function ( $a, $b ) {
00068                 // put 'continue' params at the end - lazy method
00069                 $a = strpos( $a, 'continue' ) !== false ? 'zzz ' . $a : $a;
00070                 $b = strpos( $b, 'continue' ) !== false ? 'zzz ' . $b : $b;
00071 
00072                 return strcmp( $a, $b );
00073             } );
00074             $reqStr = http_build_query( $request );
00075             //$reqStr = str_replace( '&', ' & ', $reqStr );
00076             $this->assertLessThan( $expectedCount, $count, "$id more data: $reqStr" );
00077             if ( $this->mVerbose ) {
00078                 print "$id (#$count): $reqStr\n";
00079             }
00080             try {
00081                 $data = $this->doApiRequest( $request );
00082             } catch ( Exception $e ) {
00083                 throw new Exception( "$id on $count", 0, $e );
00084             }
00085             $data = $data[0];
00086             if ( isset( $data['warnings'] ) ) {
00087                 $warnings = json_encode( $data['warnings'] );
00088                 $this->fail( "$id Warnings on #$count in $reqStr\n$warnings" );
00089             }
00090             $this->assertArrayHasKey( 'query', $data, "$id no 'query' on #$count in $reqStr" );
00091             if ( isset( $data['continue'] ) ) {
00092                 $continue = $data['continue'];
00093                 unset( $data['continue'] );
00094             } else {
00095                 $continue = array();
00096             }
00097             if ( $this->mVerbose ) {
00098                 $this->printResult( $data );
00099             }
00100             $this->mergeResult( $result, $data );
00101             $count++;
00102             if ( empty( $continue ) ) {
00103                 // $this->assertEquals( $expectedCount, $count, "$id finished early" );
00104                 if ( $expectedCount > $count ) {
00105                     print "***** $id Finished early in $count turns. $expectedCount was expected\n";
00106                 }
00107 
00108                 return $result;
00109             } elseif ( !$useContinue ) {
00110                 $this->assertFalse( 'Non-smart query must be requested all at once' );
00111             }
00112         } while ( true );
00113     }
00114 
00115     private function printResult( $data ) {
00116         $q = $data['query'];
00117         $print = array();
00118         if ( isset( $q['pages'] ) ) {
00119             foreach ( $q['pages'] as $p ) {
00120                 $m = $p['title'];
00121                 if ( isset( $p['links'] ) ) {
00122                     $m .= '/[' . implode( ',', array_map(
00123                         function ( $v ) {
00124                             return $v['title'];
00125                         },
00126                         $p['links'] ) ) . ']';
00127                 }
00128                 if ( isset( $p['categories'] ) ) {
00129                     $m .= '/(' . implode( ',', array_map(
00130                         function ( $v ) {
00131                             return str_replace( 'Category:', '', $v['title'] );
00132                         },
00133                         $p['categories'] ) ) . ')';
00134                 }
00135                 $print[] = $m;
00136             }
00137         }
00138         if ( isset( $q['allcategories'] ) ) {
00139             $print[] = '*Cats/(' . implode( ',', array_map(
00140                 function ( $v ) {
00141                     return $v['*'];
00142                 },
00143                 $q['allcategories'] ) ) . ')';
00144         }
00145         self::GetItems( $q, 'allpages', 'Pages', $print );
00146         self::GetItems( $q, 'alllinks', 'Links', $print );
00147         self::GetItems( $q, 'alltransclusions', 'Trnscl', $print );
00148         print ' ' . implode( '  ', $print ) . "\n";
00149     }
00150 
00151     private static function GetItems( $q, $moduleName, $name, &$print ) {
00152         if ( isset( $q[$moduleName] ) ) {
00153             $print[] = "*$name/[" . implode( ',',
00154                 array_map( function ( $v ) {
00155                         return $v['title'];
00156                     },
00157                     $q[$moduleName] ) ) . ']';
00158         }
00159     }
00160 
00167     protected function mergeResult( &$results, $newResult, $numericIds = false ) {
00168         $this->assertEquals( is_array( $results ), is_array( $newResult ), 'Type of result and data do not match' );
00169         if ( !is_array( $results ) ) {
00170             $this->assertEquals( $results, $newResult, 'Repeated result must be the same as before' );
00171         } else {
00172             $sort = null;
00173             foreach ( $newResult as $key => $value ) {
00174                 if ( !$numericIds && $sort === null ) {
00175                     if ( !is_array( $value ) ) {
00176                         $sort = false;
00177                     } elseif ( array_key_exists( 'title', $value ) ) {
00178                         $sort = function ( $a, $b ) {
00179                             return strcmp( $a['title'], $b['title'] );
00180                         };
00181                     } else {
00182                         $sort = false;
00183                     }
00184                 }
00185                 $keyExists = array_key_exists( $key, $results );
00186                 if ( is_numeric( $key ) ) {
00187                     if ( $numericIds ) {
00188                         if ( !$keyExists ) {
00189                             $results[$key] = $value;
00190                         } else {
00191                             $this->mergeResult( $results[$key], $value );
00192                         }
00193                     } else {
00194                         $results[] = $value;
00195                     }
00196                 } elseif ( !$keyExists ) {
00197                     $results[$key] = $value;
00198                 } else {
00199                     $this->mergeResult( $results[$key], $value, $key === 'pages' );
00200                 }
00201             }
00202             if ( $numericIds ) {
00203                 ksort( $results, SORT_NUMERIC );
00204             } elseif ( $sort !== null && $sort !== false ) {
00205                 uasort( $results, $sort );
00206             }
00207         }
00208     }
00209 }