AssetCollectionTest.php 8.1KB

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