ZipTestCase.php 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149
  1. <?php
  2. namespace PhpZip;
  3. use PhpZip\Model\EndOfCentralDirectory;
  4. use PhpZip\Util\FilesUtil;
  5. /**
  6. * PHPUnit test case and helper methods.
  7. */
  8. class ZipTestCase extends \PHPUnit_Framework_TestCase
  9. {
  10. /**
  11. * @var string
  12. */
  13. protected $outputFilename;
  14. /**
  15. * @var string
  16. */
  17. protected $outputDirname;
  18. /**
  19. * Before test
  20. */
  21. protected function setUp()
  22. {
  23. parent::setUp();
  24. $id = uniqid('phpzip', true);
  25. $tempDir = sys_get_temp_dir() . '/phpunit-phpzip';
  26. if (!is_dir($tempDir) && !mkdir($tempDir, 0755, true) && !is_dir($tempDir)) {
  27. throw new \RuntimeException('Dir ' . $tempDir . " can't created");
  28. }
  29. $this->outputFilename = $tempDir . '/' . $id . '.zip';
  30. $this->outputDirname = $tempDir . '/' . $id;
  31. }
  32. /**
  33. * After test
  34. */
  35. protected function tearDown()
  36. {
  37. parent::tearDown();
  38. if ($this->outputFilename !== null && file_exists($this->outputFilename)) {
  39. unlink($this->outputFilename);
  40. }
  41. if ($this->outputDirname !== null && is_dir($this->outputDirname)) {
  42. FilesUtil::removeDir($this->outputDirname);
  43. }
  44. }
  45. /**
  46. * Assert correct zip archive.
  47. *
  48. * @param string $filename
  49. * @param string|null $password
  50. */
  51. public static function assertCorrectZipArchive($filename, $password = null)
  52. {
  53. if (self::existsProgram('unzip')) {
  54. $command = 'unzip';
  55. if ($password !== null) {
  56. $command .= ' -P ' . escapeshellarg($password);
  57. }
  58. $command .= ' -t ' . escapeshellarg($filename);
  59. exec($command, $output, $returnCode);
  60. $output = implode(PHP_EOL, $output);
  61. if ($password !== null && $returnCode === 81) {
  62. if (self::existsProgram('7z')) {
  63. // WinZip 99-character limit
  64. // @see https://sourceforge.net/p/p7zip/discussion/383044/thread/c859a2f0/
  65. $password = substr($password, 0, 99);
  66. $command = '7z t -p' . escapeshellarg($password) . ' ' . escapeshellarg($filename);
  67. exec($command, $output, $returnCode);
  68. /**
  69. * @var array $output
  70. */
  71. $output = implode(PHP_EOL, $output);
  72. self::assertEquals($returnCode, 0);
  73. self::assertNotContains(' Errors', $output);
  74. self::assertContains(' Ok', $output);
  75. } else {
  76. fwrite(STDERR, 'Program unzip cannot support this function.' . PHP_EOL);
  77. fwrite(STDERR, 'Please install 7z. For Ubuntu-like: sudo apt-get install p7zip-full' . PHP_EOL);
  78. }
  79. } else {
  80. self::assertEquals($returnCode, 0, $output);
  81. self::assertNotContains('incorrect password', $output);
  82. self::assertContains(' OK', $output);
  83. self::assertContains('No errors', $output);
  84. }
  85. }
  86. }
  87. /**
  88. * @param string $program
  89. * @return bool
  90. */
  91. private static function existsProgram($program){
  92. if (DIRECTORY_SEPARATOR !== '\\') {
  93. exec('which ' . escapeshellarg($program), $output, $returnCode);
  94. return $returnCode === 0;
  95. }
  96. // false for Windows
  97. return false;
  98. }
  99. /**
  100. * Assert correct empty zip archive.
  101. *
  102. * @param $filename
  103. */
  104. public static function assertCorrectEmptyZip($filename)
  105. {
  106. if (self::existsProgram('zipinfo')) {
  107. exec('zipinfo ' . escapeshellarg($filename), $output, $returnCode);
  108. $output = implode(PHP_EOL, $output);
  109. self::assertContains('Empty zipfile', $output);
  110. }
  111. $actualEmptyZipData = pack('VVVVVv', EndOfCentralDirectory::END_OF_CENTRAL_DIRECTORY_RECORD_SIG, 0, 0, 0, 0, 0);
  112. self::assertStringEqualsFile($filename, $actualEmptyZipData);
  113. }
  114. /**
  115. * @param string $filename
  116. * @param bool $showErrors
  117. * @return bool|null If null - can not install zipalign
  118. */
  119. public static function assertVerifyZipAlign($filename, $showErrors = false)
  120. {
  121. if (self::existsProgram('zipalign')) {
  122. exec('zipalign -c -v 4 ' . escapeshellarg($filename), $output, $returnCode);
  123. if ($showErrors && $returnCode !== 0) {
  124. fwrite(STDERR, implode(PHP_EOL, $output));
  125. }
  126. return $returnCode === 0;
  127. }
  128. fwrite(STDERR, 'Can not find program "zipalign" for test' . PHP_EOL);
  129. return null;
  130. }
  131. }