MediaWiki
REL1_21
|
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 return strcmp( $a, $b ); 00072 } ); 00073 $reqStr = http_build_query( $request ); 00074 //$reqStr = str_replace( '&', ' & ', $reqStr ); 00075 $this->assertLessThan( $expectedCount, $count, "$id more data: $reqStr" ); 00076 if ( $this->mVerbose ) { 00077 print ("$id (#$count): $reqStr\n"); 00078 } 00079 try { 00080 $data = $this->doApiRequest( $request ); 00081 } catch ( Exception $e ) { 00082 throw new Exception( "$id on $count", 0, $e ); 00083 } 00084 $data = $data[0]; 00085 if ( isset( $data['warnings'] ) ) { 00086 $warnings = json_encode( $data['warnings'] ); 00087 $this->fail( "$id Warnings on #$count in $reqStr\n$warnings" ); 00088 } 00089 $this->assertArrayHasKey( 'query', $data, "$id no 'query' on #$count in $reqStr" ); 00090 if ( isset( $data['continue'] ) ) { 00091 $continue = $data['continue']; 00092 unset( $data['continue'] ); 00093 } else { 00094 $continue = array(); 00095 } 00096 if ( $this->mVerbose ) { 00097 $this->printResult( $data ); 00098 } 00099 $this->mergeResult( $result, $data ); 00100 $count++; 00101 if ( empty( $continue ) ) { 00102 // $this->assertEquals( $expectedCount, $count, "$id finished early" ); 00103 if ( $expectedCount > $count ) { 00104 print "***** $id Finished early in $count turns. $expectedCount was expected\n"; 00105 } 00106 return $result; 00107 } elseif ( !$useContinue ) { 00108 $this->assertFalse( 'Non-smart query must be requested all at once' ); 00109 } 00110 } while( true ); 00111 } 00112 00113 private function printResult( $data ) { 00114 $q = $data['query']; 00115 $print = array(); 00116 if (isset($q['pages'])) { 00117 foreach ($q['pages'] as $p) { 00118 $m = $p['title']; 00119 if (isset($p['links'])) { 00120 $m .= '/[' . implode(',', array_map( 00121 function ($v) { 00122 return $v['title']; 00123 }, 00124 $p['links'])) . ']'; 00125 } 00126 if (isset($p['categories'])) { 00127 $m .= '/(' . implode(',', array_map( 00128 function ($v) { 00129 return str_replace('Category:', '', $v['title']); 00130 }, 00131 $p['categories'])) . ')'; 00132 } 00133 $print[] = $m; 00134 } 00135 } 00136 if (isset($q['allcategories'])) { 00137 $print[] = '*Cats/(' . implode(',', array_map( 00138 function ($v) { return $v['*']; }, 00139 $q['allcategories'])) . ')'; 00140 } 00141 self::GetItems( $q, 'allpages', 'Pages', $print ); 00142 self::GetItems( $q, 'alllinks', 'Links', $print ); 00143 self::GetItems( $q, 'alltransclusions', 'Trnscl', $print ); 00144 print(' ' . implode(' ', $print) . "\n"); 00145 } 00146 00147 private static function GetItems( $q, $moduleName, $name, &$print ) { 00148 if (isset($q[$moduleName])) { 00149 $print[] = "*$name/[" . implode(',', 00150 array_map( function ($v) { return $v['title']; }, 00151 $q[$moduleName])) . ']'; 00152 } 00153 } 00154 00161 protected function mergeResult( &$results, $newResult, $numericIds = false ) { 00162 $this->assertEquals( is_array( $results ), is_array( $newResult ), 'Type of result and data do not match' ); 00163 if ( !is_array( $results ) ) { 00164 $this->assertEquals( $results, $newResult, 'Repeated result must be the same as before' ); 00165 } else { 00166 $sort = null; 00167 foreach( $newResult as $key => $value ) { 00168 if ( !$numericIds && $sort === null ) { 00169 if ( !is_array( $value ) ) { 00170 $sort = false; 00171 } elseif ( array_key_exists( 'title', $value ) ) { 00172 $sort = function( $a, $b ) { 00173 return strcmp( $a['title'], $b['title'] ); 00174 }; 00175 } else { 00176 $sort = false; 00177 } 00178 } 00179 $keyExists = array_key_exists( $key, $results ); 00180 if ( is_numeric( $key ) ) { 00181 if ( $numericIds ) { 00182 if ( !$keyExists ) { 00183 $results[$key] = $value; 00184 } else { 00185 $this->mergeResult( $results[$key], $value ); 00186 } 00187 } else { 00188 $results[] = $value; 00189 } 00190 } elseif ( !$keyExists ) { 00191 $results[$key] = $value; 00192 } else { 00193 $this->mergeResult( $results[$key], $value, $key === 'pages' ); 00194 } 00195 } 00196 if ( $numericIds ) { 00197 ksort( $results, SORT_NUMERIC ); 00198 } elseif ( $sort !== null && $sort !== false ) { 00199 uasort( $results, $sort ); 00200 } 00201 } 00202 } 00203 }