summaryrefslogtreecommitdiff
path: root/includes/specials/SpecialJavaScriptTest.php
blob: d7e1655f4de5d557ae572d0d25e6653de5fb99b0 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
<?php

class SpecialJavaScriptTest extends SpecialPage {

	/**
	 * @var $frameworks Array: Mapping of framework ids and their initilizer methods
	 * in this class. If a framework is requested but not in this array,
	 * the 'unknownframework' error is served.
	 */
	static $frameworks = array(
		'qunit' => 'initQUnitTesting',
	);

	public function __construct() {
		parent::__construct( 'JavaScriptTest' );
	}

	public function execute( $par ) {
		global $wgEnableJavaScriptTest;

		$out = $this->getOutput();

		$this->setHeaders();
		$out->disallowUserJs();

		// Abort early if we're disabled
		if ( $wgEnableJavaScriptTest !== true ) {
			$out->addWikiMsg( 'javascripttest-disabled' );
			return;
		}

		$out->addModules( 'mediawiki.special.javaScriptTest' );

		// Determine framework
		$pars = explode( '/', $par );
		$framework = strtolower( $pars[0] );

		// No framework specified
		if ( $par == '' ) {
			$out->setPagetitle( wfMsgHtml( 'javascripttest' ) );
			$summary = $this->wrapSummaryHtml(
				wfMsgHtml( 'javascripttest-pagetext-noframework' ) . $this->getFrameworkListHtml(),
				'noframework'
			);
			$out->addHtml( $summary );

		// Matched! Display proper title and initialize the framework
		} elseif ( isset( self::$frameworks[$framework] ) ) {
			$out->setPagetitle( wfMsgHtml( 'javascripttest-title', wfMsgHtml( "javascripttest-$framework-name" ) ) );
			$out->setSubtitle(
				wfMessage( 'javascripttest-backlink' )->rawParams( Linker::linkKnown( $this->getTitle() ) )->escaped()
			);
			$this->{self::$frameworks[$framework]}();

		// Framework not found, display error
		} else {
			$out->setPagetitle( wfMsgHtml( 'javascripttest' ) );
			$summary = $this->wrapSummaryHtml( '<p class="error">'
				. wfMsgHtml( 'javascripttest-pagetext-unknownframework', $par )
				. '</p>'
				. $this->getFrameworkListHtml(),
				'unknownframework'
			);
			$out->addHtml( $summary );
		}
	}

	/**
	 * Get a list of frameworks (including introduction paragraph and links to the framework run pages)
	 * @return String: HTML
	 */
	private function getFrameworkListHtml() {
		$list = '<ul>';
		foreach( self::$frameworks as $framework => $initFn ) {
			$list .= Html::rawElement(
				'li',
				array(),
				Linker::link( $this->getTitle( $framework ), wfMsgHtml( "javascripttest-$framework-name" ) )
			);
		}
		$list .= '</ul>';
		$msg = wfMessage( 'javascripttest-pagetext-frameworks' )->rawParams( $list )->parseAsBlock();

		return $msg;
	}

	/**
	 * Function to wrap the summary.
	 * It must be given a valid state as a second parameter or an exception will
	 * be thrown.
	 * @param $html String: The raw HTML.
	 * @param $state String: State, one of 'noframework', 'unknownframework' or 'frameworkfound'
	 */
	private function wrapSummaryHtml( $html, $state ) {
		$validStates = array( 'noframework', 'unknownframework', 'frameworkfound' );
		if( !in_array( $state, $validStates ) ) {
			throw new MWException( __METHOD__
				. ' given an invalid state. Must be one of "'
				. join( '", "', $validStates) . '".'
			);
		}
		return "<div id=\"mw-javascripttest-summary\" class=\"mw-javascripttest-$state\">$html</div>";
	}

	/**
	 * Initialize the page for QUnit.
	 */
	private function initQUnitTesting() {
		global $wgJavaScriptTestConfig, $wgLang;

		$out = $this->getOutput();

		$out->addModules( 'mediawiki.tests.qunit.testrunner' );
		$qunitTestModules = $out->getResourceLoader()->getTestModuleNames( 'qunit' );
		$out->addModules( $qunitTestModules );

		$summary = wfMessage( 'javascripttest-qunit-intro' )
			->params( $wgJavaScriptTestConfig['qunit']['documentation'] )
			->parseAsBlock();
		$header = wfMessage( 'javascripttest-qunit-heading' )->escaped();
		$userDir = $wgLang->getDir();

		$baseHtml = <<<HTML
<div class="mw-content-ltr">
<div id="qunit-header"><span dir="$userDir">$header</span></div>
<div id="qunit-banner"></div>
<div id="qunit-testrunner-toolbar"></div>
<div id="qunit-userAgent"></div>
<ol id="qunit-tests"></ol>
<div id="qunit-fixture">test markup, will be hidden</div>
</div>
HTML;
		$out->addHtml( $this->wrapSummaryHtml( $summary, 'frameworkfound' ) . $baseHtml );

	}

	public function isListed(){
		global $wgEnableJavaScriptTest;
		return $wgEnableJavaScriptTest === true;
	}

}