diff options
Diffstat (limited to 'tests')
| -rw-r--r-- | tests/AddFileTest.php | 67 | ||||
| -rw-r--r-- | tests/ArchiveTest.php | 89 | ||||
| -rw-r--r-- | tests/BaseTestCase.php | 49 | ||||
| -rw-r--r-- | tests/LargeFileTest.php | 35 | ||||
| -rw-r--r-- | tests/PathTest.php | 83 | 
5 files changed, 323 insertions, 0 deletions
diff --git a/tests/AddFileTest.php b/tests/AddFileTest.php new file mode 100644 index 0000000..3ea65e0 --- /dev/null +++ b/tests/AddFileTest.php @@ -0,0 +1,67 @@ +<?php +declare(strict_types = 1); + +namespace Pablotron\ZipStream\Tests; + +use \PHPUnit\Framework\TestCase; +use \Pablotron\ZipStream\ZipStream; + +final class AddFileTest extends BaseTestCase { +  public function testCreateFile() : void { +    $this->with_temp_zip(function(ZipStream &$zip) { +      $zip->add_file('hello.txt', 'hello!'); +    }, function(string $path) { +      $zip = $this->open_archive($path); + +      $this->assertEquals( +        'hello!', +        $zip->getFromName('hello.txt') +      ); +    }); +  } + +  public function testCreateFileWithComment() : void { +    $comment = 'test comment'; +    $this->with_temp_zip(function(ZipStream &$zip) use ($comment) { +      $zip->add_file('hello.txt', 'hello!', [ +        'comment' => $comment, +      ]); +    }, function(string $path) use ($comment) { +      $zip = $this->open_archive($path); + +      $this->assertEquals( +        $comment, +        $zip->getCommentName('hello.txt') +      ); +    }); +  } + +  public function testCreateFileWithUnknownMethod() : void { +    $this->expectException(\Pablotron\ZipStream\UnknownMethodError::class); + +    $this->with_temp_zip(function(ZipStream &$zip) { +      $zip->add_file('hello.txt', 'hello!', [ +        'method'  => -20, +      ]); +    }); +  } + +  public function testCreateFileTimestamp() : void { +    # get timezone offset +    # $ofs = \DateTimeZone::getOffset(\DateTime::getTimezone()); +    $ofs = 4 * 3600; # hard-coded to EDT for now + +    # get time from 2 hours ago (round to even number of seconds) +    $time = ((time() - (2 * 3600)) >> 1) << 1; + +    $this->with_temp_zip(function(ZipStream &$zip) use ($time) { +      $zip->add_file('hello.txt', 'hello!', [ +        'time' => $time, +      ]); +    }, function($zip_path) use ($time, $ofs) { +      $zip = $this->open_archive($zip_path); +      $st = $zip->statName('hello.txt'); +      $this->assertEquals($time, $st['mtime'] - $ofs); +    }); +  } +}; diff --git a/tests/ArchiveTest.php b/tests/ArchiveTest.php new file mode 100644 index 0000000..cbac0f1 --- /dev/null +++ b/tests/ArchiveTest.php @@ -0,0 +1,89 @@ +<?php +declare(strict_types = 1); + +namespace Pablotron\ZipStream\Tests; + +use PHPUnit\Framework\TestCase; +use Pablotron\ZipStream\ZipStream; +use Pablotron\ZipStream\FileWriter; +use Pablotron\ZipStream\StreamWriter; + +final class ArchiveTest extends BaseTestCase { +  public function testCreate() : void { +    $zip = new ZipStream('test.zip'); + +    $this->assertInstanceOf( +      ZipStream::class, +      $zip +    ); +  } + +  public function testFileWriter() { +    $this->with_temp_file(function(string $dst_path) { +      ZipStream::send($dst_path, function(ZipStream &$zip) { +        $zip->add_file('hello.txt', 'hello!'); +      }, [ +        'output' => new FileWriter(), +      ]); + +      # open archive +      $zip = $this->open_archive($dst_path); + +      # read hello.txt, check text +      $this->assertEquals( +        'hello!', +        $zip->getFromName('hello.txt') +      ); +    }); +  } + +  public function testStreamWriter() { +    $this->with_temp_file(function(string $dst_path) { +      $fh = fopen($dst_path, 'wb'); +      if ($fh === false) { +        throw new Exception("fopen() failed"); +      } + +      ZipStream::send($dst_path, function(ZipStream &$zip) { +        $zip->add_file('hello.txt', 'hello!'); +      }, [ +        'output' => new StreamWriter($fh), +      ]); + +      # close stream +      fclose($fh); + +      # open archive +      $zip = $this->open_archive($dst_path); + +      # read hello.txt, check text +      $this->assertEquals( +        'hello!', +        $zip->getFromName('hello.txt') +      ); +    }); +  } + +  public function testArchiveComment() : void { +    $this->with_temp_file(function($dst_path) { +      $comment = 'test archive comment'; + +      # write archive +      ZipStream::send($dst_path, function(ZipStream &$zip) { +        $zip->add_file('hello.txt', 'hello!'); +      }, [ +        'comment' => $comment, +        'output'  => new FileWriter(), +      ]); + +      # open archive +      $zip = $this->open_archive($dst_path); + +      # read hello.txt, check text +      $this->assertEquals( +        $comment, +        $zip->getArchiveComment() +      ); +    }); +  } +}; diff --git a/tests/BaseTestCase.php b/tests/BaseTestCase.php new file mode 100644 index 0000000..8934e96 --- /dev/null +++ b/tests/BaseTestCase.php @@ -0,0 +1,49 @@ +<?php +declare(strict_types = 1); + +namespace Pablotron\ZipStream\Tests; + +use PHPUnit\Framework\TestCase; +use \Pablotron\ZipStream\ZipStream; +use \Pablotron\ZipStream\FileWriter; + +class BaseTestCase extends TestCase { +  protected function open_archive(string $path) { +    # open archive, check for error +    $zip = new \ZipArchive(); +    if ($zip->open($path) !== true) { +      throw new Exception("ZipArchive#open() failed: $dst_name"); +    } + +    # return archive +    return $zip; +  } + +  protected function with_temp_file(callable $cb) : void { +    # build path to temp file +    $path = tempnam('/tmp', 'zipstream-test'); +    try { +      # pass to test +      $cb($path); +    } finally { +      if (file_exists($path)) { +        # remove temp file if it exists +        unlink($path); +      } +    } +  } + +  protected function with_temp_zip(callable $zip_cb, callable $test_cb = null) { +    $this->with_temp_file(function(string $dst_path) use ($zip_cb, $test_cb) { +      # create zip, pass to zip callback +      ZipStream::send($dst_path, $zip_cb, [ +        'output' => new FileWriter(), +      ]); + +      if ($test_cb) { +        # pass to test callback +        $test_cb($dst_path); +      } +    }); +  } +}; diff --git a/tests/LargeFileTest.php b/tests/LargeFileTest.php new file mode 100644 index 0000000..c271b47 --- /dev/null +++ b/tests/LargeFileTest.php @@ -0,0 +1,35 @@ +<?php +declare(strict_types = 1); + +namespace Pablotron\ZipStream\Tests; + +use \PHPUnit\Framework\TestCase; +use \Pablotron\ZipStream\ZipStream; + +final class LargeFileTest extends BaseTestCase { +  public function testCreateLargeFile() : void { +    # build 4M string +    $chunk_size = (1 << 22); +    $num_chunks = 1025; + +    # calculate expected size +    $expected_size = $chunk_size * $num_chunks; + +    $this->with_temp_zip(function(ZipStream &$zip) use ($chunk_size, $num_chunks) { +      $zip->add('hello.txt', function($e) use ($chunk_size, $num_chunks) { +        # build chunk +        $data = str_repeat('x', $chunk_size); + +        # repeatedly write chunk +        foreach (range(0, $num_chunks - 1) as $i) { +          $e->write($data); +        } +      }); +    }, function($zip_path) use ($expected_size) { +      $zip = $this->open_archive($zip_path); +      $st = $zip->statName('hello.txt'); + +      $this->assertEquals($expected_size, $st['size']); +    }); +  } +}; diff --git a/tests/PathTest.php b/tests/PathTest.php new file mode 100644 index 0000000..a71be8d --- /dev/null +++ b/tests/PathTest.php @@ -0,0 +1,83 @@ +<?php +declare(strict_types = 1); + +namespace Pablotron\ZipStream\Tests; + +use \PHPUnit\Framework\TestCase; +use \Pablotron\ZipStream\ZipStream; + +final class PathTest extends BaseTestCase { +  public function testAddEmptyPath() : void { +    $this->expectException(\Pablotron\ZipStream\PathError::class); + +    $this->with_temp_zip(function(ZipStream &$zip) { +      $zip->add_file('', 'empty test'); +    }); +  } + +  public function testAddLongPath() : void { +    $this->expectException(\Pablotron\ZipStream\PathError::class); + +    $this->with_temp_zip(function(ZipStream &$zip) { +      $long_path = str_repeat('x', 65535); +      $zip->add_file($long_path, 'long path test'); +    }); +  } + +  public function testAddPathWithLeadingSlash() : void { +    $this->expectException(\Pablotron\ZipStream\PathError::class); + +    $this->with_temp_zip(function(ZipStream &$zip) { +      $zip->add_file('/foo', 'leading slash path test'); +    }); +  } + +  public function testAddPathWithTrailingSlash() : void { +    $this->expectException(\Pablotron\ZipStream\PathError::class); + +    $this->with_temp_zip(function(ZipStream &$zip) { +      $zip->add_file('foo/', 'trailing slash path test'); +    }); +  } + +  public function testAddPathWithDoubleSlashes() : void { +    $this->expectException(\Pablotron\ZipStream\PathError::class); + +    $this->with_temp_zip(function(ZipStream &$zip) { +      $zip->add_file('foo//bar', 'double slash path test'); +    }); +  } + +  public function testAddPathWithBackslashes() : void { +    $this->expectException(\Pablotron\ZipStream\PathError::class); + +    $this->with_temp_zip(function(ZipStream &$zip) { +      $zip->add_file('foo\\bar', 'backslash path test'); +    }); +  } + +  public function testLeadingRelativePath() : void { +    $this->expectException(\Pablotron\ZipStream\PathError::class); + +    $this->with_temp_zip(function(ZipStream &$zip) { +      $zip->add_file('../bar', 'leading relative path test'); +    }); +  } + +  public function testMiddleRelativePath() : void { +    $this->expectException(\Pablotron\ZipStream\PathError::class); + +    $this->with_temp_zip(function(ZipStream &$zip) { +      $zip->add_file('foo/../bar', 'middle relative path test'); +    }); +  } + +  public function testTrailingRelativePath() : void { +    $this->expectException(\Pablotron\ZipStream\PathError::class); + +    $this->with_temp_zip(function(ZipStream &$zip) { +      $zip->add_file('foo/../bar', 'trailing relative path test'); +    }); +  } + +};  | 
