summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPaul Duncan <pabs@pablotron.org>2018-09-02 18:58:32 -0400
committerPaul Duncan <pabs@pablotron.org>2018-09-03 09:54:47 -0400
commite4850cba6fd67a6d4d9d8c969281e57447c17fd9 (patch)
tree29fb04954bdabde80a2208d6fa88c575cc7ed802
parentd70e1b519d27e5b0090412c566bee79d57f7838e (diff)
downloadzipstream-php-e4850cba6fd67a6d4d9d8c969281e57447c17fd9.tar.bz2
zipstream-php-e4850cba6fd67a6d4d9d8c969281e57447c17fd9.zip
add tests/ and composer test script
-rw-r--r--composer.json6
-rw-r--r--tests/AddFileTest.php67
-rw-r--r--tests/ArchiveTest.php89
-rw-r--r--tests/BaseTestCase.php49
-rw-r--r--tests/LargeFileTest.php35
-rw-r--r--tests/PathTest.php83
6 files changed, 329 insertions, 0 deletions
diff --git a/composer.json b/composer.json
index 67e2d06..3d078a8 100644
--- a/composer.json
+++ b/composer.json
@@ -29,5 +29,11 @@
"psr-4": {
"Pablotron\\ZipStream\\Tests\\": "tests/"
}
+ },
+
+ "scripts": {
+ "test": [
+ "phpunit --bootstrap vendor/autoload.php tests"
+ ]
}
}
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');
+ });
+ }
+
+};