Vous êtes connecté en tant que anonymous Se Deconnecter
Browse code

Application modulaire fonctionnelle !

Emmanuel ROY authored on 12/08/2019 15:10:25
Showing 1 changed files
1 1
deleted file mode 100644
... ...
@@ -1,318 +0,0 @@
1
-<?php
2
-
3
-/*
4
- * This file is part of the Symfony package.
5
- *
6
- * (c) Fabien Potencier <fabien@symfony.com>
7
- *
8
- * For the full copyright and license information, please view the LICENSE
9
- * file that was distributed with this source code.
10
- */
11
-
12
-namespace Symfony\Component\Translation\Tests;
13
-
14
-use PHPUnit\Framework\TestCase;
15
-use Symfony\Component\Config\Resource\SelfCheckingResourceInterface;
16
-use Symfony\Component\Translation\Loader\ArrayLoader;
17
-use Symfony\Component\Translation\Loader\LoaderInterface;
18
-use Symfony\Component\Translation\MessageCatalogue;
19
-use Symfony\Component\Translation\Translator;
20
-
21
-class TranslatorCacheTest extends TestCase
22
-{
23
-    protected $tmpDir;
24
-
25
-    protected function setUp()
26
-    {
27
-        $this->tmpDir = sys_get_temp_dir().'/sf_translation';
28
-        $this->deleteTmpDir();
29
-    }
30
-
31
-    protected function tearDown()
32
-    {
33
-        $this->deleteTmpDir();
34
-    }
35
-
36
-    protected function deleteTmpDir()
37
-    {
38
-        if (!file_exists($dir = $this->tmpDir)) {
39
-            return;
40
-        }
41
-
42
-        $iterator = new \RecursiveIteratorIterator(new \RecursiveDirectoryIterator($this->tmpDir), \RecursiveIteratorIterator::CHILD_FIRST);
43
-        foreach ($iterator as $path) {
44
-            if (preg_match('#[/\\\\]\.\.?$#', $path->__toString())) {
45
-                continue;
46
-            }
47
-            if ($path->isDir()) {
48
-                rmdir($path->__toString());
49
-            } else {
50
-                unlink($path->__toString());
51
-            }
52
-        }
53
-        rmdir($this->tmpDir);
54
-    }
55
-
56
-    /**
57
-     * @dataProvider runForDebugAndProduction
58
-     */
59
-    public function testThatACacheIsUsed($debug)
60
-    {
61
-        $locale = 'any_locale';
62
-        $format = 'some_format';
63
-        $msgid = 'test';
64
-
65
-        // Prime the cache
66
-        $translator = new Translator($locale, null, $this->tmpDir, $debug);
67
-        $translator->addLoader($format, new ArrayLoader());
68
-        $translator->addResource($format, [$msgid => 'OK'], $locale);
69
-        $translator->addResource($format, [$msgid.'+intl' => 'OK'], $locale, 'messages+intl-icu');
70
-        $translator->trans($msgid);
71
-        $translator->trans($msgid.'+intl', [], 'messages+intl-icu');
72
-
73
-        // Try again and see we get a valid result whilst no loader can be used
74
-        $translator = new Translator($locale, null, $this->tmpDir, $debug);
75
-        $translator->addLoader($format, $this->createFailingLoader());
76
-        $translator->addResource($format, [$msgid => 'OK'], $locale);
77
-        $translator->addResource($format, [$msgid.'+intl' => 'OK'], $locale, 'messages+intl-icu');
78
-        $this->assertEquals('OK', $translator->trans($msgid), '-> caching does not work in '.($debug ? 'debug' : 'production'));
79
-        $this->assertEquals('OK', $translator->trans($msgid.'+intl', [], 'messages+intl-icu'));
80
-    }
81
-
82
-    public function testCatalogueIsReloadedWhenResourcesAreNoLongerFresh()
83
-    {
84
-        /*
85
-         * The testThatACacheIsUsed() test showed that we don't need the loader as long as the cache
86
-         * is fresh.
87
-         *
88
-         * Now we add a Resource that is never fresh and make sure that the
89
-         * cache is discarded (the loader is called twice).
90
-         *
91
-         * We need to run this for debug=true only because in production the cache
92
-         * will never be revalidated.
93
-         */
94
-
95
-        $locale = 'any_locale';
96
-        $format = 'some_format';
97
-        $msgid = 'test';
98
-
99
-        $catalogue = new MessageCatalogue($locale, []);
100
-        $catalogue->addResource(new StaleResource()); // better use a helper class than a mock, because it gets serialized in the cache and re-loaded
101
-
102
-        /** @var LoaderInterface|\PHPUnit_Framework_MockObject_MockObject $loader */
103
-        $loader = $this->getMockBuilder('Symfony\Component\Translation\Loader\LoaderInterface')->getMock();
104
-        $loader
105
-            ->expects($this->exactly(2))
106
-            ->method('load')
107
-            ->willReturn($catalogue)
108
-        ;
109
-
110
-        // 1st pass
111
-        $translator = new Translator($locale, null, $this->tmpDir, true);
112
-        $translator->addLoader($format, $loader);
113
-        $translator->addResource($format, null, $locale);
114
-        $translator->trans($msgid);
115
-
116
-        // 2nd pass
117
-        $translator = new Translator($locale, null, $this->tmpDir, true);
118
-        $translator->addLoader($format, $loader);
119
-        $translator->addResource($format, null, $locale);
120
-        $translator->trans($msgid);
121
-    }
122
-
123
-    /**
124
-     * @dataProvider runForDebugAndProduction
125
-     */
126
-    public function testDifferentTranslatorsForSameLocaleDoNotOverwriteEachOthersCache($debug)
127
-    {
128
-        /*
129
-         * Similar to the previous test. After we used the second translator, make
130
-         * sure there's still a usable cache for the first one.
131
-         */
132
-
133
-        $locale = 'any_locale';
134
-        $format = 'some_format';
135
-        $msgid = 'test';
136
-
137
-        // Create a Translator and prime its cache
138
-        $translator = new Translator($locale, null, $this->tmpDir, $debug);
139
-        $translator->addLoader($format, new ArrayLoader());
140
-        $translator->addResource($format, [$msgid => 'OK'], $locale);
141
-        $translator->trans($msgid);
142
-
143
-        // Create another Translator with a different catalogue for the same locale
144
-        $translator = new Translator($locale, null, $this->tmpDir, $debug);
145
-        $translator->addLoader($format, new ArrayLoader());
146
-        $translator->addResource($format, [$msgid => 'FAIL'], $locale);
147
-        $translator->trans($msgid);
148
-
149
-        // Now the first translator must still have a usable cache.
150
-        $translator = new Translator($locale, null, $this->tmpDir, $debug);
151
-        $translator->addLoader($format, $this->createFailingLoader());
152
-        $translator->addResource($format, [$msgid => 'OK'], $locale);
153
-        $this->assertEquals('OK', $translator->trans($msgid), '-> the cache was overwritten by another translator instance in '.($debug ? 'debug' : 'production'));
154
-    }
155
-
156
-    public function testGeneratedCacheFilesAreOnlyBelongRequestedLocales()
157
-    {
158
-        $translator = new Translator('a', null, $this->tmpDir);
159
-        $translator->setFallbackLocales(['b']);
160
-        $translator->trans('bar');
161
-
162
-        $cachedFiles = glob($this->tmpDir.'/*.php');
163
-
164
-        $this->assertCount(1, $cachedFiles);
165
-    }
166
-
167
-    public function testDifferentCacheFilesAreUsedForDifferentSetsOfFallbackLocales()
168
-    {
169
-        /*
170
-         * Because the cache file contains a catalogue including all of its fallback
171
-         * catalogues, we must take the set of fallback locales into consideration when
172
-         * loading a catalogue from the cache.
173
-         */
174
-        $translator = new Translator('a', null, $this->tmpDir);
175
-        $translator->setFallbackLocales(['b']);
176
-
177
-        $translator->addLoader('array', new ArrayLoader());
178
-        $translator->addResource('array', ['foo' => 'foo (a)'], 'a');
179
-        $translator->addResource('array', ['bar' => 'bar (b)'], 'b');
180
-
181
-        $this->assertEquals('bar (b)', $translator->trans('bar'));
182
-
183
-        // Remove fallback locale
184
-        $translator->setFallbackLocales([]);
185
-        $this->assertEquals('bar', $translator->trans('bar'));
186
-
187
-        // Use a fresh translator with no fallback locales, result should be the same
188
-        $translator = new Translator('a', null, $this->tmpDir);
189
-
190
-        $translator->addLoader('array', new ArrayLoader());
191
-        $translator->addResource('array', ['foo' => 'foo (a)'], 'a');
192
-        $translator->addResource('array', ['bar' => 'bar (b)'], 'b');
193
-
194
-        $this->assertEquals('bar', $translator->trans('bar'));
195
-    }
196
-
197
-    public function testPrimaryAndFallbackCataloguesContainTheSameMessagesRegardlessOfCaching()
198
-    {
199
-        /*
200
-         * As a safeguard against potential BC breaks, make sure that primary and fallback
201
-         * catalogues (reachable via getFallbackCatalogue()) always contain the full set of
202
-         * messages provided by the loader. This must also be the case when these catalogues
203
-         * are (internally) read from a cache.
204
-         *
205
-         * Optimizations inside the translator must not change this behavior.
206
-         */
207
-
208
-        /*
209
-         * Create a translator that loads two catalogues for two different locales.
210
-         * The catalogues contain distinct sets of messages.
211
-         */
212
-        $translator = new Translator('a', null, $this->tmpDir);
213
-        $translator->setFallbackLocales(['b']);
214
-
215
-        $translator->addLoader('array', new ArrayLoader());
216
-        $translator->addResource('array', ['foo' => 'foo (a)'], 'a');
217
-        $translator->addResource('array', ['foo' => 'foo (b)'], 'b');
218
-        $translator->addResource('array', ['bar' => 'bar (b)'], 'b');
219
-        $translator->addResource('array', ['baz' => 'baz (b)'], 'b', 'messages+intl-icu');
220
-
221
-        $catalogue = $translator->getCatalogue('a');
222
-        $this->assertFalse($catalogue->defines('bar')); // Sure, the "a" catalogue does not contain that message.
223
-
224
-        $fallback = $catalogue->getFallbackCatalogue();
225
-        $this->assertTrue($fallback->defines('foo')); // "foo" is present in "a" and "b"
226
-
227
-        /*
228
-         * Now, repeat the same test.
229
-         * Behind the scenes, the cache is used. But that should not matter, right?
230
-         */
231
-        $translator = new Translator('a', null, $this->tmpDir);
232
-        $translator->setFallbackLocales(['b']);
233
-
234
-        $translator->addLoader('array', new ArrayLoader());
235
-        $translator->addResource('array', ['foo' => 'foo (a)'], 'a');
236
-        $translator->addResource('array', ['foo' => 'foo (b)'], 'b');
237
-        $translator->addResource('array', ['bar' => 'bar (b)'], 'b');
238
-        $translator->addResource('array', ['baz' => 'baz (b)'], 'b', 'messages+intl-icu');
239
-
240
-        $catalogue = $translator->getCatalogue('a');
241
-        $this->assertFalse($catalogue->defines('bar'));
242
-
243
-        $fallback = $catalogue->getFallbackCatalogue();
244
-        $this->assertTrue($fallback->defines('foo'));
245
-        $this->assertTrue($fallback->defines('baz', 'messages+intl-icu'));
246
-    }
247
-
248
-    public function testRefreshCacheWhenResourcesAreNoLongerFresh()
249
-    {
250
-        $resource = $this->getMockBuilder('Symfony\Component\Config\Resource\SelfCheckingResourceInterface')->getMock();
251
-        $loader = $this->getMockBuilder('Symfony\Component\Translation\Loader\LoaderInterface')->getMock();
252
-        $resource->method('isFresh')->willReturn(false);
253
-        $loader
254
-            ->expects($this->exactly(2))
255
-            ->method('load')
256
-            ->willReturn($this->getCatalogue('fr', [], [$resource]));
257
-
258
-        // prime the cache
259
-        $translator = new Translator('fr', null, $this->tmpDir, true);
260
-        $translator->addLoader('loader', $loader);
261
-        $translator->addResource('loader', 'foo', 'fr');
262
-        $translator->trans('foo');
263
-
264
-        // prime the cache second time
265
-        $translator = new Translator('fr', null, $this->tmpDir, true);
266
-        $translator->addLoader('loader', $loader);
267
-        $translator->addResource('loader', 'foo', 'fr');
268
-        $translator->trans('foo');
269
-    }
270
-
271
-    protected function getCatalogue($locale, $messages, $resources = [])
272
-    {
273
-        $catalogue = new MessageCatalogue($locale);
274
-        foreach ($messages as $key => $translation) {
275
-            $catalogue->set($key, $translation);
276
-        }
277
-        foreach ($resources as $resource) {
278
-            $catalogue->addResource($resource);
279
-        }
280
-
281
-        return $catalogue;
282
-    }
283
-
284
-    public function runForDebugAndProduction()
285
-    {
286
-        return [[true], [false]];
287
-    }
288
-
289
-    /**
290
-     * @return LoaderInterface
291
-     */
292
-    private function createFailingLoader()
293
-    {
294
-        $loader = $this->getMockBuilder('Symfony\Component\Translation\Loader\LoaderInterface')->getMock();
295
-        $loader
296
-            ->expects($this->never())
297
-            ->method('load');
298
-
299
-        return $loader;
300
-    }
301
-}
302
-
303
-class StaleResource implements SelfCheckingResourceInterface
304
-{
305
-    public function isFresh($timestamp)
306
-    {
307
-        return false;
308
-    }
309
-
310
-    public function getResource()
311
-    {
312
-    }
313
-
314
-    public function __toString()
315
-    {
316
-        return '';
317
-    }
318
-}
Browse code

initial commit

Emmanuel ROY authored on 09/08/2019 08:39:02
Showing 1 changed files
1 1
new file mode 100644
... ...
@@ -0,0 +1,318 @@
1
+<?php
2
+
3
+/*
4
+ * This file is part of the Symfony package.
5
+ *
6
+ * (c) Fabien Potencier <fabien@symfony.com>
7
+ *
8
+ * For the full copyright and license information, please view the LICENSE
9
+ * file that was distributed with this source code.
10
+ */
11
+
12
+namespace Symfony\Component\Translation\Tests;
13
+
14
+use PHPUnit\Framework\TestCase;
15
+use Symfony\Component\Config\Resource\SelfCheckingResourceInterface;
16
+use Symfony\Component\Translation\Loader\ArrayLoader;
17
+use Symfony\Component\Translation\Loader\LoaderInterface;
18
+use Symfony\Component\Translation\MessageCatalogue;
19
+use Symfony\Component\Translation\Translator;
20
+
21
+class TranslatorCacheTest extends TestCase
22
+{
23
+    protected $tmpDir;
24
+
25
+    protected function setUp()
26
+    {
27
+        $this->tmpDir = sys_get_temp_dir().'/sf_translation';
28
+        $this->deleteTmpDir();
29
+    }
30
+
31
+    protected function tearDown()
32
+    {
33
+        $this->deleteTmpDir();
34
+    }
35
+
36
+    protected function deleteTmpDir()
37
+    {
38
+        if (!file_exists($dir = $this->tmpDir)) {
39
+            return;
40
+        }
41
+
42
+        $iterator = new \RecursiveIteratorIterator(new \RecursiveDirectoryIterator($this->tmpDir), \RecursiveIteratorIterator::CHILD_FIRST);
43
+        foreach ($iterator as $path) {
44
+            if (preg_match('#[/\\\\]\.\.?$#', $path->__toString())) {
45
+                continue;
46
+            }
47
+            if ($path->isDir()) {
48
+                rmdir($path->__toString());
49
+            } else {
50
+                unlink($path->__toString());
51
+            }
52
+        }
53
+        rmdir($this->tmpDir);
54
+    }
55
+
56
+    /**
57
+     * @dataProvider runForDebugAndProduction
58
+     */
59
+    public function testThatACacheIsUsed($debug)
60
+    {
61
+        $locale = 'any_locale';
62
+        $format = 'some_format';
63
+        $msgid = 'test';
64
+
65
+        // Prime the cache
66
+        $translator = new Translator($locale, null, $this->tmpDir, $debug);
67
+        $translator->addLoader($format, new ArrayLoader());
68
+        $translator->addResource($format, [$msgid => 'OK'], $locale);
69
+        $translator->addResource($format, [$msgid.'+intl' => 'OK'], $locale, 'messages+intl-icu');
70
+        $translator->trans($msgid);
71
+        $translator->trans($msgid.'+intl', [], 'messages+intl-icu');
72
+
73
+        // Try again and see we get a valid result whilst no loader can be used
74
+        $translator = new Translator($locale, null, $this->tmpDir, $debug);
75
+        $translator->addLoader($format, $this->createFailingLoader());
76
+        $translator->addResource($format, [$msgid => 'OK'], $locale);
77
+        $translator->addResource($format, [$msgid.'+intl' => 'OK'], $locale, 'messages+intl-icu');
78
+        $this->assertEquals('OK', $translator->trans($msgid), '-> caching does not work in '.($debug ? 'debug' : 'production'));
79
+        $this->assertEquals('OK', $translator->trans($msgid.'+intl', [], 'messages+intl-icu'));
80
+    }
81
+
82
+    public function testCatalogueIsReloadedWhenResourcesAreNoLongerFresh()
83
+    {
84
+        /*
85
+         * The testThatACacheIsUsed() test showed that we don't need the loader as long as the cache
86
+         * is fresh.
87
+         *
88
+         * Now we add a Resource that is never fresh and make sure that the
89
+         * cache is discarded (the loader is called twice).
90
+         *
91
+         * We need to run this for debug=true only because in production the cache
92
+         * will never be revalidated.
93
+         */
94
+
95
+        $locale = 'any_locale';
96
+        $format = 'some_format';
97
+        $msgid = 'test';
98
+
99
+        $catalogue = new MessageCatalogue($locale, []);
100
+        $catalogue->addResource(new StaleResource()); // better use a helper class than a mock, because it gets serialized in the cache and re-loaded
101
+
102
+        /** @var LoaderInterface|\PHPUnit_Framework_MockObject_MockObject $loader */
103
+        $loader = $this->getMockBuilder('Symfony\Component\Translation\Loader\LoaderInterface')->getMock();
104
+        $loader
105
+            ->expects($this->exactly(2))
106
+            ->method('load')
107
+            ->willReturn($catalogue)
108
+        ;
109
+
110
+        // 1st pass
111
+        $translator = new Translator($locale, null, $this->tmpDir, true);
112
+        $translator->addLoader($format, $loader);
113
+        $translator->addResource($format, null, $locale);
114
+        $translator->trans($msgid);
115
+
116
+        // 2nd pass
117
+        $translator = new Translator($locale, null, $this->tmpDir, true);
118
+        $translator->addLoader($format, $loader);
119
+        $translator->addResource($format, null, $locale);
120
+        $translator->trans($msgid);
121
+    }
122
+
123
+    /**
124
+     * @dataProvider runForDebugAndProduction
125
+     */
126
+    public function testDifferentTranslatorsForSameLocaleDoNotOverwriteEachOthersCache($debug)
127
+    {
128
+        /*
129
+         * Similar to the previous test. After we used the second translator, make
130
+         * sure there's still a usable cache for the first one.
131
+         */
132
+
133
+        $locale = 'any_locale';
134
+        $format = 'some_format';
135
+        $msgid = 'test';
136
+
137
+        // Create a Translator and prime its cache
138
+        $translator = new Translator($locale, null, $this->tmpDir, $debug);
139
+        $translator->addLoader($format, new ArrayLoader());
140
+        $translator->addResource($format, [$msgid => 'OK'], $locale);
141
+        $translator->trans($msgid);
142
+
143
+        // Create another Translator with a different catalogue for the same locale
144
+        $translator = new Translator($locale, null, $this->tmpDir, $debug);
145
+        $translator->addLoader($format, new ArrayLoader());
146
+        $translator->addResource($format, [$msgid => 'FAIL'], $locale);
147
+        $translator->trans($msgid);
148
+
149
+        // Now the first translator must still have a usable cache.
150
+        $translator = new Translator($locale, null, $this->tmpDir, $debug);
151
+        $translator->addLoader($format, $this->createFailingLoader());
152
+        $translator->addResource($format, [$msgid => 'OK'], $locale);
153
+        $this->assertEquals('OK', $translator->trans($msgid), '-> the cache was overwritten by another translator instance in '.($debug ? 'debug' : 'production'));
154
+    }
155
+
156
+    public function testGeneratedCacheFilesAreOnlyBelongRequestedLocales()
157
+    {
158
+        $translator = new Translator('a', null, $this->tmpDir);
159
+        $translator->setFallbackLocales(['b']);
160
+        $translator->trans('bar');
161
+
162
+        $cachedFiles = glob($this->tmpDir.'/*.php');
163
+
164
+        $this->assertCount(1, $cachedFiles);
165
+    }
166
+
167
+    public function testDifferentCacheFilesAreUsedForDifferentSetsOfFallbackLocales()
168
+    {
169
+        /*
170
+         * Because the cache file contains a catalogue including all of its fallback
171
+         * catalogues, we must take the set of fallback locales into consideration when
172
+         * loading a catalogue from the cache.
173
+         */
174
+        $translator = new Translator('a', null, $this->tmpDir);
175
+        $translator->setFallbackLocales(['b']);
176
+
177
+        $translator->addLoader('array', new ArrayLoader());
178
+        $translator->addResource('array', ['foo' => 'foo (a)'], 'a');
179
+        $translator->addResource('array', ['bar' => 'bar (b)'], 'b');
180
+
181
+        $this->assertEquals('bar (b)', $translator->trans('bar'));
182
+
183
+        // Remove fallback locale
184
+        $translator->setFallbackLocales([]);
185
+        $this->assertEquals('bar', $translator->trans('bar'));
186
+
187
+        // Use a fresh translator with no fallback locales, result should be the same
188
+        $translator = new Translator('a', null, $this->tmpDir);
189
+
190
+        $translator->addLoader('array', new ArrayLoader());
191
+        $translator->addResource('array', ['foo' => 'foo (a)'], 'a');
192
+        $translator->addResource('array', ['bar' => 'bar (b)'], 'b');
193
+
194
+        $this->assertEquals('bar', $translator->trans('bar'));
195
+    }
196
+
197
+    public function testPrimaryAndFallbackCataloguesContainTheSameMessagesRegardlessOfCaching()
198
+    {
199
+        /*
200
+         * As a safeguard against potential BC breaks, make sure that primary and fallback
201
+         * catalogues (reachable via getFallbackCatalogue()) always contain the full set of
202
+         * messages provided by the loader. This must also be the case when these catalogues
203
+         * are (internally) read from a cache.
204
+         *
205
+         * Optimizations inside the translator must not change this behavior.
206
+         */
207
+
208
+        /*
209
+         * Create a translator that loads two catalogues for two different locales.
210
+         * The catalogues contain distinct sets of messages.
211
+         */
212
+        $translator = new Translator('a', null, $this->tmpDir);
213
+        $translator->setFallbackLocales(['b']);
214
+
215
+        $translator->addLoader('array', new ArrayLoader());
216
+        $translator->addResource('array', ['foo' => 'foo (a)'], 'a');
217
+        $translator->addResource('array', ['foo' => 'foo (b)'], 'b');
218
+        $translator->addResource('array', ['bar' => 'bar (b)'], 'b');
219
+        $translator->addResource('array', ['baz' => 'baz (b)'], 'b', 'messages+intl-icu');
220
+
221
+        $catalogue = $translator->getCatalogue('a');
222
+        $this->assertFalse($catalogue->defines('bar')); // Sure, the "a" catalogue does not contain that message.
223
+
224
+        $fallback = $catalogue->getFallbackCatalogue();
225
+        $this->assertTrue($fallback->defines('foo')); // "foo" is present in "a" and "b"
226
+
227
+        /*
228
+         * Now, repeat the same test.
229
+         * Behind the scenes, the cache is used. But that should not matter, right?
230
+         */
231
+        $translator = new Translator('a', null, $this->tmpDir);
232
+        $translator->setFallbackLocales(['b']);
233
+
234
+        $translator->addLoader('array', new ArrayLoader());
235
+        $translator->addResource('array', ['foo' => 'foo (a)'], 'a');
236
+        $translator->addResource('array', ['foo' => 'foo (b)'], 'b');
237
+        $translator->addResource('array', ['bar' => 'bar (b)'], 'b');
238
+        $translator->addResource('array', ['baz' => 'baz (b)'], 'b', 'messages+intl-icu');
239
+
240
+        $catalogue = $translator->getCatalogue('a');
241
+        $this->assertFalse($catalogue->defines('bar'));
242
+
243
+        $fallback = $catalogue->getFallbackCatalogue();
244
+        $this->assertTrue($fallback->defines('foo'));
245
+        $this->assertTrue($fallback->defines('baz', 'messages+intl-icu'));
246
+    }
247
+
248
+    public function testRefreshCacheWhenResourcesAreNoLongerFresh()
249
+    {
250
+        $resource = $this->getMockBuilder('Symfony\Component\Config\Resource\SelfCheckingResourceInterface')->getMock();
251
+        $loader = $this->getMockBuilder('Symfony\Component\Translation\Loader\LoaderInterface')->getMock();
252
+        $resource->method('isFresh')->willReturn(false);
253
+        $loader
254
+            ->expects($this->exactly(2))
255
+            ->method('load')
256
+            ->willReturn($this->getCatalogue('fr', [], [$resource]));
257
+
258
+        // prime the cache
259
+        $translator = new Translator('fr', null, $this->tmpDir, true);
260
+        $translator->addLoader('loader', $loader);
261
+        $translator->addResource('loader', 'foo', 'fr');
262
+        $translator->trans('foo');
263
+
264
+        // prime the cache second time
265
+        $translator = new Translator('fr', null, $this->tmpDir, true);
266
+        $translator->addLoader('loader', $loader);
267
+        $translator->addResource('loader', 'foo', 'fr');
268
+        $translator->trans('foo');
269
+    }
270
+
271
+    protected function getCatalogue($locale, $messages, $resources = [])
272
+    {
273
+        $catalogue = new MessageCatalogue($locale);
274
+        foreach ($messages as $key => $translation) {
275
+            $catalogue->set($key, $translation);
276
+        }
277
+        foreach ($resources as $resource) {
278
+            $catalogue->addResource($resource);
279
+        }
280
+
281
+        return $catalogue;
282
+    }
283
+
284
+    public function runForDebugAndProduction()
285
+    {
286
+        return [[true], [false]];
287
+    }
288
+
289
+    /**
290
+     * @return LoaderInterface
291
+     */
292
+    private function createFailingLoader()
293
+    {
294
+        $loader = $this->getMockBuilder('Symfony\Component\Translation\Loader\LoaderInterface')->getMock();
295
+        $loader
296
+            ->expects($this->never())
297
+            ->method('load');
298
+
299
+        return $loader;
300
+    }
301
+}
302
+
303
+class StaleResource implements SelfCheckingResourceInterface
304
+{
305
+    public function isFresh($timestamp)
306
+    {
307
+        return false;
308
+    }
309
+
310
+    public function getResource()
311
+    {
312
+    }
313
+
314
+    public function __toString()
315
+    {
316
+        return '';
317
+    }
318
+}