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