File: MessagesStructureTest.php

package info (click to toggle)
mediawiki 1%3A1.43.3%2Bdfsg-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 417,464 kB
  • sloc: php: 1,062,949; javascript: 664,290; sql: 9,714; python: 5,458; xml: 3,489; sh: 1,131; makefile: 64
file content (160 lines) | stat: -rw-r--r-- 4,689 bytes parent folder | download
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
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
<?php

use MediaWiki\Language\Language;

/**
 * Validate the Messages*.php files
 * @coversNothing -- no way to cover non-class files
 */
class MessagesStructureTest extends MediaWikiUnitTestCase {
	/** @var string */
	private $langCode;
	/** @var array */
	private static $enData;

	public static function provideMessagesFiles() {
		$n = 0;
		foreach ( glob( MW_INSTALL_PATH . '/languages/messages/Messages*.php' ) as $path ) {
			$fileName = basename( $path );
			yield [ $fileName ];
			$n++;
		}
		if ( $n === 0 ) {
			throw new \UnderflowException( 'Not enough files' );
		}
	}

	/**
	 * @dataProvider provideMessagesFiles
	 * @param string $fileName
	 */
	public function testMessageFile( $fileName ) {
		$this->langCode = Language::getCodeFromFileName( $fileName, 'Messages' );

		// Like isValidBuiltInCode()
		$this->assertMatchesRegularExpression( '/^[a-z0-9-]{2,}$/', $this->langCode );

		// Check for unrecognised variable names
		$path = MW_INSTALL_PATH . '/languages/messages/' . $fileName;
		$vars = $this->readFile( $path );
		$unknownVars = array_diff(
			array_keys( $vars ),
			LocalisationCache::ALL_KEYS
		);
		$this->assertSame( [], $unknownVars, 'unknown variables' );

		foreach ( $vars as $name => $value ) {
			$method = 'validate' . ucfirst( $name );
			if ( method_exists( $this, $method ) ) {
				$this->$method( $value );
			}
		}
	}

	private function readFile( $_path ) {
		require $_path;
		$vars = get_defined_vars();
		unset( $vars['_path'] );
		return $vars;
	}

	private function getEnData() {
		if ( self::$enData === null ) {
			self::$enData = $this->readFile( MW_INSTALL_PATH . '/languages/messages/MessagesEn.php' );
		}
		return self::$enData;
	}

	private function validateFallback( $value ) {
		if ( $this->langCode === 'en' ) {
			$this->assertFalse( $value, 'fallback for en must be false' );
			return;
		}
		$fallbacks = array_map( 'trim', explode( ',', $value ) );
		$this->assertLessThanOrEqual(
			MessageCache::MAX_REQUEST_LANGUAGES - 2,
			count( $fallbacks ),
			'fallback chain is too long (T310532)'
		);
		foreach ( $fallbacks as $code ) {
			// Like isValidBuiltInCode()
			$this->assertMatchesRegularExpression( '/^[a-z0-9-]{2,}$/', $code );
		}
	}

	private function validateNamespaceNames( $names ) {
		$enNames = $this->getEnData()['namespaceNames'];
		$this->assertSame(
			[],
			array_diff( array_keys( $names ), array_keys( $enNames ) ),
			'unrecognised namespace IDs'
		);
		foreach ( $names as $id => $name ) {
			$this->assertIsString( $name );
			if ( $id !== NS_MAIN ) {
				$this->assertNotSame( '', $name );
			}
			$this->assertStringNotContainsString( ' ', $name, 'Use underscores in namespace names' );
		}
	}

	private function validateNamespaceAliases( $aliases ) {
		foreach ( $aliases as $alias => $id ) {
			$this->assertIsString( $alias );
			$this->assertNotSame( '', $alias );
			$this->assertStringNotContainsString( ' ', $alias, 'Use underscores in namespace aliases' );
		}
	}

	private function validateMagicWords( $magicWords ) {
		$enWords = $this->getEnData()['magicWords'];
		$this->assertSame(
			[],
			array_diff( array_keys( $magicWords ), array_keys( $enWords ) ),
			'unrecognised magic word IDs'
		);
		foreach ( $magicWords as $id => $parts ) {
			// Ideally the case should be an integer, but some script writes it as a string
			$case = $parts[0];
			$this->assertThat(
				[ 0, 1, '0', '1' ],
				$this->containsIdentical( $case ),
				"$id case should be 0 or 1"
			);
			array_shift( $parts );
			foreach ( $parts as $i => $syn ) {
				$this->assertIsString( $syn, "$id syn $i should be string" );
				$this->assertNotSame( '', $syn, "$id syn $i should not be empty" );
			}
			$canonical = $enWords[$id][1];
			$this->assertContains( $canonical, $parts,
				"$id should contain English synonym $canonical" );
		}
	}

	private function validateSpecialPageAliases( $pages ) {
		$enPages = $this->getEnData()['specialPageAliases'];
		$this->assertSame(
			[],
			array_diff( array_keys( $pages ), array_keys( $enPages ) ),
			'unrecognised special page IDs'
		);
		foreach ( $pages as $pageName => $aliases ) {
			foreach ( $aliases as $i => $alias ) {
				$this->assertIsString( $alias, "$pageName alias $i should be string" );
				$this->assertNotSame( '', $alias,
					"$pageName alias $i should not be empty" );
				$this->assertStringNotContainsString( ' ', $alias, 'Use underscores in specialpage alias' );
			}
		}
	}

	private function validateLinkTrail( $linkTrail ) {
		$this->assertIsString( $linkTrail );
		$result = preg_match( $linkTrail, 'test' );
		if ( $result === false ) {
			$this->fail( "linkTrail regex match failed with code " . preg_last_error() );
		}
	}

}