You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

267 lines
9.9KB

  1. <?php
  2. /*
  3. * This file is part of the Fxp Composer Asset Plugin package.
  4. *
  5. * (c) François Pluchino <francois.pluchino@gmail.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 Fxp\Composer\AssetPlugin\Tests\Repository\Vcs;
  11. use Composer\IO\IOInterface;
  12. use Composer\Util\Filesystem;
  13. use Composer\Config;
  14. use Composer\Util\ProcessExecutor;
  15. use Fxp\Composer\AssetPlugin\Repository\Vcs\SvnDriver;
  16. /**
  17. * Tests of vcs svn repository.
  18. *
  19. * @author François Pluchino <francois.pluchino@gmail.com>
  20. */
  21. class SvnDriverTest extends \PHPUnit_Framework_TestCase
  22. {
  23. /**
  24. * @var Config
  25. */
  26. private $config;
  27. public function setUp()
  28. {
  29. $this->config = new Config();
  30. $this->config->merge(array(
  31. 'config' => array(
  32. 'home' => sys_get_temp_dir().'/composer-test',
  33. 'cache-repo-dir' => sys_get_temp_dir().'/composer-test-cache',
  34. ),
  35. ));
  36. }
  37. public function tearDown()
  38. {
  39. $fs = new Filesystem();
  40. $fs->removeDirectory(sys_get_temp_dir().'/composer-test');
  41. $fs->removeDirectory(sys_get_temp_dir().'/composer-test-cache');
  42. }
  43. public function getAssetTypes()
  44. {
  45. return array(
  46. array('npm', 'package.json', '1234'),
  47. array('npm', 'package.json', '/@1234'),
  48. array('bower', 'bower.json', '1234'),
  49. array('bower', 'bower.json', '/@1234'),
  50. );
  51. }
  52. /**
  53. * @dataProvider getAssetTypes
  54. */
  55. public function testPublicRepositoryWithEmptyComposer($type, $filename, $identifier)
  56. {
  57. $repoUrl = 'svn://example.tld/composer-test/repo-name/trunk';
  58. $io = $this->getMock('Composer\IO\IOInterface');
  59. $repoConfig = array(
  60. 'url' => $repoUrl,
  61. 'asset-type' => $type,
  62. 'filename' => $filename,
  63. );
  64. $process = $this->getMock('Composer\Util\ProcessExecutor');
  65. $process->expects($this->any())
  66. ->method('splitLines')
  67. ->will($this->returnValue(array()));
  68. $process->expects($this->any())
  69. ->method('execute')
  70. ->will($this->returnCallback(function () {
  71. return 0;
  72. }));
  73. /* @var IOInterface $io */
  74. /* @var ProcessExecutor $process */
  75. $driver = new SvnDriver($repoConfig, $io, $this->config, $process, null);
  76. $driver->initialize();
  77. $validEmpty = array(
  78. '_nonexistent_package' => true,
  79. );
  80. $this->assertSame($validEmpty, $driver->getComposerInformation($identifier));
  81. }
  82. /**
  83. * @dataProvider getAssetTypes
  84. */
  85. public function testPublicRepositoryWithCodeCache($type, $filename, $identifier)
  86. {
  87. $repoBaseUrl = 'svn://example.tld/composer-test/repo-name';
  88. $repoUrl = $repoBaseUrl.'/trunk';
  89. $repoConfig = array(
  90. 'url' => $repoUrl,
  91. 'asset-type' => $type,
  92. 'filename' => $filename,
  93. );
  94. $io = $this->getMock('Composer\IO\IOInterface');
  95. $process = $this->getMock('Composer\Util\ProcessExecutor');
  96. $process->expects($this->any())
  97. ->method('splitLines')
  98. ->will($this->returnCallback(function ($value) {
  99. return is_string($value) ? preg_split('{\r?\n}', $value) : array();
  100. }));
  101. $process->expects($this->any())
  102. ->method('execute')
  103. ->will($this->returnCallback(function ($command, &$output) use ($repoBaseUrl, $identifier, $repoConfig) {
  104. if ($command === sprintf('svn cat --non-interactive %s', ProcessExecutor::escape(sprintf('%s/%s/%s', $repoBaseUrl, $identifier, $repoConfig['filename'])))
  105. || $command === sprintf('svn cat --non-interactive %s', ProcessExecutor::escape(sprintf('%s/%s%s', $repoBaseUrl, $repoConfig['filename'], trim($identifier, '/'))))) {
  106. $output('out', '{"name": "foo"}');
  107. } elseif ($command === sprintf('svn info --non-interactive %s', ProcessExecutor::escape(sprintf('%s/%s/', $repoBaseUrl, $identifier)))
  108. || $command === sprintf('svn info --non-interactive %s', ProcessExecutor::escape(sprintf('%s/%s', $repoBaseUrl, trim($identifier, '/'))))) {
  109. $date = new \DateTime(null, new \DateTimeZone('UTC'));
  110. $value = array(
  111. 'Last Changed Rev: '.$identifier,
  112. 'Last Changed Date: '.$date->format('Y-m-d H:i:s O').' ('.$date->format('l, j F Y').')',
  113. );
  114. $output('out', implode(PHP_EOL, $value));
  115. }
  116. return 0;
  117. }));
  118. /* @var IOInterface $io */
  119. /* @var ProcessExecutor $process */
  120. $driver = new SvnDriver($repoConfig, $io, $this->config, $process, null);
  121. $driver->initialize();
  122. $composer1 = $driver->getComposerInformation($identifier);
  123. $composer2 = $driver->getComposerInformation($identifier);
  124. $this->assertNotNull($composer1);
  125. $this->assertNotNull($composer2);
  126. $this->assertSame($composer1, $composer2);
  127. $this->assertArrayHasKey('time', $composer1);
  128. }
  129. /**
  130. * @dataProvider getAssetTypes
  131. */
  132. public function testPublicRepositoryWithFilesystemCache($type, $filename, $identifier)
  133. {
  134. $repoBaseUrl = 'svn://example.tld/composer-test/repo-name';
  135. $repoUrl = $repoBaseUrl.'/trunk';
  136. $repoConfig = array(
  137. 'url' => $repoUrl,
  138. 'asset-type' => $type,
  139. 'filename' => $filename,
  140. );
  141. $io = $this->getMock('Composer\IO\IOInterface');
  142. $process = $this->getMock('Composer\Util\ProcessExecutor');
  143. $process->expects($this->any())
  144. ->method('splitLines')
  145. ->will($this->returnCallback(function ($value) {
  146. return is_string($value) ? preg_split('{\r?\n}', $value) : array();
  147. }));
  148. $process->expects($this->any())
  149. ->method('execute')
  150. ->will($this->returnCallback(function ($command, &$output) use ($repoBaseUrl, $identifier, $repoConfig) {
  151. if ($command === sprintf('svn cat --non-interactive %s', ProcessExecutor::escape(sprintf('%s/%s/%s', $repoBaseUrl, $identifier, $repoConfig['filename'])))
  152. || $command === sprintf('svn cat --non-interactive %s', ProcessExecutor::escape(sprintf('%s/%s%s', $repoBaseUrl, $repoConfig['filename'], trim($identifier, '/'))))) {
  153. $output('out', '{"name": "foo"}');
  154. } elseif ($command === sprintf('svn info --non-interactive %s', ProcessExecutor::escape(sprintf('%s/%s/', $repoBaseUrl, $identifier)))
  155. || $command === sprintf('svn info --non-interactive %s', ProcessExecutor::escape(sprintf('%s/%s', $repoBaseUrl, trim($identifier, '/'))))) {
  156. $date = new \DateTime(null, new \DateTimeZone('UTC'));
  157. $value = array(
  158. 'Last Changed Rev: '.$identifier,
  159. 'Last Changed Date: '.$date->format('Y-m-d H:i:s O').' ('.$date->format('l, j F Y').')',
  160. );
  161. $output('out', implode(PHP_EOL, $value));
  162. }
  163. return 0;
  164. }));
  165. /* @var IOInterface $io */
  166. /* @var ProcessExecutor $process */
  167. $driver1 = new SvnDriver($repoConfig, $io, $this->config, $process, null);
  168. $driver2 = new SvnDriver($repoConfig, $io, $this->config, $process, null);
  169. $driver1->initialize();
  170. $driver2->initialize();
  171. $composer1 = $driver1->getComposerInformation($identifier);
  172. $composer2 = $driver2->getComposerInformation($identifier);
  173. $this->assertNotNull($composer1);
  174. $this->assertNotNull($composer2);
  175. $this->assertSame($composer1, $composer2);
  176. $this->assertArrayHasKey('time', $composer1);
  177. }
  178. /**
  179. * @dataProvider getAssetTypes
  180. */
  181. public function testPublicRepositoryWithInvalidUrl($type, $filename, $identifier)
  182. {
  183. $this->setExpectedException('Composer\Downloader\TransportException');
  184. $repoUrl = 'svn://example.tld/composer-test/repo-name/trunk';
  185. $io = $this->getMock('Composer\IO\IOInterface');
  186. $repoConfig = array(
  187. 'url' => $repoUrl,
  188. 'asset-type' => $type,
  189. 'filename' => $filename,
  190. );
  191. $process = $this->getMock('Composer\Util\ProcessExecutor');
  192. $process->expects($this->any())
  193. ->method('splitLines')
  194. ->will($this->returnValue(array()));
  195. $process->expects($this->any())
  196. ->method('execute')
  197. ->will($this->returnCallback(function ($command) {
  198. return 0 === strpos($command, 'svn cat ') ? 1 : 0;
  199. }));
  200. /* @var IOInterface $io */
  201. /* @var ProcessExecutor $process */
  202. $driver = new SvnDriver($repoConfig, $io, $this->config, $process, null);
  203. $driver->initialize();
  204. $driver->getComposerInformation($identifier);
  205. }
  206. /**
  207. * @return array
  208. */
  209. public function getSupportsUrls()
  210. {
  211. return array(
  212. array('svn://example.tld/trunk', true),
  213. array('svn+ssh://example.tld/trunk', true),
  214. array('svn://svn.example.tld/trunk', true),
  215. array('svn+ssh://svn.example.tld/trunk', true),
  216. array('http://example.tld/svn/trunk', true),
  217. array('https://example.tld/svn/trunk', true),
  218. array('http://example.tld/sub', false),
  219. array('https://example.tld/sub', false),
  220. );
  221. }
  222. /**
  223. * @dataProvider getSupportsUrls
  224. */
  225. public function testSupports($url, $supperted)
  226. {
  227. /* @var IOInterface $io */
  228. $io = $this->getMock('Composer\IO\IOInterface');
  229. $this->assertSame($supperted, SvnDriver::supports($io, $this->config, $url, false));
  230. }
  231. }