Merge "Make addedwatchtext less verbose"
[lhc/web/wiklou.git] / tests / phpunit / includes / api / query / ApiQueryTestBase.php
1 <?php
2 /**
3 * Created on Feb 10, 2013
4 *
5 * Copyright © 2013 Yuri Astrakhan "<Firstname><Lastname>@gmail.com"
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 3 of the License, or
10 * (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License along
18 * with this program; if not, write to the Free Software Foundation, Inc.,
19 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
20 * http://www.gnu.org/copyleft/gpl.html
21 *
22 * @file
23 */
24
25 /** This class has some common functionality for testing query module
26 */
27 abstract class ApiQueryTestBase extends ApiTestCase {
28
29 const PARAM_ASSERT = <<<STR
30 Each parameter must be an array of two elements,
31 first - an array of params to the API call,
32 and the second array - expected results as returned by the API
33 STR;
34
35 /**
36 * Merges all requests parameter + expected values into one
37 * @param array $v,... List of arrays, each of which contains exactly two
38 * @return array
39 */
40 protected function merge( /*...*/ ) {
41 $request = array();
42 $expected = array();
43 foreach ( func_get_args() as $v ) {
44 list( $req, $exp ) = $this->validateRequestExpectedPair( $v );
45 $request = array_merge_recursive( $request, $req );
46 $this->mergeExpected( $expected, $exp );
47 }
48
49 return array( $request, $expected );
50 }
51
52 /**
53 * Check that the parameter is a valid two element array,
54 * with the first element being API request and the second - expected result
55 * @param array $v
56 * @return array
57 */
58 private function validateRequestExpectedPair( $v ) {
59 $this->assertInternalType( 'array', $v, self::PARAM_ASSERT );
60 $this->assertEquals( 2, count( $v ), self::PARAM_ASSERT );
61 $this->assertArrayHasKey( 0, $v, self::PARAM_ASSERT );
62 $this->assertArrayHasKey( 1, $v, self::PARAM_ASSERT );
63 $this->assertInternalType( 'array', $v[0], self::PARAM_ASSERT );
64 $this->assertInternalType( 'array', $v[1], self::PARAM_ASSERT );
65
66 return $v;
67 }
68
69 /**
70 * Recursively merges the expected values in the $item into the $all
71 * @param array &$all
72 * @param array $item
73 */
74 private function mergeExpected( &$all, $item ) {
75 foreach ( $item as $k => $v ) {
76 if ( array_key_exists( $k, $all ) ) {
77 if ( is_array( $all[$k] ) ) {
78 $this->mergeExpected( $all[$k], $v );
79 } else {
80 $this->assertEquals( $all[$k], $v );
81 }
82 } else {
83 $all[$k] = $v;
84 }
85 }
86 }
87
88 /**
89 * Checks that the request's result matches the expected results.
90 * Assumes no rawcontinue and a complete batch.
91 * @param array $values Array is a two element array( request, expected_results )
92 * @param array $session
93 * @param bool $appendModule
94 * @param User $user
95 */
96 protected function check( $values, array $session = null,
97 $appendModule = false, User $user = null
98 ) {
99 list( $req, $exp ) = $this->validateRequestExpectedPair( $values );
100 if ( !array_key_exists( 'action', $req ) ) {
101 $req['action'] = 'query';
102 }
103 // Silence warning
104 if ( !isset( $params['continue'] ) ) {
105 $params['continue'] = '';
106 }
107 foreach ( $req as &$val ) {
108 if ( is_array( $val ) ) {
109 $val = implode( '|', array_unique( $val ) );
110 }
111 }
112 $result = $this->doApiRequest( $req, $session, $appendModule, $user );
113 $this->assertResult( array( 'batchcomplete' => true, 'query' => $exp ), $result[0], $req );
114 }
115
116 protected function assertResult( $exp, $result, $message = '' ) {
117 try {
118 $exp = self::sanitizeResultArray( $exp );
119 $result = self::sanitizeResultArray( $result );
120 $this->assertEquals( $exp, $result );
121 } catch ( PHPUnit_Framework_ExpectationFailedException $e ) {
122 if ( is_array( $message ) ) {
123 $message = http_build_query( $message );
124 }
125
126 // FIXME: once we migrate to phpunit 4.1+, hardcode ComparisonFailure exception use
127 $compEx = 'SebastianBergmann\Comparator\ComparisonFailure';
128 if ( !class_exists( $compEx ) ) {
129 $compEx = 'PHPUnit_Framework_ComparisonFailure';
130 }
131
132 throw new PHPUnit_Framework_ExpectationFailedException(
133 $e->getMessage() . "\nRequest: $message",
134 new $compEx(
135 $exp,
136 $result,
137 print_r( $exp, true ),
138 print_r( $result, true ),
139 false,
140 $e->getComparisonFailure()->getMessage() . "\nRequest: $message"
141 )
142 );
143 }
144 }
145
146 /**
147 * Recursively ksorts a result array and removes any 'pageid' keys.
148 * @param array $result
149 * @return array
150 */
151 private static function sanitizeResultArray( $result ) {
152 unset( $result['pageid'] );
153 foreach ( $result as $key => $value ) {
154 if ( is_array( $value ) ) {
155 $result[$key] = self::sanitizeResultArray( $value );
156 }
157 }
158
159 // Sort the result by keys, then take advantage of how array_merge will
160 // renumber numeric keys while leaving others alone.
161 ksort( $result );
162 return array_merge( $result );
163 }
164 }