Merge "Set rup/roa-rup autonym to "armãneashti""
[lhc/web/wiklou.git] / includes / specials / SpecialJavaScriptTest.php
1 <?php
2 /**
3 * Implements Special:JavaScriptTest
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License along
16 * with this program; if not, write to the Free Software Foundation, Inc.,
17 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
18 * http://www.gnu.org/copyleft/gpl.html
19 *
20 * @file
21 * @ingroup SpecialPage
22 */
23
24 /**
25 * @ingroup SpecialPage
26 */
27 class SpecialJavaScriptTest extends SpecialPage {
28 /**
29 * @var array Mapping of framework ids and their initilizer methods
30 * in this class. If a framework is requested but not in this array,
31 * the 'unknownframework' error is served.
32 */
33 private static $frameworks = array(
34 'qunit' => 'initQUnitTesting',
35 );
36
37 public function __construct() {
38 parent::__construct( 'JavaScriptTest' );
39 }
40
41 public function execute( $par ) {
42 $out = $this->getOutput();
43
44 $this->setHeaders();
45 $out->disallowUserJs();
46
47 $out->addModules( 'mediawiki.special.javaScriptTest' );
48
49 // Determine framework
50 $pars = explode( '/', $par );
51 $framework = strtolower( $pars[0] );
52
53 // No framework specified
54 if ( $par == '' ) {
55 $out->setPageTitle( $this->msg( 'javascripttest' ) );
56 $summary = $this->wrapSummaryHtml(
57 $this->msg( 'javascripttest-pagetext-noframework' )->escaped() .
58 $this->getFrameworkListHtml(),
59 'noframework'
60 );
61 $out->addHtml( $summary );
62 } elseif ( isset( self::$frameworks[$framework] ) ) {
63 // Matched! Display proper title and initialize the framework
64 $out->setPageTitle( $this->msg(
65 'javascripttest-title',
66 // Messages: javascripttest-qunit-name
67 $this->msg( "javascripttest-$framework-name" )->plain()
68 ) );
69 $out->setSubtitle( $this->msg( 'javascripttest-backlink' )
70 ->rawParams( Linker::linkKnown( $this->getPageTitle() ) ) );
71 $this->{self::$frameworks[$framework]}();
72 } else {
73 // Framework not found, display error
74 $out->setPageTitle( $this->msg( 'javascripttest' ) );
75 $summary = $this->wrapSummaryHtml(
76 '<p class="error">' .
77 $this->msg( 'javascripttest-pagetext-unknownframework', $par )->escaped() .
78 '</p>' .
79 $this->getFrameworkListHtml(),
80 'unknownframework'
81 );
82 $out->addHtml( $summary );
83 }
84 }
85
86 /**
87 * Get a list of frameworks (including introduction paragraph and links
88 * to the framework run pages)
89 *
90 * @return string HTML
91 */
92 private function getFrameworkListHtml() {
93 $list = '<ul>';
94 foreach ( self::$frameworks as $framework => $initFn ) {
95 $list .= Html::rawElement(
96 'li',
97 array(),
98 Linker::link(
99 $this->getPageTitle( $framework ),
100 // Message: javascripttest-qunit-name
101 $this->msg( "javascripttest-$framework-name" )->escaped()
102 )
103 );
104 }
105 $list .= '</ul>';
106
107 return $this->msg( 'javascripttest-pagetext-frameworks' )->rawParams( $list )
108 ->parseAsBlock();
109 }
110
111 /**
112 * Function to wrap the summary.
113 * It must be given a valid state as a second parameter or an exception will
114 * be thrown.
115 * @param string $html The raw HTML.
116 * @param string $state State, one of 'noframework', 'unknownframework' or 'frameworkfound'
117 * @throws MWException
118 * @return string
119 */
120 private function wrapSummaryHtml( $html, $state ) {
121 $validStates = array( 'noframework', 'unknownframework', 'frameworkfound' );
122
123 if ( !in_array( $state, $validStates ) ) {
124 throw new MWException( __METHOD__
125 . ' given an invalid state. Must be one of "'
126 . join( '", "', $validStates ) . '".'
127 );
128 }
129
130 return "<div id=\"mw-javascripttest-summary\" class=\"mw-javascripttest-$state\">$html</div>";
131 }
132
133 /**
134 * Initialize the page for QUnit.
135 */
136 private function initQUnitTesting() {
137 $out = $this->getOutput();
138 $testConfig = $this->getConfig()->get( 'JavaScriptTestConfig' );
139
140 $out->addModules( 'test.mediawiki.qunit.testrunner' );
141 $qunitTestModules = $out->getResourceLoader()->getTestModuleNames( 'qunit' );
142 $out->addModules( $qunitTestModules );
143
144 $summary = $this->msg( 'javascripttest-qunit-intro' )
145 ->params( $testConfig['qunit']['documentation'] )
146 ->parseAsBlock();
147 $header = $this->msg( 'javascripttest-qunit-heading' )->escaped();
148 $userDir = $this->getLanguage()->getDir();
149
150 $baseHtml = <<<HTML
151 <div class="mw-content-ltr">
152 <div id="qunit-header"><span dir="$userDir">$header</span></div>
153 <div id="qunit-banner"></div>
154 <div id="qunit-testrunner-toolbar"></div>
155 <div id="qunit-userAgent"></div>
156 <ol id="qunit-tests"></ol>
157 <div id="qunit-fixture">test markup, will be hidden</div>
158 </div>
159 HTML;
160 $out->addHtml( $this->wrapSummaryHtml( $summary, 'frameworkfound' ) . $baseHtml );
161
162 // This special page is disabled by default ($wgEnableJavaScriptTest), and contains
163 // no sensitive data. In order to allow TestSwarm to embed it into a test client window,
164 // we need to allow iframing of this page.
165 $out->allowClickjacking();
166
167 // Used in ./tests/qunit/data/testrunner.js, see also documentation of
168 // $wgJavaScriptTestConfig in DefaultSettings.php
169 $out->addJsConfigVars(
170 'QUnitTestSwarmInjectJSPath',
171 $testConfig['qunit']['testswarm-injectjs']
172 );
173 }
174
175 /**
176 * Return an array of subpages beginning with $search that this special page will accept.
177 *
178 * @param string $search Prefix to search for
179 * @param int $limit Maximum number of results to return
180 * @return string[] Matching subpages
181 */
182 public function prefixSearchSubpages( $search, $limit = 10 ) {
183 return self::prefixSearchArray(
184 $search,
185 $limit,
186 array_keys( self::$frameworks )
187 );
188 }
189
190 protected function getGroupName() {
191 return 'other';
192 }
193 }