AssetCollectionTest.php 8.1KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261
  1. <?php
  2. /*
  3. * This file is part of the Assetic package, an OpenSky project.
  4. *
  5. * (c) 2010-2012 OpenSky Project Inc
  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 Assetic\Test\Asset;
  11. use Assetic\Asset\StringAsset;
  12. use Assetic\Asset\AssetCollection;
  13. use Assetic\Filter\CallablesFilter;
  14. class AssetCollectionTest extends \PHPUnit_Framework_TestCase
  15. {
  16. public function testInterface()
  17. {
  18. $coll = new AssetCollection();
  19. $this->assertInstanceOf('Assetic\\Asset\\AssetInterface', $coll, 'AssetCollection implements AssetInterface');
  20. }
  21. public function testLoadFilter()
  22. {
  23. $filter = $this->getMock('Assetic\\Filter\\FilterInterface');
  24. $filter->expects($this->once())->method('filterLoad');
  25. $coll = new AssetCollection(array(new StringAsset('')), array($filter));
  26. $coll->load();
  27. }
  28. public function testDumpFilter()
  29. {
  30. $filter = $this->getMock('Assetic\\Filter\\FilterInterface');
  31. $filter->expects($this->once())->method('filterDump');
  32. $coll = new AssetCollection(array(new StringAsset('')), array($filter));
  33. $coll->dump();
  34. }
  35. public function testNestedCollectionLoad()
  36. {
  37. $content = 'foobar';
  38. $count = 0;
  39. $matches = array();
  40. $filter = new CallablesFilter(function($asset) use ($content, &$matches, &$count) {
  41. ++$count;
  42. if ($content == $asset->getContent()) {
  43. $matches[] = $asset;
  44. }
  45. });
  46. $innerColl = new AssetCollection(array(new StringAsset($content)));
  47. $outerColl = new AssetCollection(array($innerColl), array($filter));
  48. $outerColl->load();
  49. $this->assertEquals(1, count($matches), '->load() applies filters to leaves');
  50. $this->assertEquals(1, $count, '->load() applies filters to leaves only');
  51. }
  52. public function testMixedIteration()
  53. {
  54. $asset = new StringAsset('asset');
  55. $nestedAsset = new StringAsset('nested');
  56. $innerColl = new AssetCollection(array($nestedAsset));
  57. $contents = array();
  58. $filter = new CallablesFilter(function($asset) use (&$contents) {
  59. $contents[] = $asset->getContent();
  60. });
  61. $coll = new AssetCollection(array($asset, $innerColl), array($filter));
  62. $coll->load();
  63. $this->assertEquals(array('asset', 'nested'), $contents, '->load() iterates over multiple levels');
  64. }
  65. public function testLoadDedupBySourceUrl()
  66. {
  67. $asset1 = new StringAsset('asset', array(), '/some/dir', 'foo.bar');
  68. $asset2 = new StringAsset('asset', array(), '/some/dir', 'foo.bar');
  69. $coll = new AssetCollection(array($asset1, $asset2));
  70. $coll->load();
  71. $this->assertEquals('asset', $coll->getContent(), '->load() detects duplicate assets based on source URL');
  72. }
  73. public function testLoadDedupByStrictEquality()
  74. {
  75. $asset = new StringAsset('foo');
  76. $coll = new AssetCollection(array($asset, $asset));
  77. $coll->load();
  78. $this->assertEquals('foo', $coll->getContent(), '->load() detects duplicate assets based on strict equality');
  79. }
  80. public function testDumpDedupBySourceUrl()
  81. {
  82. $asset1 = new StringAsset('asset', array(), '/some/dir', 'foo.bar');
  83. $asset2 = new StringAsset('asset', array(), '/some/dir', 'foo.bar');
  84. $coll = new AssetCollection(array($asset1, $asset2));
  85. $coll->load();
  86. $this->assertEquals('asset', $coll->dump(), '->dump() detects duplicate assets based on source URL');
  87. }
  88. public function testDumpDedupByStrictEquality()
  89. {
  90. $asset = new StringAsset('foo');
  91. $coll = new AssetCollection(array($asset, $asset));
  92. $coll->load();
  93. $this->assertEquals('foo', $coll->dump(), '->dump() detects duplicate assets based on strict equality');
  94. }
  95. public function testIterationFilters()
  96. {
  97. $count = 0;
  98. $filter = new CallablesFilter(function() use (&$count) { ++$count; });
  99. $coll = new AssetCollection();
  100. $coll->add(new StringAsset(''));
  101. $coll->ensureFilter($filter);
  102. foreach ($coll as $asset) {
  103. $asset->dump();
  104. }
  105. $this->assertEquals(1, $count, 'collection filters are called when child assets are iterated over');
  106. }
  107. public function testSetContent()
  108. {
  109. $coll = new AssetCollection();
  110. $coll->setContent('asdf');
  111. $this->assertEquals('asdf', $coll->getContent(), '->setContent() sets the content');
  112. }
  113. /**
  114. * @dataProvider getTimestampsAndExpected
  115. */
  116. public function testGetLastModified($timestamps, $expected)
  117. {
  118. $asset = $this->getMock('Assetic\\Asset\\AssetInterface');
  119. for ($i = 0; $i < count($timestamps); $i++) {
  120. $asset->expects($this->at($i))
  121. ->method('getLastModified')
  122. ->will($this->returnValue($timestamps[$i]));
  123. }
  124. $coll = new AssetCollection(array_fill(0, count($timestamps), $asset));
  125. $this->assertEquals($expected, $coll->getLastModified(), '->getLastModifed() returns the highest last modified');
  126. }
  127. public function getTimestampsAndExpected()
  128. {
  129. return array(
  130. array(array(1, 2, 3), 3),
  131. array(array(5, 4, 3), 5),
  132. array(array(3, 8, 5), 8),
  133. array(array(3, 8, null), 8),
  134. );
  135. }
  136. public function testRecursiveIteration()
  137. {
  138. $asset1 = $this->getMock('Assetic\\Asset\\AssetInterface');
  139. $asset2 = $this->getMock('Assetic\\Asset\\AssetInterface');
  140. $asset3 = $this->getMock('Assetic\\Asset\\AssetInterface');
  141. $asset4 = $this->getMock('Assetic\\Asset\\AssetInterface');
  142. $coll3 = new AssetCollection(array($asset1, $asset2));
  143. $coll2 = new AssetCollection(array($asset3, $coll3));
  144. $coll1 = new AssetCollection(array($asset4, $coll2));
  145. $i = 0;
  146. foreach ($coll1 as $a) {
  147. $i++;
  148. }
  149. $this->assertEquals(4, $i, 'iteration with a recursive iterator is recursive');
  150. }
  151. public function testRecursiveDeduplication()
  152. {
  153. $asset = $this->getMock('Assetic\\Asset\\AssetInterface');
  154. $coll3 = new AssetCollection(array($asset, $asset));
  155. $coll2 = new AssetCollection(array($asset, $coll3));
  156. $coll1 = new AssetCollection(array($asset, $coll2));
  157. $i = 0;
  158. foreach ($coll1 as $a) {
  159. $i++;
  160. }
  161. $this->assertEquals(1, $i, 'deduplication is performed recursively');
  162. }
  163. public function testIteration()
  164. {
  165. $asset1 = new StringAsset('asset1', array(), '/some/dir', 'foo.css');
  166. $asset2 = new StringAsset('asset2', array(), '/some/dir', 'foo.css');
  167. $asset3 = new StringAsset('asset3', array(), '/some/dir', 'bar.css');
  168. $coll = new AssetCollection(array($asset1, $asset2, $asset3));
  169. $count = 0;
  170. foreach ($coll as $a) {
  171. ++$count;
  172. }
  173. $this->assertEquals(2, $count, 'iterator filters duplicates based on url');
  174. }
  175. public function testBasenameCollision()
  176. {
  177. $asset1 = new StringAsset('asset1', array(), '/some/dir', 'foo/foo.css');
  178. $asset2 = new StringAsset('asset2', array(), '/some/dir', 'bar/foo.css');
  179. $coll = new AssetCollection(array($asset1, $asset2));
  180. $urls = array();
  181. foreach ($coll as $leaf) {
  182. $urls[] = $leaf->getTargetPath();
  183. }
  184. $this->assertEquals(2, count(array_unique($urls)), 'iterator prevents basename collisions');
  185. }
  186. public function testEmptyMtime()
  187. {
  188. $coll = new AssetCollection();
  189. $this->assertNull($coll->getLastModified(), '->getLastModified() returns null on empty collection');
  190. }
  191. public function testLeafManipulation()
  192. {
  193. $coll = new AssetCollection(array(new StringAsset('asdf')));
  194. foreach ($coll as $leaf) {
  195. $leaf->setTargetPath('asdf');
  196. }
  197. foreach ($coll as $leaf) {
  198. $this->assertEquals('asdf', $leaf->getTargetPath(), 'leaf changes persist between iterations');
  199. }
  200. }
  201. }