From 5dda6b1011472e558e3fd9c744c2fd537528b115 Mon Sep 17 00:00:00 2001
From: Paul Duncan <pabs@pablotron.org>
Date: Mon, 3 Sep 2018 06:50:31 -0400
Subject: add CommentError, Methods::check(), and several additional tests

---
 tests/AddFileTest.php | 127 +++++++++++++++++++++++++++++++++++++++++++++-----
 tests/ArchiveTest.php |  63 +++++++++++++++++++++----
 2 files changed, 169 insertions(+), 21 deletions(-)

(limited to 'tests')

diff --git a/tests/AddFileTest.php b/tests/AddFileTest.php
index 3ea65e0..d4b5d5a 100644
--- a/tests/AddFileTest.php
+++ b/tests/AddFileTest.php
@@ -7,11 +7,11 @@ use \PHPUnit\Framework\TestCase;
 use \Pablotron\ZipStream\ZipStream;
 
 final class AddFileTest extends BaseTestCase {
-  public function testCreateFile() : void {
+  public function testAddFile() : void {
     $this->with_temp_zip(function(ZipStream &$zip) {
       $zip->add_file('hello.txt', 'hello!');
-    }, function(string $path) {
-      $zip = $this->open_archive($path);
+    }, function(string $zip_path) {
+      $zip = $this->open_archive($zip_path);
 
       $this->assertEquals(
         'hello!',
@@ -20,14 +20,57 @@ final class AddFileTest extends BaseTestCase {
     });
   }
 
-  public function testCreateFileWithComment() : void {
+  public function testAddFileFromPath() : void {
+    $this->with_temp_zip(function(ZipStream &$zip) {
+      $zip->add_file_from_path('test.php', __FILE__);
+    }, function(string $zip_path) {
+      $zip = $this->open_archive($zip_path);
+
+      $this->assertEquals(
+        sha1(file_get_contents(__FILE__)),
+        sha1($zip->getFromName('test.php'))
+      );
+    });
+  }
+
+  public function testAddStream() : void {
+    $this->with_temp_zip(function(ZipStream &$zip) {
+      $fh = fopen(__FILE__, 'rb');
+      $zip->add_stream('test.php', $fh);
+      fclose($fh);
+    }, function(string $zip_path) {
+      $zip = $this->open_archive($zip_path);
+
+      $this->assertEquals(
+        sha1(file_get_contents(__FILE__)),
+        sha1($zip->getFromName('test.php'))
+      );
+    });
+  }
+
+  public function testAdd() : void {
+    $this->with_temp_zip(function(ZipStream &$zip) {
+      $zip->add('test.php', function(&$e) {
+        $e->write(file_get_contents(__FILE__));
+      });
+    }, function(string $zip_path) {
+      $zip = $this->open_archive($zip_path);
+
+      $this->assertEquals(
+        sha1(file_get_contents(__FILE__)),
+        sha1($zip->getFromName('test.php'))
+      );
+    });
+  }
+
+  public function testAddFileWithComment() : 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);
+    }, function(string $zip_path) use ($comment) {
+      $zip = $this->open_archive($zip_path);
 
       $this->assertEquals(
         $comment,
@@ -36,7 +79,7 @@ final class AddFileTest extends BaseTestCase {
     });
   }
 
-  public function testCreateFileWithUnknownMethod() : void {
+  public function testAddFileWithUnknownMethod() : void {
     $this->expectException(\Pablotron\ZipStream\UnknownMethodError::class);
 
     $this->with_temp_zip(function(ZipStream &$zip) {
@@ -46,22 +89,84 @@ final class AddFileTest extends BaseTestCase {
     });
   }
 
-  public function testCreateFileTimestamp() : void {
+  public function testAddFileTimestamp() : void {
     # get timezone offset
     # $ofs = \DateTimeZone::getOffset(\DateTime::getTimezone());
-    $ofs = 4 * 3600; # hard-coded to EDT for now
+    $ofs = 4 * 3600; # FIXME: hard-coded to EDT for now
 
     # get time from 2 hours ago (round to even number of seconds)
     $time = ((time() - (2 * 3600)) >> 1) << 1;
 
+    # get test time
+    $expected_time = $time + $ofs;
+
     $this->with_temp_zip(function(ZipStream &$zip) use ($time) {
       $zip->add_file('hello.txt', 'hello!', [
         'time' => $time,
       ]);
-    }, function($zip_path) use ($time, $ofs) {
+    }, function($zip_path) use ($expected_time) {
       $zip = $this->open_archive($zip_path);
       $st = $zip->statName('hello.txt');
-      $this->assertEquals($time, $st['mtime'] - $ofs);
+
+      $this->assertEquals($expected_time, $st['mtime']);
+    });
+  }
+
+  public function testAddFileCRC() : void {
+    $data = 'hello!';
+
+    # calculate crc32b of file data
+    $hash = hash('crc32b', $data, true);
+
+    # pack expected crc as integer
+    $expected_crc = (
+      (ord($hash[0]) << 24) |
+      (ord($hash[1]) << 16) |
+      (ord($hash[2]) << 8) |
+      (ord($hash[3]))
+    );
+
+    $this->with_temp_zip(function(ZipStream &$zip) use ($data) {
+      $zip->add_file('hello.txt', $data);
+    }, function($zip_path) use ($expected_crc) {
+      $zip = $this->open_archive($zip_path);
+      $st = $zip->statName('hello.txt');
+
+      $this->assertEquals($expected_crc, $st['crc']);
+    });
+  }
+
+  public function testAddFileWithMethodStore() : void {
+    $data = file_get_contents(__FILE__);
+
+    $this->with_temp_zip(function(ZipStream &$zip) use ($data) {
+      $zip->add_file('test.php', $data, [
+        'method' => \Pablotron\ZipStream\Methods::STORE,
+      ]);
+    }, function($zip_path) use ($data) {
+      $zip = $this->open_archive($zip_path);
+
+      $this->assertEquals(
+        sha1($data),
+        sha1($zip->getFromName('test.php'))
+      );
+    });
+  }
+
+  public function testAddFileWithMethodDeflate() : void {
+    $data = file_get_contents(__FILE__);
+
+    $this->with_temp_zip(function(ZipStream &$zip) use ($data) {
+      $zip->add_file('test.php', $data, [
+        'method' => \Pablotron\ZipStream\Methods::DEFLATE,
+      ]);
+    }, function($zip_path) use ($data) {
+      $zip = $this->open_archive($zip_path);
+
+      $this->assertEquals(
+        sha1($data),
+        sha1($zip->getFromName('test.php'))
+      );
     });
   }
 };
diff --git a/tests/ArchiveTest.php b/tests/ArchiveTest.php
index cbac0f1..8345ee4 100644
--- a/tests/ArchiveTest.php
+++ b/tests/ArchiveTest.php
@@ -19,15 +19,15 @@ final class ArchiveTest extends BaseTestCase {
   }
 
   public function testFileWriter() {
-    $this->with_temp_file(function(string $dst_path) {
-      ZipStream::send($dst_path, function(ZipStream &$zip) {
+    $this->with_temp_file(function(string $zip_path) {
+      ZipStream::send($zip_path, function(ZipStream &$zip) {
         $zip->add_file('hello.txt', 'hello!');
       }, [
         'output' => new FileWriter(),
       ]);
 
       # open archive
-      $zip = $this->open_archive($dst_path);
+      $zip = $this->open_archive($zip_path);
 
       # read hello.txt, check text
       $this->assertEquals(
@@ -38,13 +38,13 @@ final class ArchiveTest extends BaseTestCase {
   }
 
   public function testStreamWriter() {
-    $this->with_temp_file(function(string $dst_path) {
-      $fh = fopen($dst_path, 'wb');
+    $this->with_temp_file(function(string $zip_path) {
+      $fh = fopen($zip_path, 'wb');
       if ($fh === false) {
         throw new Exception("fopen() failed");
       }
 
-      ZipStream::send($dst_path, function(ZipStream &$zip) {
+      ZipStream::send($zip_path, function(ZipStream &$zip) {
         $zip->add_file('hello.txt', 'hello!');
       }, [
         'output' => new StreamWriter($fh),
@@ -54,7 +54,7 @@ final class ArchiveTest extends BaseTestCase {
       fclose($fh);
 
       # open archive
-      $zip = $this->open_archive($dst_path);
+      $zip = $this->open_archive($zip_path);
 
       # read hello.txt, check text
       $this->assertEquals(
@@ -65,11 +65,11 @@ final class ArchiveTest extends BaseTestCase {
   }
 
   public function testArchiveComment() : void {
-    $this->with_temp_file(function($dst_path) {
+    $this->with_temp_file(function($zip_path) {
       $comment = 'test archive comment';
 
       # write archive
-      ZipStream::send($dst_path, function(ZipStream &$zip) {
+      ZipStream::send($zip_path, function(ZipStream &$zip) {
         $zip->add_file('hello.txt', 'hello!');
       }, [
         'comment' => $comment,
@@ -77,7 +77,7 @@ final class ArchiveTest extends BaseTestCase {
       ]);
 
       # open archive
-      $zip = $this->open_archive($dst_path);
+      $zip = $this->open_archive($zip_path);
 
       # read hello.txt, check text
       $this->assertEquals(
@@ -86,4 +86,47 @@ final class ArchiveTest extends BaseTestCase {
       );
     });
   }
+
+  public function testLongArchiveComment() : void {
+    $this->expectException(\Pablotron\ZipStream\CommentError::class);
+
+    $this->with_temp_file(function($zip_path) {
+      $comment = str_repeat('x', 0xFFFF);
+
+      # write archive
+      ZipStream::send($zip_path, function(ZipStream &$zip) {
+        $zip->add_file('hello.txt', 'hello!');
+      }, [
+        'comment' => $comment,
+        'output'  => new FileWriter(),
+      ]);
+    });
+  }
+
+  public function testInvalidOutput() : void {
+    $this->expectException(\Pablotron\ZipStream\Error::class);
+
+    $this->with_temp_file(function($zip_path) {
+      # write archive with invalid writer
+      ZipStream::send($zip_path, function(ZipStream &$zip) {
+        $zip->add_file('hello.txt', 'hello!');
+      }, [
+        'output' => 'bad writer',
+      ]);
+    });
+  }
+
+  public function testInvalidMethod() : void {
+    $this->expectException(\Pablotron\ZipStream\UnknownMethodError::class);
+
+    $this->with_temp_file(function($zip_path) {
+      # write archive with invalid compression method
+      ZipStream::send($zip_path, function(ZipStream &$zip) {
+        $zip->add_file('hello.txt', 'hello!');
+      }, [
+        'method'  => 100,
+        'output'  => new FileWriter(),
+      ]);
+    });
+  }
 };
-- 
cgit v1.2.3