Merge "Type hint against LinkTarget in WatchedItemStore"
[lhc/web/wiklou.git] / tests / phpunit / ResourceLoaderTestCase.php
1 <?php
2
3 use MediaWiki\MediaWikiServices;
4 use Psr\Log\LoggerInterface;
5
6 abstract class ResourceLoaderTestCase extends MediaWikiTestCase {
7 // Version hash for a blank file module.
8 // Result of ResourceLoader::makeHash(), ResourceLoaderTestModule
9 // and ResourceLoaderFileModule::getDefinitionSummary().
10 const BLANK_VERSION = '09p30q0';
11
12 /**
13 * @param array|string $options Language code or options array
14 * - string 'lang' Language code
15 * - string 'dir' Language direction (ltr or rtl)
16 * - string 'modules' Pipe-separated list of module names
17 * - string|null 'only' "scripts" (unwrapped script), "styles" (stylesheet), or null
18 * (mw.loader.implement).
19 * @param ResourceLoader|null $rl
20 * @return ResourceLoaderContext
21 */
22 protected function getResourceLoaderContext( $options = [], ResourceLoader $rl = null ) {
23 if ( is_string( $options ) ) {
24 // Back-compat for extension tests
25 $options = [ 'lang' => $options ];
26 }
27 $options += [
28 'debug' => 'true',
29 'lang' => 'en',
30 'dir' => 'ltr',
31 'skin' => 'fallback',
32 'modules' => 'startup',
33 'only' => 'scripts',
34 'safemode' => null,
35 ];
36 $resourceLoader = $rl ?: new ResourceLoader( MediaWikiServices::getInstance()->getMainConfig() );
37 $request = new FauxRequest( [
38 'debug' => $options['debug'],
39 'lang' => $options['lang'],
40 'modules' => $options['modules'],
41 'only' => $options['only'],
42 'safemode' => $options['safemode'],
43 'skin' => $options['skin'],
44 'target' => 'phpunit',
45 ] );
46 $ctx = $this->getMockBuilder( ResourceLoaderContext::class )
47 ->setConstructorArgs( [ $resourceLoader, $request ] )
48 ->setMethods( [ 'getDirection' ] )
49 ->getMock();
50 $ctx->method( 'getDirection' )->willReturn( $options['dir'] );
51 return $ctx;
52 }
53
54 public static function getSettings() {
55 return [
56 // For ResourceLoader::inDebugMode since it doesn't have context
57 'ResourceLoaderDebug' => true,
58
59 // For ResourceLoaderStartUpModule and ResourceLoader::__construct()
60 'ScriptPath' => '/w',
61 'Script' => '/w/index.php',
62 'LoadScript' => '/w/load.php',
63
64 // For ResourceLoader::register() - TODO: Inject somehow T32956
65 'ResourceModuleSkinStyles' => [],
66
67 // For ResourceLoader::respond() - TODO: Inject somehow T32956
68 'UseFileCache' => false,
69 ];
70 }
71
72 public static function getMinimalConfig() {
73 return new HashConfig( self::getSettings() );
74 }
75
76 protected function setUp() {
77 parent::setUp();
78
79 ResourceLoader::clearCache();
80
81 $globals = [];
82 foreach ( self::getSettings() as $key => $value ) {
83 $globals['wg' . $key] = $value;
84 }
85 $this->setMwGlobals( $globals );
86 }
87 }
88
89 /* Stubs */
90
91 class ResourceLoaderTestModule extends ResourceLoaderModule {
92 protected $messages = [];
93 protected $dependencies = [];
94 protected $group = null;
95 protected $source = 'local';
96 protected $script = '';
97 protected $styles = '';
98 protected $skipFunction = null;
99 protected $isRaw = false;
100 protected $isKnownEmpty = false;
101 protected $type = ResourceLoaderModule::LOAD_GENERAL;
102 protected $targets = [ 'phpunit' ];
103 protected $shouldEmbed = null;
104 protected $mayValidateScript = false;
105
106 public function __construct( $options = [] ) {
107 foreach ( $options as $key => $value ) {
108 $this->$key = $value;
109 }
110 }
111
112 public function getScript( ResourceLoaderContext $context ) {
113 if ( $this->mayValidateScript ) {
114 // This enables the validation check that replaces invalid
115 // scripts with a warning message.
116 // Based on $wgResourceLoaderValidateJS
117 return $this->validateScriptFile( 'input', $this->script );
118 } else {
119 return $this->script;
120 }
121 }
122
123 public function getStyles( ResourceLoaderContext $context ) {
124 return [ '' => $this->styles ];
125 }
126
127 public function getMessages() {
128 return $this->messages;
129 }
130
131 public function getDependencies( ResourceLoaderContext $context = null ) {
132 return $this->dependencies;
133 }
134
135 public function getGroup() {
136 return $this->group;
137 }
138
139 public function getSource() {
140 return $this->source;
141 }
142
143 public function getType() {
144 return $this->type;
145 }
146
147 public function getSkipFunction() {
148 return $this->skipFunction;
149 }
150
151 public function isRaw() {
152 return $this->isRaw;
153 }
154
155 public function isKnownEmpty( ResourceLoaderContext $context ) {
156 return $this->isKnownEmpty;
157 }
158
159 public function shouldEmbedModule( ResourceLoaderContext $context ) {
160 return $this->shouldEmbed ?? parent::shouldEmbedModule( $context );
161 }
162
163 public function enableModuleContentVersion() {
164 return true;
165 }
166 }
167
168 /**
169 * A more constrained and testable variant of ResourceLoaderFileModule.
170 *
171 * - Implements getLessVars() support.
172 * - Disables database persistance of discovered file dependencies.
173 */
174 class ResourceLoaderFileTestModule extends ResourceLoaderFileModule {
175 protected $lessVars = [];
176
177 public function __construct( $options = [] ) {
178 if ( isset( $options['lessVars'] ) ) {
179 $this->lessVars = $options['lessVars'];
180 unset( $options['lessVars'] );
181 }
182
183 parent::__construct( $options );
184 }
185
186 public function getLessVars( ResourceLoaderContext $context ) {
187 return $this->lessVars;
188 }
189
190 /** @return array */
191 protected function getFileDependencies( ResourceLoaderContext $context ) {
192 // No-op
193 return [];
194 }
195
196 protected function saveFileDependencies( ResourceLoaderContext $context, $refs ) {
197 // No-op
198 }
199 }
200
201 class ResourceLoaderFileModuleTestingSubclass extends ResourceLoaderFileModule {
202 }
203
204 class EmptyResourceLoader extends ResourceLoader {
205 public function __construct( Config $config = null, LoggerInterface $logger = null ) {
206 parent::__construct( $config ?: ResourceLoaderTestCase::getMinimalConfig(), $logger );
207 }
208
209 public function getErrors() {
210 return $this->errors;
211 }
212 }