Passed
Push — master ( 122983...91227d )
by William
02:34 queued 26s
created

LoaderTest   A

Complexity

Total Complexity 12

Size/Duplication

Total Lines 304
Duplicated Lines 0 %

Importance

Changes 2
Bugs 0 Features 0
Metric Value
eloc 157
c 2
b 0
f 0
dl 0
loc 304
rs 10
wmc 12

10 Methods

Rating   Name   Duplication   Size   Complexity  
A testInstance() 0 29 1
A testSetCacheFactory() 0 24 1
A testDetectEnv() 0 34 3
A getLoader() 0 8 1
A testGetTranslator() 0 7 1
A translatorData() 0 38 1
A testDetect() 0 9 1
A testLocaleChange() 0 11 1
A testListLocales() 0 5 1
A localeList() 0 97 1
1
<?php
2
3
declare(strict_types=1);
4
5
namespace PhpMyAdmin\MoTranslator\Tests;
6
7
use PhpMyAdmin\MoTranslator\Cache\CacheFactoryInterface;
8
use PhpMyAdmin\MoTranslator\Cache\CacheInterface;
9
use PhpMyAdmin\MoTranslator\Loader;
10
use PhpMyAdmin\MoTranslator\MoParser;
11
use PHPUnit\Framework\MockObject\MockObject;
12
use PHPUnit\Framework\TestCase;
13
14
use function getenv;
15
use function putenv;
16
17
/**
18
 * Test for mo loading.
19
 */
20
class LoaderTest extends TestCase
21
{
22
    /**
23
     * @param array[] $expected
24
     *
25
     * @dataProvider localeList
26
     */
27
    public function testListLocales(string $locale, array $expected): void
28
    {
29
        $this->assertEquals(
30
            $expected,
31
            Loader::listLocales($locale)
32
        );
33
    }
34
35
    /**
36
     * @return array[]
37
     */
38
    public function localeList(): array
39
    {
40
        return [
41
            [
42
                'cs_CZ',
43
                [
44
                    'cs_CZ',
45
                    'cs',
46
                ],
47
            ],
48
            [
49
                'sr_CS.UTF-8@latin',
50
                [
51
                    'sr_CS.UTF-8@latin',
52
                    'sr_CS@latin',
53
                    'sr@latin',
54
                    'sr_CS.UTF-8',
55
                    'sr_CS',
56
                    'sr',
57
                ],
58
            ],
59
            // For a locale containing country code, we prefer
60
            // full locale name, but if that's not found, fall back
61
            // to the language only locale name.
62
            [
63
                'sr_RS',
64
                [
65
                    'sr_RS',
66
                    'sr',
67
                ],
68
            ],
69
            // If language code is used, it's the only thing returned.
70
            [
71
                'sr',
72
                ['sr'],
73
            ],
74
            // There is support for language and charset only.
75
            [
76
                'sr.UTF-8',
77
                [
78
                    'sr.UTF-8',
79
                    'sr',
80
                ],
81
            ],
82
83
            // It can also split out character set from the full locale name.
84
            [
85
                'sr_RS.UTF-8',
86
                [
87
                    'sr_RS.UTF-8',
88
                    'sr_RS',
89
                    'sr',
90
                ],
91
            ],
92
93
            // There is support for @modifier in locale names as well.
94
            [
95
                'sr_RS.UTF-8@latin',
96
                [
97
                    'sr_RS.UTF-8@latin',
98
                    'sr_RS@latin',
99
                    'sr@latin',
100
                    'sr_RS.UTF-8',
101
                    'sr_RS',
102
                    'sr',
103
                ],
104
            ],
105
            [
106
                'sr.UTF-8@latin',
107
                [
108
                    'sr.UTF-8@latin',
109
                    'sr@latin',
110
                    'sr.UTF-8',
111
                    'sr',
112
                ],
113
            ],
114
115
            // We can pass in only language and modifier.
116
            [
117
                'sr@latin',
118
                [
119
                    'sr@latin',
120
                    'sr',
121
                ],
122
            ],
123
124
            // If locale name is not following the regular POSIX pattern,
125
            // it's used verbatim.
126
            [
127
                'something',
128
                ['something'],
129
            ],
130
131
            // Passing in an empty string returns an empty array.
132
            [
133
                '',
134
                [],
135
            ],
136
        ];
137
    }
138
139
    private function getLoader(string $domain, string $locale): Loader
140
    {
141
        $loader = new Loader();
142
        $loader->setlocale($locale);
143
        $loader->textdomain($domain);
144
        $loader->bindtextdomain($domain, __DIR__ . '/data/locale/');
145
146
        return $loader;
147
    }
148
149
    public function testLocaleChange(): void
150
    {
151
        $loader = new Loader();
152
        $loader->setlocale('cs');
153
        $loader->textdomain('phpmyadmin');
154
        $loader->bindtextdomain('phpmyadmin', __DIR__ . '/data/locale/');
155
        $translator = $loader->getTranslator('phpmyadmin');
156
        $this->assertEquals('Typ', $translator->gettext('Type'));
157
        $loader->setlocale('be_BY');
158
        $translator = $loader->getTranslator('phpmyadmin');
159
        $this->assertEquals('Тып', $translator->gettext('Type'));
160
    }
161
162
    /**
163
     * @dataProvider translatorData
164
     */
165
    public function testGetTranslator(string $domain, string $locale, string $otherdomain, string $expected): void
166
    {
167
        $loader = $this->getLoader($domain, $locale);
168
        $translator = $loader->getTranslator($otherdomain);
169
        $this->assertEquals(
170
            $expected,
171
            $translator->gettext('Type')
172
        );
173
    }
174
175
    /**
176
     * @return array[]
177
     */
178
    public function translatorData(): array
179
    {
180
        return [
181
            [
182
                'phpmyadmin',
183
                'cs',
184
                '',
185
                'Typ',
186
            ],
187
            [
188
                'phpmyadmin',
189
                'cs_CZ',
190
                '',
191
                'Typ',
192
            ],
193
            [
194
                'phpmyadmin',
195
                'be_BY',
196
                '',
197
                'Тып',
198
            ],
199
            [
200
                'phpmyadmin',
201
                'be@latin',
202
                '',
203
                'Typ',
204
            ],
205
            [
206
                'phpmyadmin',
207
                'cs',
208
                'other',
209
                'Type',
210
            ],
211
            [
212
                'other',
213
                'cs',
214
                'phpmyadmin',
215
                'Type',
216
            ],
217
        ];
218
    }
219
220
    public function testInstance(): void
221
    {
222
        $loader = Loader::getInstance();
223
        $loader->setlocale('cs');
224
        $loader->textdomain('phpmyadmin');
225
        $loader->bindtextdomain('phpmyadmin', __DIR__ . '/data/locale/');
226
227
        $translator = $loader->getTranslator();
228
        $this->assertEquals(
229
            'Typ',
230
            $translator->gettext('Type')
231
        );
232
233
        /* Ensure the object survives */
234
        $loader = Loader::getInstance();
235
        $translator = $loader->getTranslator();
236
        $this->assertEquals(
237
            'Typ',
238
            $translator->gettext('Type')
239
        );
240
241
        /* Ensure the object can support different locale files for the same domain */
242
        $loader = Loader::getInstance();
243
        $loader->setlocale('be_BY');
244
        $loader->bindtextdomain('phpmyadmin', __DIR__ . '/data/locale/');
245
        $translator = $loader->getTranslator();
246
        $this->assertEquals(
247
            'Тып',
248
            $translator->gettext('Type')
249
        );
250
    }
251
252
    public function testDetect(): void
253
    {
254
        $GLOBALS['lang'] = 'foo';
255
        $loader = Loader::getInstance();
256
        $this->assertEquals(
257
            'foo',
258
            $loader->detectlocale()
259
        );
260
        unset($GLOBALS['lang']);
261
    }
262
263
    public function testDetectEnv(): void
264
    {
265
        $loader = Loader::getInstance();
266
        foreach (['LC_MESSAGES', 'LC_ALL', 'LANG'] as $var) {
267
            putenv($var);
268
            if (getenv($var) === false) {
269
                continue;
270
            }
271
272
            $this->markTestSkipped('Unsetting environment does not work');
273
        }
274
275
        unset($GLOBALS['lang']);
276
        putenv('LC_ALL=baz');
277
        $this->assertEquals(
278
            'baz',
279
            $loader->detectlocale()
280
        );
281
        putenv('LC_ALL');
282
        putenv('LC_MESSAGES=bar');
283
        $this->assertEquals(
284
            'bar',
285
            $loader->detectlocale()
286
        );
287
        putenv('LC_MESSAGES');
288
        putenv('LANG=barr');
289
        $this->assertEquals(
290
            'barr',
291
            $loader->detectlocale()
292
        );
293
        putenv('LANG');
294
        $this->assertEquals(
295
            'en',
296
            $loader->detectlocale()
297
        );
298
    }
299
300
    public function testSetCacheFactory(): void
301
    {
302
        $expected = 'Foo';
303
        $locale = 'be_BY';
304
        $domain = 'apcu';
305
306
        $cache = $this->createMock(CacheInterface::class);
307
        $cache->method('get')
308
            ->willReturn($expected);
309
        /** @var CacheFactoryInterface&MockObject $factory */
310
        $factory = $this->createMock(CacheFactoryInterface::class);
311
        $factory->expects($this->once())
312
            ->method('getInstance')
313
            ->with($this->isInstanceOf(MoParser::class), $locale, $domain)
314
            ->willReturn($cache);
315
316
        Loader::setCacheFactory($factory);
317
        $loader = Loader::getInstance();
318
        $loader->setlocale($locale);
319
        $loader->bindtextdomain($domain, __DIR__ . '/data/locale/');
320
        $translator = $loader->getTranslator($domain);
321
322
        $actual = $translator->gettext('Type');
323
        $this->assertEquals($expected, $actual);
324
    }
325
}
326