BundleEntryReaderTest.php 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366
  1. <?php
  2. /*
  3. * This file is part of the Symfony package.
  4. *
  5. * (c) Fabien Potencier <fabien@symfony.com>
  6. *
  7. * For the full copyright and license information, please view the LICENSE
  8. * file that was distributed with this source code.
  9. */
  10. namespace Symfony\Component\Intl\Tests\Data\Bundle\Reader;
  11. use PHPUnit\Framework\TestCase;
  12. use Symfony\Component\Intl\Exception\ResourceBundleNotFoundException;
  13. use Symfony\Component\Intl\Data\Bundle\Reader\BundleEntryReader;
  14. /**
  15. * @author Bernhard Schussek <bschussek@gmail.com>
  16. */
  17. class BundleEntryReaderTest extends TestCase
  18. {
  19. const RES_DIR = '/res/dir';
  20. /**
  21. * @var BundleEntryReader
  22. */
  23. private $reader;
  24. /**
  25. * @var \PHPUnit_Framework_MockObject_MockObject
  26. */
  27. private $readerImpl;
  28. private static $data = array(
  29. 'Entries' => array(
  30. 'Foo' => 'Bar',
  31. 'Bar' => 'Baz',
  32. ),
  33. 'Foo' => 'Bar',
  34. 'Version' => '2.0',
  35. );
  36. private static $fallbackData = array(
  37. 'Entries' => array(
  38. 'Foo' => 'Foo',
  39. 'Bam' => 'Lah',
  40. ),
  41. 'Baz' => 'Foo',
  42. 'Version' => '1.0',
  43. );
  44. private static $mergedData = array(
  45. // no recursive merging -> too complicated
  46. 'Entries' => array(
  47. 'Foo' => 'Bar',
  48. 'Bar' => 'Baz',
  49. ),
  50. 'Baz' => 'Foo',
  51. 'Version' => '2.0',
  52. 'Foo' => 'Bar',
  53. );
  54. protected function setUp()
  55. {
  56. $this->readerImpl = $this->getMockBuilder('Symfony\Component\Intl\Data\Bundle\Reader\BundleEntryReaderInterface')->getMock();
  57. $this->reader = new BundleEntryReader($this->readerImpl);
  58. }
  59. public function testForwardCallToRead()
  60. {
  61. $this->readerImpl->expects($this->once())
  62. ->method('read')
  63. ->with(self::RES_DIR, 'root')
  64. ->will($this->returnValue(self::$data));
  65. $this->assertSame(self::$data, $this->reader->read(self::RES_DIR, 'root'));
  66. }
  67. public function testReadEntireDataFileIfNoIndicesGiven()
  68. {
  69. $this->readerImpl->expects($this->at(0))
  70. ->method('read')
  71. ->with(self::RES_DIR, 'en')
  72. ->will($this->returnValue(self::$data));
  73. $this->readerImpl->expects($this->at(1))
  74. ->method('read')
  75. ->with(self::RES_DIR, 'root')
  76. ->will($this->returnValue(self::$fallbackData));
  77. $this->assertSame(self::$mergedData, $this->reader->readEntry(self::RES_DIR, 'en', array()));
  78. }
  79. public function testReadExistingEntry()
  80. {
  81. $this->readerImpl->expects($this->once())
  82. ->method('read')
  83. ->with(self::RES_DIR, 'root')
  84. ->will($this->returnValue(self::$data));
  85. $this->assertSame('Bar', $this->reader->readEntry(self::RES_DIR, 'root', array('Entries', 'Foo')));
  86. }
  87. /**
  88. * @expectedException \Symfony\Component\Intl\Exception\MissingResourceException
  89. */
  90. public function testReadNonExistingEntry()
  91. {
  92. $this->readerImpl->expects($this->once())
  93. ->method('read')
  94. ->with(self::RES_DIR, 'root')
  95. ->will($this->returnValue(self::$data));
  96. $this->reader->readEntry(self::RES_DIR, 'root', array('Entries', 'NonExisting'));
  97. }
  98. public function testFallbackIfEntryDoesNotExist()
  99. {
  100. $this->readerImpl->expects($this->at(0))
  101. ->method('read')
  102. ->with(self::RES_DIR, 'en_GB')
  103. ->will($this->returnValue(self::$data));
  104. $this->readerImpl->expects($this->at(1))
  105. ->method('read')
  106. ->with(self::RES_DIR, 'en')
  107. ->will($this->returnValue(self::$fallbackData));
  108. $this->assertSame('Lah', $this->reader->readEntry(self::RES_DIR, 'en_GB', array('Entries', 'Bam')));
  109. }
  110. /**
  111. * @expectedException \Symfony\Component\Intl\Exception\MissingResourceException
  112. */
  113. public function testDontFallbackIfEntryDoesNotExistAndFallbackDisabled()
  114. {
  115. $this->readerImpl->expects($this->once())
  116. ->method('read')
  117. ->with(self::RES_DIR, 'en_GB')
  118. ->will($this->returnValue(self::$data));
  119. $this->reader->readEntry(self::RES_DIR, 'en_GB', array('Entries', 'Bam'), false);
  120. }
  121. public function testFallbackIfLocaleDoesNotExist()
  122. {
  123. $this->readerImpl->expects($this->at(0))
  124. ->method('read')
  125. ->with(self::RES_DIR, 'en_GB')
  126. ->will($this->throwException(new ResourceBundleNotFoundException()));
  127. $this->readerImpl->expects($this->at(1))
  128. ->method('read')
  129. ->with(self::RES_DIR, 'en')
  130. ->will($this->returnValue(self::$fallbackData));
  131. $this->assertSame('Lah', $this->reader->readEntry(self::RES_DIR, 'en_GB', array('Entries', 'Bam')));
  132. }
  133. /**
  134. * @expectedException \Symfony\Component\Intl\Exception\MissingResourceException
  135. */
  136. public function testDontFallbackIfLocaleDoesNotExistAndFallbackDisabled()
  137. {
  138. $this->readerImpl->expects($this->once())
  139. ->method('read')
  140. ->with(self::RES_DIR, 'en_GB')
  141. ->will($this->throwException(new ResourceBundleNotFoundException()));
  142. $this->reader->readEntry(self::RES_DIR, 'en_GB', array('Entries', 'Bam'), false);
  143. }
  144. public function provideMergeableValues()
  145. {
  146. return array(
  147. array('foo', null, 'foo'),
  148. array(null, 'foo', 'foo'),
  149. array(array('foo', 'bar'), null, array('foo', 'bar')),
  150. array(array('foo', 'bar'), array(), array('foo', 'bar')),
  151. array(null, array('baz'), array('baz')),
  152. array(array(), array('baz'), array('baz')),
  153. array(array('foo', 'bar'), array('baz'), array('baz', 'foo', 'bar')),
  154. );
  155. }
  156. /**
  157. * @dataProvider provideMergeableValues
  158. */
  159. public function testMergeDataWithFallbackData($childData, $parentData, $result)
  160. {
  161. if (null === $childData || is_array($childData)) {
  162. $this->readerImpl->expects($this->at(0))
  163. ->method('read')
  164. ->with(self::RES_DIR, 'en')
  165. ->will($this->returnValue($childData));
  166. $this->readerImpl->expects($this->at(1))
  167. ->method('read')
  168. ->with(self::RES_DIR, 'root')
  169. ->will($this->returnValue($parentData));
  170. } else {
  171. $this->readerImpl->expects($this->once())
  172. ->method('read')
  173. ->with(self::RES_DIR, 'en')
  174. ->will($this->returnValue($childData));
  175. }
  176. $this->assertSame($result, $this->reader->readEntry(self::RES_DIR, 'en', array(), true));
  177. }
  178. /**
  179. * @dataProvider provideMergeableValues
  180. */
  181. public function testDontMergeDataIfFallbackDisabled($childData, $parentData, $result)
  182. {
  183. $this->readerImpl->expects($this->once())
  184. ->method('read')
  185. ->with(self::RES_DIR, 'en_GB')
  186. ->will($this->returnValue($childData));
  187. $this->assertSame($childData, $this->reader->readEntry(self::RES_DIR, 'en_GB', array(), false));
  188. }
  189. /**
  190. * @dataProvider provideMergeableValues
  191. */
  192. public function testMergeExistingEntryWithExistingFallbackEntry($childData, $parentData, $result)
  193. {
  194. if (null === $childData || is_array($childData)) {
  195. $this->readerImpl->expects($this->at(0))
  196. ->method('read')
  197. ->with(self::RES_DIR, 'en')
  198. ->will($this->returnValue(array('Foo' => array('Bar' => $childData))));
  199. $this->readerImpl->expects($this->at(1))
  200. ->method('read')
  201. ->with(self::RES_DIR, 'root')
  202. ->will($this->returnValue(array('Foo' => array('Bar' => $parentData))));
  203. } else {
  204. $this->readerImpl->expects($this->once())
  205. ->method('read')
  206. ->with(self::RES_DIR, 'en')
  207. ->will($this->returnValue(array('Foo' => array('Bar' => $childData))));
  208. }
  209. $this->assertSame($result, $this->reader->readEntry(self::RES_DIR, 'en', array('Foo', 'Bar'), true));
  210. }
  211. /**
  212. * @dataProvider provideMergeableValues
  213. */
  214. public function testMergeNonExistingEntryWithExistingFallbackEntry($childData, $parentData, $result)
  215. {
  216. $this->readerImpl->expects($this->at(0))
  217. ->method('read')
  218. ->with(self::RES_DIR, 'en_GB')
  219. ->will($this->returnValue(array('Foo' => 'Baz')));
  220. $this->readerImpl->expects($this->at(1))
  221. ->method('read')
  222. ->with(self::RES_DIR, 'en')
  223. ->will($this->returnValue(array('Foo' => array('Bar' => $parentData))));
  224. $this->assertSame($parentData, $this->reader->readEntry(self::RES_DIR, 'en_GB', array('Foo', 'Bar'), true));
  225. }
  226. /**
  227. * @dataProvider provideMergeableValues
  228. */
  229. public function testMergeExistingEntryWithNonExistingFallbackEntry($childData, $parentData, $result)
  230. {
  231. if (null === $childData || is_array($childData)) {
  232. $this->readerImpl->expects($this->at(0))
  233. ->method('read')
  234. ->with(self::RES_DIR, 'en_GB')
  235. ->will($this->returnValue(array('Foo' => array('Bar' => $childData))));
  236. $this->readerImpl->expects($this->at(1))
  237. ->method('read')
  238. ->with(self::RES_DIR, 'en')
  239. ->will($this->returnValue(array('Foo' => 'Bar')));
  240. } else {
  241. $this->readerImpl->expects($this->once())
  242. ->method('read')
  243. ->with(self::RES_DIR, 'en_GB')
  244. ->will($this->returnValue(array('Foo' => array('Bar' => $childData))));
  245. }
  246. $this->assertSame($childData, $this->reader->readEntry(self::RES_DIR, 'en_GB', array('Foo', 'Bar'), true));
  247. }
  248. /**
  249. * @expectedException \Symfony\Component\Intl\Exception\MissingResourceException
  250. */
  251. public function testFailIfEntryFoundNeitherInParentNorChild()
  252. {
  253. $this->readerImpl->expects($this->at(0))
  254. ->method('read')
  255. ->with(self::RES_DIR, 'en_GB')
  256. ->will($this->returnValue(array('Foo' => 'Baz')));
  257. $this->readerImpl->expects($this->at(1))
  258. ->method('read')
  259. ->with(self::RES_DIR, 'en')
  260. ->will($this->returnValue(array('Foo' => 'Bar')));
  261. $this->reader->readEntry(self::RES_DIR, 'en_GB', array('Foo', 'Bar'), true);
  262. }
  263. /**
  264. * @dataProvider provideMergeableValues
  265. */
  266. public function testMergeTraversables($childData, $parentData, $result)
  267. {
  268. $parentData = is_array($parentData) ? new \ArrayObject($parentData) : $parentData;
  269. $childData = is_array($childData) ? new \ArrayObject($childData) : $childData;
  270. if (null === $childData || $childData instanceof \ArrayObject) {
  271. $this->readerImpl->expects($this->at(0))
  272. ->method('read')
  273. ->with(self::RES_DIR, 'en_GB')
  274. ->will($this->returnValue(array('Foo' => array('Bar' => $childData))));
  275. $this->readerImpl->expects($this->at(1))
  276. ->method('read')
  277. ->with(self::RES_DIR, 'en')
  278. ->will($this->returnValue(array('Foo' => array('Bar' => $parentData))));
  279. } else {
  280. $this->readerImpl->expects($this->once())
  281. ->method('read')
  282. ->with(self::RES_DIR, 'en_GB')
  283. ->will($this->returnValue(array('Foo' => array('Bar' => $childData))));
  284. }
  285. $this->assertSame($result, $this->reader->readEntry(self::RES_DIR, 'en_GB', array('Foo', 'Bar'), true));
  286. }
  287. /**
  288. * @dataProvider provideMergeableValues
  289. */
  290. public function testFollowLocaleAliases($childData, $parentData, $result)
  291. {
  292. $this->reader->setLocaleAliases(array('mo' => 'ro_MD'));
  293. if (null === $childData || is_array($childData)) {
  294. $this->readerImpl->expects($this->at(0))
  295. ->method('read')
  296. ->with(self::RES_DIR, 'ro_MD')
  297. ->will($this->returnValue(array('Foo' => array('Bar' => $childData))));
  298. // Read fallback locale of aliased locale ("ro_MD" -> "ro")
  299. $this->readerImpl->expects($this->at(1))
  300. ->method('read')
  301. ->with(self::RES_DIR, 'ro')
  302. ->will($this->returnValue(array('Foo' => array('Bar' => $parentData))));
  303. } else {
  304. $this->readerImpl->expects($this->once())
  305. ->method('read')
  306. ->with(self::RES_DIR, 'ro_MD')
  307. ->will($this->returnValue(array('Foo' => array('Bar' => $childData))));
  308. }
  309. $this->assertSame($result, $this->reader->readEntry(self::RES_DIR, 'mo', array('Foo', 'Bar'), true));
  310. }
  311. }