Pārlūkot izejas kodu

zip extra fields tests

Ne-Lexa 6 gadi atpakaļ
vecāks
revīzija
47161bdb02

+ 101 - 0
tests/Extra/Fields/AbstractUnicodeExtraFieldTest.php

@@ -0,0 +1,101 @@
+<?php
+
+/** @noinspection PhpUndefinedMethodInspection */
+
+namespace PhpZip\Tests\Extra\Fields;
+
+use PHPUnit\Framework\TestCase;
+use PhpZip\Exception\ZipException;
+use PhpZip\Model\Extra\Fields\AbstractUnicodeExtraField;
+
+/**
+ * Class AbstractUnicodeExtraFieldTest.
+ */
+abstract class AbstractUnicodeExtraFieldTest extends TestCase
+{
+    /**
+     * @return string|AbstractUnicodeExtraField
+     *
+     * @psalm-var class-string<\PhpZip\Model\Extra\Fields\AbstractUnicodeExtraField>
+     */
+    abstract protected function getUnicodeExtraFieldClassName();
+
+    /**
+     * @dataProvider provideExtraField
+     *
+     * @param int    $crc32
+     * @param string $unicodePath
+     * @param string $originalPath
+     * @param string $binaryData
+     *
+     * @throws ZipException
+     */
+    public function testExtraField($crc32, $unicodePath, $originalPath, $binaryData)
+    {
+        $crc32 = (int) $crc32; // for php 32-bit
+
+        $className = $this->getUnicodeExtraFieldClassName();
+
+        /** @var AbstractUnicodeExtraField $extraField */
+        $extraField = new $className($crc32, $unicodePath);
+        static::assertSame($extraField->getCrc32(), $crc32);
+        static::assertSame($extraField->getUnicodeValue(), $unicodePath);
+        static::assertSame(crc32($originalPath), $crc32);
+
+        static::assertSame($binaryData, $extraField->packLocalFileData());
+        static::assertSame($binaryData, $extraField->packCentralDirData());
+        static::assertEquals($className::unpackLocalFileData($binaryData), $extraField);
+        static::assertEquals($className::unpackCentralDirData($binaryData), $extraField);
+    }
+
+    /**
+     * @return array
+     */
+    abstract public function provideExtraField();
+
+    public function testSetter()
+    {
+        $className = $this->getUnicodeExtraFieldClassName();
+        $entryName = '11111';
+
+        /** @var AbstractUnicodeExtraField $extraField */
+        $extraField = new $className(crc32($entryName), '22222');
+        static::assertSame($extraField->getHeaderId(), $className::HEADER_ID);
+        static::assertSame($extraField->getCrc32(), crc32($entryName));
+        static::assertSame($extraField->getUnicodeValue(), '22222');
+
+        $crc32 = 1234567;
+        $extraField->setCrc32($crc32);
+        static::assertSame($extraField->getCrc32(), $crc32);
+        $extraField->setUnicodeValue('44444');
+        static::assertSame($extraField->getUnicodeValue(), '44444');
+    }
+
+    /**
+     * @throws ZipException
+     */
+    public function testUnicodeErrorParse()
+    {
+        $this->setExpectedException(
+            ZipException::class,
+            'Unicode path extra data must have at least 5 bytes.'
+        );
+
+        $className = $this->getUnicodeExtraFieldClassName();
+        $className::unpackLocalFileData('');
+    }
+
+    /**
+     * @throws ZipException
+     */
+    public function testUnknownVersionParse()
+    {
+        $this->setExpectedException(
+            ZipException::class,
+            'Unsupported version [2] for Unicode path extra data.'
+        );
+
+        $className = $this->getUnicodeExtraFieldClassName();
+        $className::unpackLocalFileData("\x02\x04a\xD28\xC3\xA4\\\xC3\xBC.txt");
+    }
+}

Failā izmaiņas netiks attēlotas, jo tās ir par lielu
+ 78 - 0
tests/Extra/Fields/ApkAlignmentExtraFieldTest.php


+ 101 - 0
tests/Extra/Fields/AsiExtraFieldTest.php

@@ -0,0 +1,101 @@
+<?php
+
+namespace PhpZip\Tests\Extra\Fields;
+
+use PHPUnit\Framework\TestCase;
+use PhpZip\Exception\Crc32Exception;
+use PhpZip\Exception\ZipException;
+use PhpZip\Model\Extra\Fields\AsiExtraField;
+
+/**
+ * @internal
+ *
+ * @small
+ */
+final class AsiExtraFieldTest extends TestCase
+{
+    /**
+     * @dataProvider provideExtraField
+     *
+     * @param int    $mode
+     * @param int    $uid
+     * @param int    $gid
+     * @param string $link
+     * @param string $binaryData
+     *
+     * @throws ZipException
+     */
+    public function testExtraField($mode, $uid, $gid, $link, $binaryData)
+    {
+        $asiExtraField = new AsiExtraField($mode, $uid, $gid, $link);
+        self::assertSame($asiExtraField->getHeaderId(), AsiExtraField::HEADER_ID);
+
+        self::assertSame($asiExtraField->getMode(), $mode);
+        self::assertSame($asiExtraField->getUserId(), $uid);
+        self::assertSame($asiExtraField->getGroupId(), $uid);
+        self::assertSame($asiExtraField->getLink(), $link);
+
+        self::assertSame($asiExtraField->packLocalFileData(), $binaryData);
+        self::assertSame($asiExtraField->packCentralDirData(), $binaryData);
+
+        self::assertEquals(AsiExtraField::unpackLocalFileData($binaryData), $asiExtraField);
+        self::assertEquals(AsiExtraField::unpackCentralDirData($binaryData), $asiExtraField);
+    }
+
+    /**
+     * @return array
+     */
+    public function provideExtraField()
+    {
+        return [
+            [
+                040755,
+                AsiExtraField::USER_GID_PID,
+                AsiExtraField::USER_GID_PID,
+                '',
+                "#\x06\\\xF6\xEDA\x00\x00\x00\x00\xE8\x03\xE8\x03",
+            ],
+            [
+                0100644,
+                0,
+                0,
+                'sites-enabled/example.conf',
+                "_\xB8\xC7b\xA4\x81\x1A\x00\x00\x00\x00\x00\x00\x00sites-enabled/example.conf",
+            ],
+        ];
+    }
+
+    public function testSetter()
+    {
+        $extraField = new AsiExtraField(0777);
+        $extraField->setMode(0100666);
+        self::assertSame(0100666, $extraField->getMode());
+        $extraField->setUserId(700);
+        self::assertSame(700, $extraField->getUserId());
+        $extraField->setGroupId(500);
+        self::assertSame(500, $extraField->getGroupId());
+        $extraField->setLink('link.txt');
+        self::assertSame($extraField->getLink(), 'link.txt');
+        self::assertSame(0120666, $extraField->getMode());
+
+        // dir mode
+        $extraField->setMode(0755);
+        self::assertSame(0120755, $extraField->getMode());
+        $extraField->setLink('');
+        self::assertSame($extraField->getLink(), '');
+        self::assertSame(0100755, $extraField->getMode());
+    }
+
+    /**
+     * @throws Crc32Exception
+     */
+    public function testInvalidParse()
+    {
+        $this->setExpectedException(
+            Crc32Exception::class,
+            'Asi Unix Extra Filed Data (expected CRC32 value'
+        );
+
+        AsiExtraField::unpackLocalFileData("\x01\x06\\\xF6\xEDA\x00\x00\x00\x00\xE8\x03\xE8\x03");
+    }
+}

+ 158 - 0
tests/Extra/Fields/ExtendedTimestampExtraFieldTest.php

@@ -0,0 +1,158 @@
+<?php
+
+namespace PhpZip\Tests\Extra\Fields;
+
+use PHPUnit\Framework\TestCase;
+use PhpZip\Model\Extra\Fields\ExtendedTimestampExtraField;
+
+/**
+ * Class ExtendedTimestampExtraFieldTest.
+ *
+ * @internal
+ *
+ * @small
+ */
+final class ExtendedTimestampExtraFieldTest extends TestCase
+{
+    /**
+     * @dataProvider provideExtraField
+     *
+     * @param int      $flags
+     * @param int|null $modifyTime
+     * @param int|null $accessTime
+     * @param int|null $createTime
+     * @param string   $localData
+     * @param string   $cdData
+     *
+     * @noinspection PhpTooManyParametersInspection
+     */
+    public function testExtraField(
+        $flags,
+        $modifyTime,
+        $accessTime,
+        $createTime,
+        $localData,
+        $cdData
+    ) {
+        $localExtraField = new ExtendedTimestampExtraField($flags, $modifyTime, $accessTime, $createTime);
+        self::assertSame($localExtraField->getHeaderId(), ExtendedTimestampExtraField::HEADER_ID);
+        self::assertSame($localExtraField->getFlags(), $flags);
+        self::assertSame($localExtraField->getModifyTime(), $modifyTime);
+        self::assertSame($localExtraField->getAccessTime(), $accessTime);
+        self::assertSame($localExtraField->getCreateTime(), $createTime);
+        self::assertSame($localExtraField->packLocalFileData(), $localData);
+        self::assertEquals(ExtendedTimestampExtraField::unpackLocalFileData($localData), $localExtraField);
+
+        $extTimeField = ExtendedTimestampExtraField::create($modifyTime, $accessTime, $createTime);
+        self::assertEquals($extTimeField, $localExtraField);
+
+        $accessTime = null;
+        $createTime = null;
+        $cdExtraField = new ExtendedTimestampExtraField($flags, $modifyTime, $accessTime, $createTime);
+        self::assertSame($cdExtraField->getHeaderId(), ExtendedTimestampExtraField::HEADER_ID);
+        self::assertSame($cdExtraField->getFlags(), $flags);
+        self::assertSame($cdExtraField->getModifyTime(), $modifyTime);
+        self::assertSame($cdExtraField->getAccessTime(), $accessTime);
+        self::assertSame($cdExtraField->getCreateTime(), $createTime);
+        self::assertSame($cdExtraField->packCentralDirData(), $cdData);
+        self::assertEquals(ExtendedTimestampExtraField::unpackCentralDirData($cdData), $cdExtraField);
+        self::assertSame($localExtraField->packCentralDirData(), $cdData);
+    }
+
+    /**
+     * @return array
+     */
+    public function provideExtraField()
+    {
+        return [
+            [
+                ExtendedTimestampExtraField::MODIFY_TIME_BIT |
+                ExtendedTimestampExtraField::ACCESS_TIME_BIT |
+                ExtendedTimestampExtraField::CREATE_TIME_BIT,
+                911512006,
+                911430000,
+                893709400,
+                "\x07\xC6\x91T6pQS6X\xECD5",
+                "\x07\xC6\x91T6",
+            ],
+            [
+                ExtendedTimestampExtraField::MODIFY_TIME_BIT |
+                ExtendedTimestampExtraField::ACCESS_TIME_BIT,
+                1492955702,
+                1492955638,
+                null,
+                "\x036\xB2\xFCX\xF6\xB1\xFCX",
+                "\x036\xB2\xFCX",
+            ],
+            [
+                ExtendedTimestampExtraField::MODIFY_TIME_BIT,
+                1470494391,
+                null,
+                null,
+                "\x01\xB7\xF6\xA5W",
+                "\x01\xB7\xF6\xA5W",
+            ],
+        ];
+    }
+
+    /**
+     * @throws \Exception
+     */
+    public function testSetter()
+    {
+        $mtime = time();
+        $atime = null;
+        $ctime = null;
+
+        $field = ExtendedTimestampExtraField::create($mtime, $atime, $ctime);
+        self::assertSame($field->getFlags(), ExtendedTimestampExtraField::MODIFY_TIME_BIT);
+        self::assertSame($field->getModifyTime(), $mtime);
+        self::assertEquals($field->getModifyDateTime(), new \DateTimeImmutable('@' . $mtime));
+        self::assertSame($field->getAccessTime(), $atime);
+        self::assertSame($field->getCreateTime(), $ctime);
+
+        $atime = strtotime('-1 min');
+        $field->setAccessTime($atime);
+        self::assertSame(
+            $field->getFlags(),
+            ExtendedTimestampExtraField::MODIFY_TIME_BIT |
+            ExtendedTimestampExtraField::ACCESS_TIME_BIT
+        );
+        self::assertSame($field->getModifyTime(), $mtime);
+        self::assertSame($field->getAccessTime(), $atime);
+        self::assertEquals($field->getAccessDateTime(), new \DateTimeImmutable('@' . $atime));
+        self::assertSame($field->getCreateTime(), $ctime);
+
+        $ctime = strtotime('-1 hour');
+        $field->setCreateTime($ctime);
+        self::assertSame(
+            $field->getFlags(),
+            ExtendedTimestampExtraField::MODIFY_TIME_BIT |
+            ExtendedTimestampExtraField::ACCESS_TIME_BIT |
+            ExtendedTimestampExtraField::CREATE_TIME_BIT
+        );
+        self::assertSame($field->getModifyTime(), $mtime);
+        self::assertSame($field->getAccessTime(), $atime);
+        self::assertSame($field->getCreateTime(), $ctime);
+        self::assertEquals($field->getCreateDateTime(), new \DateTimeImmutable('@' . $ctime));
+
+        $field->setCreateTime(null);
+        self::assertNull($field->getCreateTime());
+        self::assertNull($field->getCreateDateTime());
+        self::assertSame(
+            $field->getFlags(),
+            ExtendedTimestampExtraField::MODIFY_TIME_BIT |
+            ExtendedTimestampExtraField::ACCESS_TIME_BIT
+        );
+
+        $field->setAccessTime(null);
+        self::assertNull($field->getAccessTime());
+        self::assertNull($field->getAccessDateTime());
+        self::assertSame($field->getFlags(), ExtendedTimestampExtraField::MODIFY_TIME_BIT);
+
+        $field->setModifyTime(null);
+        self::assertNull($field->getModifyTime());
+        self::assertNull($field->getModifyDateTime());
+        self::assertSame($field->getFlags(), 0);
+    }
+}

+ 55 - 0
tests/Extra/Fields/JarMarkerExtraFieldTest.php

@@ -0,0 +1,55 @@
+<?php
+
+namespace PhpZip\Tests\Extra\Fields;
+
+use PHPUnit\Framework\TestCase;
+use PhpZip\Exception\ZipException;
+use PhpZip\Model\Extra\Fields\JarMarkerExtraField;
+
+/**
+ * Class JarMarkerExtraFieldTest.
+ *
+ * @internal
+ *
+ * @small
+ */
+final class JarMarkerExtraFieldTest extends TestCase
+{
+    /**
+     * @throws ZipException
+     */
+    public function testExtraField()
+    {
+        $jarField = new JarMarkerExtraField();
+        self::assertSame('', $jarField->packLocalFileData());
+        self::assertSame('', $jarField->packCentralDirData());
+        self::assertEquals(JarMarkerExtraField::unpackLocalFileData(''), $jarField);
+        self::assertEquals(JarMarkerExtraField::unpackCentralDirData(''), $jarField);
+    }
+
+    /**
+     * @throws ZipException
+     */
+    public function testInvalidUnpackLocalData()
+    {
+        $this->setExpectedException(
+            ZipException::class,
+            "JarMarker doesn't expect any data"
+        );
+
+        JarMarkerExtraField::unpackLocalFileData("\x02\x00\00");
+    }
+
+    /**
+     * @throws ZipException
+     */
+    public function testInvalidUnpackCdData()
+    {
+        $this->setExpectedException(
+            ZipException::class,
+            "JarMarker doesn't expect any data"
+        );
+
+        JarMarkerExtraField::unpackCentralDirData("\x02\x00\00");
+    }
+}

+ 97 - 0
tests/Extra/Fields/NewUnixExtraFieldTest.php

@@ -0,0 +1,97 @@
+<?php
+
+namespace PhpZip\Tests\Extra\Fields;
+
+use PHPUnit\Framework\TestCase;
+use PhpZip\Exception\ZipException;
+use PhpZip\Model\Extra\Fields\NewUnixExtraField;
+
+/**
+ * Class NewUnixExtraFieldTest.
+ *
+ * @internal
+ *
+ * @small
+ */
+final class NewUnixExtraFieldTest extends TestCase
+{
+    /**
+     * @dataProvider provideExtraField
+     *
+     * @param int    $version
+     * @param int    $uid
+     * @param int    $gid
+     * @param string $binaryData
+     *
+     * @throws ZipException
+     */
+    public function testExtraField($version, $uid, $gid, $binaryData)
+    {
+        $extraField = new NewUnixExtraField($version, $uid, $gid);
+        self::assertSame($extraField->getHeaderId(), NewUnixExtraField::HEADER_ID);
+        self::assertSame($extraField->getVersion(), $version);
+        self::assertSame($extraField->getGid(), $gid);
+        self::assertSame($extraField->getUid(), $uid);
+
+        self::assertEquals(NewUnixExtraField::unpackLocalFileData($binaryData), $extraField);
+        self::assertEquals(NewUnixExtraField::unpackCentralDirData($binaryData), $extraField);
+
+        self::assertSame($extraField->packLocalFileData(), $binaryData);
+        self::assertSame($extraField->packCentralDirData(), $binaryData);
+    }
+
+    /**
+     * @return array
+     */
+    public function provideExtraField()
+    {
+        return [
+            [
+                1,
+                NewUnixExtraField::USER_GID_PID,
+                NewUnixExtraField::USER_GID_PID,
+                "\x01\x04\xE8\x03\x00\x00\x04\xE8\x03\x00\x00",
+            ],
+            [
+                1,
+                501,
+                20,
+                "\x01\x04\xF5\x01\x00\x00\x04\x14\x00\x00\x00",
+            ],
+            [
+                1,
+                500,
+                495,
+                "\x01\x04\xF4\x01\x00\x00\x04\xEF\x01\x00\x00",
+            ],
+            [
+                1,
+                11252,
+                10545,
+                "\x01\x04\xF4+\x00\x00\x041)\x00\x00",
+            ],
+            [
+                1,
+                1721,
+                1721,
+                "\x01\x04\xB9\x06\x00\x00\x04\xB9\x06\x00\x00",
+            ],
+        ];
+    }
+
+    public function testSetter()
+    {
+        $extraField = new NewUnixExtraField(1, 1000, 1000);
+        self::assertSame(1, $extraField->getVersion());
+        self::assertSame(1000, $extraField->getUid());
+        self::assertSame(1000, $extraField->getGid());
+
+        $extraField->setUid(0);
+        self::assertSame(0, $extraField->getUid());
+        self::assertSame(1000, $extraField->getGid());
+
+        $extraField->setGid(0);
+        self::assertSame(0, $extraField->getUid());
+        self::assertSame(0, $extraField->getGid());
+    }
+}

+ 245 - 0
tests/Extra/Fields/NtfsExtraFieldTest.php

@@ -0,0 +1,245 @@
+<?php
+
+namespace PhpZip\Tests\Extra\Fields;
+
+use PHPUnit\Framework\TestCase;
+use PhpZip\Model\Extra\Fields\NtfsExtraField;
+
+/**
+ * Class NtfsExtraFieldTest.
+ *
+ * @internal
+ *
+ * @small
+ */
+final class NtfsExtraFieldTest extends TestCase
+{
+    protected function setUp()
+    {
+        if (\PHP_INT_SIZE === 4) {
+            self::markTestSkipped('only 64 bit test');
+        }
+    }
+
+    /**
+     * @dataProvider provideExtraField
+     *
+     * @param int    $modifyNtfsTime
+     * @param int    $accessNtfsTime
+     * @param int    $createNtfsTime
+     * @param float  $modifyTimestamp
+     * @param float  $accessTimestamp
+     * @param float  $createTimestamp
+     * @param string $binaryData
+     *
+     * @throws \Exception
+     *
+     * @noinspection PhpTooManyParametersInspection
+     */
+    public function testExtraField(
+        $modifyNtfsTime,
+        $accessNtfsTime,
+        $createNtfsTime,
+        $modifyTimestamp,
+        $accessTimestamp,
+        $createTimestamp,
+        $binaryData
+    ) {
+        $extraField = new NtfsExtraField($modifyNtfsTime, $accessNtfsTime, $createNtfsTime);
+        self::assertSame($extraField->getHeaderId(), NtfsExtraField::HEADER_ID);
+
+        self::assertEquals($extraField->getModifyDateTime()->getTimestamp(), (int) $modifyTimestamp);
+        self::assertEquals($extraField->getAccessDateTime()->getTimestamp(), (int) $accessTimestamp);
+        self::assertEquals($extraField->getCreateDateTime()->getTimestamp(), (int) $createTimestamp);
+
+        self::assertEquals(NtfsExtraField::unpackLocalFileData($binaryData), $extraField);
+        self::assertEquals(NtfsExtraField::unpackCentralDirData($binaryData), $extraField);
+
+        self::assertSame($extraField->packLocalFileData(), $binaryData);
+        self::assertSame($extraField->packCentralDirData(), $binaryData);
+
+        $extraFieldFromDateTime = NtfsExtraField::create(
+            $extraField->getModifyDateTime(),
+            $extraField->getAccessDateTime(),
+            $extraField->getCreateDateTime()
+        );
+
+        self::assertEqualsIntegerWithDelta($extraFieldFromDateTime->getModifyNtfsTime(), $extraField->getModifyNtfsTime(), 100);
+        self::assertEqualsIntegerWithDelta($extraFieldFromDateTime->getAccessNtfsTime(), $extraField->getAccessNtfsTime(), 100);
+        self::assertEqualsIntegerWithDelta($extraFieldFromDateTime->getCreateNtfsTime(), $extraField->getCreateNtfsTime(), 100);
+    }
+
+    /**
+     * @return array
+     */
+    public function provideExtraField()
+    {
+        return [
+            [
+                129853553114795379,
+                129853553114795379,
+                129853552641022547,
+                1340881711.4795379,
+                1340881711.4795379,
+                1340881664.1022547,
+                "\x00\x00\x00\x00\x01\x00\x18\x00s\xCD:Z\x1EU\xCD\x01s\xCD:Z\x1EU\xCD\x01S\x9A\xFD=\x1EU\xCD\x01",
+            ],
+            [
+                131301570250000000,
+                131865940850000000,
+                131840940680000000,
+                1485683425.000000,
+                1542120485.000000,
+                1539620468.000000,
+                "\x00\x00\x00\x00\x01\x00\x18\x00\x80\xC63\x1D\x15z\xD2\x01\x80@V\xE2_{\xD4\x01\x00\xB2\x15\x14\xA3d\xD4\x01",
+            ],
+            [
+                132181086710000000,
+                132181086710000000,
+                132181086710000000,
+                1573635071.000000,
+                1573635071.000000,
+                1573635071.000000,
+                "\x00\x00\x00\x00\x01\x00\x18\x00\x80\xE9_\x7F\xFF\x99\xD5\x01\x80\xE9_\x7F\xFF\x99\xD5\x01\x80\xE9_\x7F\xFF\x99\xD5\x01",
+            ],
+        ];
+    }
+
+    /**
+     * @param int    $expected
+     * @param int    $actual
+     * @param int    $delta
+     * @param string $message
+     */
+    private static function assertEqualsIntegerWithDelta(
+        $expected,
+        $actual,
+        $delta,
+        $message = ''
+    ) {
+        self::assertSame(
+            self::roundInt($expected, $delta),
+            self::roundInt($actual, $delta),
+            $message
+        );
+    }
+
+    /**
+     * @param int $number
+     * @param int $delta
+     *
+     * @return int
+     */
+    private static function roundInt($number, $delta)
+    {
+        return (int) (floor($number / $delta) * $delta);
+    }
+
+    /**
+     * @dataProvider provideExtraField
+     *
+     * @param int   $mtimeNtfs
+     * @param int   $atimeNtfs
+     * @param int   $ctimeNtfs
+     * @param float $mtimeTimestamp
+     * @param float $atimeTimestamp
+     * @param float $ctimeTimestamp
+     *
+     * @noinspection PhpTooManyParametersInspection
+     * @noinspection PhpUnitDeprecationsInspection
+     */
+    public function testConverter(
+        $mtimeNtfs,
+        $atimeNtfs,
+        $ctimeNtfs,
+        $mtimeTimestamp,
+        $atimeTimestamp,
+        $ctimeTimestamp
+    ) {
+        self::assertEquals(NtfsExtraField::ntfsTimeToTimestamp($mtimeNtfs), $mtimeTimestamp, '', 0.00001);
+        self::assertEquals(NtfsExtraField::ntfsTimeToTimestamp($atimeNtfs), $atimeTimestamp, '', 0.00001);
+        self::assertEquals(NtfsExtraField::ntfsTimeToTimestamp($ctimeNtfs), $ctimeTimestamp, '', 0.00001);
+
+        self::assertEqualsIntegerWithDelta(NtfsExtraField::timestampToNtfsTime($mtimeTimestamp), $mtimeNtfs, 10);
+        self::assertEqualsIntegerWithDelta(NtfsExtraField::timestampToNtfsTime($atimeTimestamp), $atimeNtfs, 10);
+        self::assertEqualsIntegerWithDelta(NtfsExtraField::timestampToNtfsTime($ctimeTimestamp), $ctimeNtfs, 10);
+    }
+
+    /**
+     * @throws \Exception
+     */
+    public function testSetter()
+    {
+        $timeZone = new \DateTimeZone('UTC');
+        $initDateTime = new \DateTimeImmutable('-1 min', $timeZone);
+        $mtimeDateTime = new \DateTimeImmutable('-1 hour', $timeZone);
+        $atimeDateTime = new \DateTimeImmutable('-1 day', $timeZone);
+        $ctimeDateTime = new \DateTimeImmutable('-1 year', $timeZone);
+
+        $extraField = NtfsExtraField::create($initDateTime, $initDateTime, $initDateTime);
+        self::assertEquals(
+            $extraField->getModifyDateTime()->getTimestamp(),
+            $initDateTime->getTimestamp()
+        );
+        self::assertEquals(
+            $extraField->getAccessDateTime()->getTimestamp(),
+            $initDateTime->getTimestamp()
+        );
+        self::assertEquals(
+            $extraField->getCreateDateTime()->getTimestamp(),
+            $initDateTime->getTimestamp()
+        );
+
+        $extraField->setModifyDateTime($mtimeDateTime);
+        self::assertEquals(
+            $extraField->getModifyDateTime()->getTimestamp(),
+            $mtimeDateTime->getTimestamp()
+        );
+        self::assertEquals(
+            $extraField->getAccessDateTime()->getTimestamp(),
+            $initDateTime->getTimestamp()
+        );
+        self::assertEquals(
+            $extraField->getCreateDateTime()->getTimestamp(),
+            $initDateTime->getTimestamp()
+        );
+
+        $extraField->setAccessDateTime($atimeDateTime);
+        self::assertEquals(
+            $extraField->getModifyDateTime()->getTimestamp(),
+            $mtimeDateTime->getTimestamp()
+        );
+        self::assertEquals(
+            $extraField->getAccessDateTime()->getTimestamp(),
+            $atimeDateTime->getTimestamp()
+        );
+        self::assertEquals(
+            $extraField->getCreateDateTime()->getTimestamp(),
+            $initDateTime->getTimestamp()
+        );
+
+        $extraField->setCreateDateTime($ctimeDateTime);
+        self::assertEquals(
+            $extraField->getModifyDateTime()->getTimestamp(),
+            $mtimeDateTime->getTimestamp()
+        );
+        self::assertEquals(
+            $extraField->getAccessDateTime()->getTimestamp(),
+            $atimeDateTime->getTimestamp()
+        );
+        self::assertEquals(
+            $extraField->getCreateDateTime()->getTimestamp(),
+            $ctimeDateTime->getTimestamp()
+        );
+
+        $newModifyNtfsTime = $extraField->getCreateNtfsTime();
+        $newAccessNtfsTime = $extraField->getModifyNtfsTime();
+        $newCreateNtfsTime = $extraField->getAccessNtfsTime();
+        $extraField->setModifyNtfsTime($newModifyNtfsTime);
+        $extraField->setAccessNtfsTime($newAccessNtfsTime);
+        $extraField->setCreateNtfsTime($newCreateNtfsTime);
+        self::assertSame($extraField->getModifyNtfsTime(), $newModifyNtfsTime);
+        self::assertSame($extraField->getAccessNtfsTime(), $newAccessNtfsTime);
+        self::assertSame($extraField->getCreateNtfsTime(), $newCreateNtfsTime);
+    }
+}

+ 156 - 0
tests/Extra/Fields/OldUnixExtraFieldTest.php

@@ -0,0 +1,156 @@
+<?php
+
+namespace PhpZip\Tests\Extra\Fields;
+
+use PHPUnit\Framework\TestCase;
+use PhpZip\Model\Extra\Fields\OldUnixExtraField;
+
+/**
+ * Class OldUnixExtraFieldTest.
+ *
+ * @internal
+ *
+ * @small
+ */
+final class OldUnixExtraFieldTest extends TestCase
+{
+    /**
+     * @dataProvider provideExtraField
+     *
+     * @param int|null $accessTime
+     * @param int|null $modifyTime
+     * @param int|null $uid
+     * @param int|null $gid
+     * @param string   $localBinaryData
+     * @param string   $cdBinaryData
+     *
+     * @noinspection PhpTooManyParametersInspection
+     *
+     * @throws \Exception
+     */
+    public function testExtraField(
+        $accessTime,
+        $modifyTime,
+        $uid,
+        $gid,
+        $localBinaryData,
+        $cdBinaryData
+    ) {
+        $extraField = new OldUnixExtraField($accessTime, $modifyTime, $uid, $gid);
+        self::assertSame($extraField->getHeaderId(), OldUnixExtraField::HEADER_ID);
+
+        self::assertSame($extraField->getAccessTime(), $accessTime);
+        self::assertSame($extraField->getModifyTime(), $modifyTime);
+        self::assertSame($extraField->getUid(), $uid);
+        self::assertSame($extraField->getGid(), $gid);
+
+        if ($extraField->getModifyTime() !== null) {
+            self::assertEquals(
+                new \DateTimeImmutable('@' . $extraField->getModifyTime()),
+                $extraField->getModifyDateTime()
+            );
+        }
+
+        if ($extraField->getAccessTime() !== null) {
+            self::assertEquals(
+                new \DateTimeImmutable('@' . $extraField->getAccessTime()),
+                $extraField->getAccessDateTime()
+            );
+        }
+
+        self::assertEquals(OldUnixExtraField::unpackLocalFileData($localBinaryData), $extraField);
+        self::assertSame($extraField->packLocalFileData(), $localBinaryData);
+
+        $uid = null;
+        $gid = null;
+        $extraField = new OldUnixExtraField($accessTime, $modifyTime, $uid, $gid);
+        self::assertSame($extraField->getHeaderId(), OldUnixExtraField::HEADER_ID);
+
+        self::assertSame($extraField->getAccessTime(), $accessTime);
+        self::assertSame($extraField->getModifyTime(), $modifyTime);
+        self::assertNull($extraField->getUid());
+        self::assertNull($extraField->getGid());
+
+        if ($extraField->getModifyTime() !== null) {
+            self::assertEquals(
+                new \DateTimeImmutable('@' . $extraField->getModifyTime()),
+                $extraField->getModifyDateTime()
+            );
+        }
+
+        if ($extraField->getAccessTime() !== null) {
+            self::assertEquals(
+                new \DateTimeImmutable('@' . $extraField->getAccessTime()),
+                $extraField->getAccessDateTime()
+            );
+        }
+
+        self::assertEquals(OldUnixExtraField::unpackCentralDirData($cdBinaryData), $extraField);
+        self::assertSame($extraField->packCentralDirData(), $cdBinaryData);
+    }
+
+    /**
+     * @return array
+     */
+    public function provideExtraField()
+    {
+        return [
+            [
+                1213373265,
+                1213365834,
+                502,
+                502,
+                "Q\x9BRHJ~RH\xF6\x01\xF6\x01",
+                "Q\x9BRHJ~RH",
+            ],
+            [
+                935520420,
+                935520401,
+                501,
+                100,
+                "\xA4\xE8\xC27\x91\xE8\xC27\xF5\x01d\x00",
+                "\xA4\xE8\xC27\x91\xE8\xC27",
+            ],
+            [
+                1402666135,
+                1402666135,
+                501,
+                20,
+                "\x97\xFC\x9AS\x97\xFC\x9AS\xF5\x01\x14\x00",
+                "\x97\xFC\x9AS\x97\xFC\x9AS",
+            ],
+            [
+                null,
+                null,
+                null,
+                null,
+                '',
+                '',
+            ],
+        ];
+    }
+
+    public function testSetter()
+    {
+        $extraField = new OldUnixExtraField(null, null, null, null);
+
+        self::assertNull($extraField->getAccessTime());
+        self::assertNull($extraField->getAccessDateTime());
+        self::assertNull($extraField->getModifyTime());
+        self::assertNull($extraField->getModifyDateTime());
+        self::assertNull($extraField->getUid());
+        self::assertNull($extraField->getGid());
+
+        $extraField->setModifyTime(1402666135);
+        self::assertSame($extraField->getModifyTime(), 1402666135);
+
+        $extraField->setAccessTime(1213365834);
+        self::assertSame($extraField->getAccessTime(), 1213365834);
+
+        $extraField->setUid(500);
+        self::assertSame($extraField->getUid(), 500);
+
+        $extraField->setGid(100);
+        self::assertSame($extraField->getGid(), 100);
+    }
+}

+ 42 - 0
tests/Extra/Fields/UnicodeCommentExtraFieldTest.php

@@ -0,0 +1,42 @@
+<?php
+
+namespace PhpZip\Tests\Extra\Fields;
+
+use PhpZip\Model\Extra\Fields\UnicodeCommentExtraField;
+
+/**
+ * @internal
+ *
+ * @small
+ */
+final class UnicodeCommentExtraFieldTest extends AbstractUnicodeExtraFieldTest
+{
+    /**
+     * {@inheritdoc}
+     */
+    protected function getUnicodeExtraFieldClassName()
+    {
+        return UnicodeCommentExtraField::class;
+    }
+
+    /**
+     * @return array
+     */
+    public function provideExtraField()
+    {
+        return [
+            [
+                4293813303,
+                'комментарий',
+                "\xAA\xAE\xAC\xAC\xA5\xAD\xE2\xA0\xE0\xA8\xA9",
+                "\x017d\xEE\xFF\xD0\xBA\xD0\xBE\xD0\xBC\xD0\xBC\xD0\xB5\xD0\xBD\xD1\x82\xD0\xB0\xD1\x80\xD0\xB8\xD0\xB9",
+            ],
+            [
+                897024324,
+                'תגובה',
+                "\x9A\x82\x85\x81\x84",
+                "\x01D\x81w5\xD7\xAA\xD7\x92\xD7\x95\xD7\x91\xD7\x94",
+            ],
+        ];
+    }
+}

+ 56 - 0
tests/Extra/Fields/UnicodePathExtraFieldTest.php

@@ -0,0 +1,56 @@
+<?php
+
+namespace PhpZip\Tests\Extra\Fields;
+
+use PhpZip\Model\Extra\Fields\UnicodePathExtraField;
+
+/**
+ * Class UnicodePathExtraFieldTest.
+ *
+ * @internal
+ *
+ * @small
+ */
+final class UnicodePathExtraFieldTest extends AbstractUnicodeExtraFieldTest
+{
+    /**
+     * {@inheritdoc}
+     */
+    protected function getUnicodeExtraFieldClassName()
+    {
+        return UnicodePathExtraField::class;
+    }
+
+    /**
+     * @return array
+     */
+    public function provideExtraField()
+    {
+        return [
+            [
+                2728523760,
+                'txt\מבחן עברי.txt',
+                "txt/\x8E\x81\x87\x8F \x92\x81\x98\x89.txt",
+                "\x01\xF0\xF7\xA1\xA2txt\\\xD7\x9E\xD7\x91\xD7\x97\xD7\x9F \xD7\xA2\xD7\x91\xD7\xA8\xD7\x99.txt",
+            ],
+            [
+                953311492,
+                'ä\ü.txt',
+                "\x84/\x81.txt",
+                "\x01\x04a\xD28\xC3\xA4\\\xC3\xBC.txt",
+            ],
+            [
+                2965532848,
+                'Ölfässer.txt',
+                "\x99lf\x84sser.txt",
+                "\x01\xB0p\xC2\xB0\xC3\x96lf\xC3\xA4sser.txt",
+            ],
+            [
+                3434671236,
+                'Как заработать в интернете.mp4',
+                "\x8A\xA0\xAA \xA7\xA0\xE0\xA0\xA1\xAE\xE2\xA0\xE2\xEC \xA2 \xA8\xAD\xE2\xA5\xE0\xAD\xA5\xE2\xA5.mp4",
+                "\x01\x84\xEC\xB8\xCC\xD0\x9A\xD0\xB0\xD0\xBA \xD0\xB7\xD0\xB0\xD1\x80\xD0\xB0\xD0\xB1\xD0\xBE\xD1\x82\xD0\xB0\xD1\x82\xD1\x8C \xD0\xB2 \xD0\xB8\xD0\xBD\xD1\x82\xD0\xB5\xD1\x80\xD0\xBD\xD0\xB5\xD1\x82\xD0\xB5.mp4",
+            ],
+        ];
+    }
+}

+ 57 - 0
tests/Extra/Fields/UnrecognizedExtraFieldTest.php

@@ -0,0 +1,57 @@
+<?php
+
+namespace PhpZip\Tests\Extra\Fields;
+
+use PHPUnit\Framework\TestCase;
+use PhpZip\Exception\RuntimeException;
+use PhpZip\Model\Extra\Fields\UnrecognizedExtraField;
+
+/**
+ * Class UnrecognizedExtraFieldTest.
+ *
+ * @internal
+ *
+ * @small
+ */
+final class UnrecognizedExtraFieldTest extends TestCase
+{
+    public function testExtraField()
+    {
+        $headerId = 0xF00D;
+        $binaryData = "\x01\x02\x03\x04\x05";
+
+        $unrecognizedExtraField = new UnrecognizedExtraField($headerId, $binaryData);
+        self::assertSame($unrecognizedExtraField->getHeaderId(), $headerId);
+        self::assertSame($unrecognizedExtraField->getData(), $binaryData);
+
+        $newHeaderId = 0xDADA;
+        $newBinaryData = "\x05\x00";
+        $unrecognizedExtraField->setHeaderId($newHeaderId);
+        self::assertSame($unrecognizedExtraField->getHeaderId(), $newHeaderId);
+        $unrecognizedExtraField->setData($newBinaryData);
+        self::assertSame($unrecognizedExtraField->getData(), $newBinaryData);
+
+        self::assertSame($unrecognizedExtraField->packLocalFileData(), $newBinaryData);
+        self::assertSame($unrecognizedExtraField->packCentralDirData(), $newBinaryData);
+    }
+
+    public function testUnpackLocalData()
+    {
+        $this->setExpectedException(
+            RuntimeException::class,
+            'Unsupport parse'
+        );
+
+        UnrecognizedExtraField::unpackLocalFileData("\x01\x02");
+    }
+
+    public function testUnpackCentralDirData()
+    {
+        $this->setExpectedException(
+            RuntimeException::class,
+            'Unsupport parse'
+        );
+
+        UnrecognizedExtraField::unpackCentralDirData("\x01\x02");
+    }
+}

+ 240 - 0
tests/Extra/Fields/WinZipAesExtraFieldTest.php

@@ -0,0 +1,240 @@
+<?php
+
+namespace PhpZip\Tests\Extra\Fields;
+
+use PHPUnit\Framework\TestCase;
+use PhpZip\Constants\ZipCompressionMethod;
+use PhpZip\Constants\ZipEncryptionMethod;
+use PhpZip\Exception\InvalidArgumentException;
+use PhpZip\Exception\ZipException;
+use PhpZip\Exception\ZipUnsupportMethodException;
+use PhpZip\Model\Extra\Fields\WinZipAesExtraField;
+
+/**
+ * @internal
+ *
+ * @small
+ */
+final class WinZipAesExtraFieldTest extends TestCase
+{
+    /**
+     * @dataProvider provideExtraField
+     *
+     * @param int    $vendorVersion
+     * @param int    $keyStrength
+     * @param int    $compressionMethod
+     * @param int    $saltSize
+     * @param string $binaryData
+     *
+     * @throws ZipException
+     * @throws ZipUnsupportMethodException
+     */
+    public function testExtraField(
+        $vendorVersion,
+        $keyStrength,
+        $compressionMethod,
+        $saltSize,
+        $binaryData
+    ) {
+        $extraField = new WinZipAesExtraField($vendorVersion, $keyStrength, $compressionMethod);
+        self::assertSame($extraField->getHeaderId(), WinZipAesExtraField::HEADER_ID);
+        self::assertSame($extraField->getVendorVersion(), $vendorVersion);
+        self::assertSame($extraField->getKeyStrength(), $keyStrength);
+        self::assertSame($extraField->getCompressionMethod(), $compressionMethod);
+        self::assertSame($extraField->getVendorId(), WinZipAesExtraField::VENDOR_ID);
+        self::assertSame($extraField->getSaltSize(), $saltSize);
+
+        self::assertSame($binaryData, $extraField->packLocalFileData());
+        self::assertSame($binaryData, $extraField->packCentralDirData());
+        self::assertEquals(WinZipAesExtraField::unpackLocalFileData($binaryData), $extraField);
+        self::assertEquals(WinZipAesExtraField::unpackCentralDirData($binaryData), $extraField);
+    }
+
+    /**
+     * @return array
+     */
+    public function provideExtraField()
+    {
+        return [
+            [
+                WinZipAesExtraField::VERSION_AE1,
+                WinZipAesExtraField::KEY_STRENGTH_128BIT,
+                ZipCompressionMethod::STORED,
+                8,
+                "\x01\x00AE\x01\x00\x00",
+            ],
+            [
+                WinZipAesExtraField::VERSION_AE1,
+                WinZipAesExtraField::KEY_STRENGTH_192BIT,
+                ZipCompressionMethod::DEFLATED,
+                12,
+                "\x01\x00AE\x02\x08\x00",
+            ],
+            [
+                WinZipAesExtraField::VERSION_AE2,
+                WinZipAesExtraField::KEY_STRENGTH_128BIT,
+                ZipCompressionMethod::DEFLATED,
+                8,
+                "\x02\x00AE\x01\x08\x00",
+            ],
+            [
+                WinZipAesExtraField::VERSION_AE2,
+                WinZipAesExtraField::KEY_STRENGTH_256BIT,
+                ZipCompressionMethod::STORED,
+                16,
+                "\x02\x00AE\x03\x00\x00",
+            ],
+            [
+                WinZipAesExtraField::VERSION_AE2,
+                WinZipAesExtraField::KEY_STRENGTH_192BIT,
+                ZipCompressionMethod::DEFLATED,
+                12,
+                "\x02\x00AE\x02\x08\x00",
+            ],
+            [
+                WinZipAesExtraField::VERSION_AE2,
+                WinZipAesExtraField::KEY_STRENGTH_256BIT,
+                ZipCompressionMethod::STORED,
+                16,
+                "\x02\x00AE\x03\x00\x00",
+            ],
+        ];
+    }
+
+    /**
+     * @throws ZipUnsupportMethodException
+     */
+    public function testSetter()
+    {
+        $extraField = new WinZipAesExtraField(
+            WinZipAesExtraField::VERSION_AE1,
+            WinZipAesExtraField::KEY_STRENGTH_256BIT,
+            ZipCompressionMethod::DEFLATED
+        );
+
+        self::assertSame($extraField->getVendorVersion(), WinZipAesExtraField::VERSION_AE1);
+        self::assertSame($extraField->getKeyStrength(), WinZipAesExtraField::KEY_STRENGTH_256BIT);
+        self::assertSame($extraField->getCompressionMethod(), ZipCompressionMethod::DEFLATED);
+        self::assertSame($extraField->getSaltSize(), 16);
+        self::assertSame($extraField->getEncryptionStrength(), 256);
+        self::assertSame($extraField->getEncryptionMethod(), ZipEncryptionMethod::WINZIP_AES_256);
+
+        $extraField->setVendorVersion(WinZipAesExtraField::VERSION_AE2);
+        self::assertSame($extraField->getVendorVersion(), WinZipAesExtraField::VERSION_AE2);
+        self::assertSame($extraField->getKeyStrength(), WinZipAesExtraField::KEY_STRENGTH_256BIT);
+        self::assertSame($extraField->getCompressionMethod(), ZipCompressionMethod::DEFLATED);
+        self::assertSame($extraField->getSaltSize(), 16);
+        self::assertSame($extraField->getEncryptionStrength(), 256);
+        self::assertSame($extraField->getEncryptionMethod(), ZipEncryptionMethod::WINZIP_AES_256);
+
+        $extraField->setKeyStrength(WinZipAesExtraField::KEY_STRENGTH_128BIT);
+        self::assertSame($extraField->getVendorVersion(), WinZipAesExtraField::VERSION_AE2);
+        self::assertSame($extraField->getKeyStrength(), WinZipAesExtraField::KEY_STRENGTH_128BIT);
+        self::assertSame($extraField->getCompressionMethod(), ZipCompressionMethod::DEFLATED);
+        self::assertSame($extraField->getSaltSize(), 8);
+        self::assertSame($extraField->getEncryptionStrength(), 128);
+        self::assertSame($extraField->getEncryptionMethod(), ZipEncryptionMethod::WINZIP_AES_128);
+
+        $extraField->setKeyStrength(WinZipAesExtraField::KEY_STRENGTH_192BIT);
+        self::assertSame($extraField->getVendorVersion(), WinZipAesExtraField::VERSION_AE2);
+        self::assertSame($extraField->getKeyStrength(), WinZipAesExtraField::KEY_STRENGTH_192BIT);
+        self::assertSame($extraField->getCompressionMethod(), ZipCompressionMethod::DEFLATED);
+        self::assertSame($extraField->getSaltSize(), 12);
+        self::assertSame($extraField->getEncryptionStrength(), 192);
+        self::assertSame($extraField->getEncryptionMethod(), ZipEncryptionMethod::WINZIP_AES_192);
+
+        $extraField->setCompressionMethod(ZipCompressionMethod::STORED);
+        self::assertSame($extraField->getVendorVersion(), WinZipAesExtraField::VERSION_AE2);
+        self::assertSame($extraField->getKeyStrength(), WinZipAesExtraField::KEY_STRENGTH_192BIT);
+        self::assertSame($extraField->getCompressionMethod(), ZipCompressionMethod::STORED);
+        self::assertSame($extraField->getSaltSize(), 12);
+        self::assertSame($extraField->getEncryptionStrength(), 192);
+        self::assertSame($extraField->getEncryptionMethod(), ZipEncryptionMethod::WINZIP_AES_192);
+    }
+
+    /**
+     * @throws ZipUnsupportMethodException
+     */
+    public function testConstructUnsupportVendorVersion()
+    {
+        $this->setExpectedException(InvalidArgumentException::class, 'Unsupport WinZip AES vendor version: 3');
+
+        new WinZipAesExtraField(
+            3,
+            WinZipAesExtraField::KEY_STRENGTH_192BIT,
+            ZipCompressionMethod::STORED
+        );
+    }
+
+    /**
+     * @throws ZipUnsupportMethodException
+     */
+    public function testSetterUnsupportVendorVersion()
+    {
+        $this->setExpectedException(InvalidArgumentException::class, 'Unsupport WinZip AES vendor version: 3');
+
+        $extraField = new WinZipAesExtraField(
+            WinZipAesExtraField::VERSION_AE1,
+            WinZipAesExtraField::KEY_STRENGTH_192BIT,
+            ZipCompressionMethod::STORED
+        );
+        $extraField->setVendorVersion(3);
+    }
+
+    /**
+     * @throws ZipUnsupportMethodException
+     */
+    public function testConstructUnsupportCompressionMethod()
+    {
+        $this->setExpectedException(ZipUnsupportMethodException::class, 'Compression method 3 (Reduced compression factor 2) is not supported.');
+
+        new WinZipAesExtraField(
+            WinZipAesExtraField::VERSION_AE1,
+            WinZipAesExtraField::KEY_STRENGTH_192BIT,
+            3
+        );
+    }
+
+    /**
+     * @throws ZipUnsupportMethodException
+     */
+    public function testSetterUnsupportCompressionMethod()
+    {
+        $this->setExpectedException(ZipUnsupportMethodException::class, 'Compression method 3 (Reduced compression factor 2) is not supported.');
+
+        $extraField = new WinZipAesExtraField(
+            WinZipAesExtraField::VERSION_AE1,
+            WinZipAesExtraField::KEY_STRENGTH_192BIT,
+            ZipCompressionMethod::STORED
+        );
+        $extraField->setCompressionMethod(3);
+    }
+
+    /**
+     * @throws ZipUnsupportMethodException
+     */
+    public function testConstructUnsupportKeyStrength()
+    {
+        $this->setExpectedException(InvalidArgumentException::class, 'Key strength 16 not support value. Allow values: 1, 2, 3');
+
+        new WinZipAesExtraField(
+            WinZipAesExtraField::VERSION_AE1,
+            0x10,
+            ZipCompressionMethod::STORED
+        );
+    }
+
+    /**
+     * @throws ZipUnsupportMethodException
+     */
+    public function testSetterUnsupportKeyStrength()
+    {
+        $this->setExpectedException(InvalidArgumentException::class, 'Key strength 16 not support value. Allow values: 1, 2, 3');
+
+        new WinZipAesExtraField(
+            WinZipAesExtraField::VERSION_AE1,
+            0x10,
+            ZipCompressionMethod::STORED
+        );
+    }
+}

+ 132 - 0
tests/Extra/Fields/Zip64ExtraFieldTest.php

@@ -0,0 +1,132 @@
+<?php
+
+namespace PhpZip\Tests\Extra\Fields;
+
+use PHPUnit\Framework\TestCase;
+use PhpZip\Constants\ZipConstants;
+use PhpZip\Exception\ZipException;
+use PhpZip\Model\Extra\Fields\Zip64ExtraField;
+use PhpZip\Model\ZipEntry;
+
+/**
+ * @internal
+ *
+ * @small
+ */
+final class Zip64ExtraFieldTest extends TestCase
+{
+    protected function setUp()
+    {
+        if (\PHP_INT_SIZE === 4) {
+            self::markTestSkipped('only 64 bit test');
+        }
+    }
+
+    /**
+     * @dataProvider provideExtraField
+     *
+     * @param int|null    $uncompressedSize
+     * @param int|null    $compressedSize
+     * @param int|null    $localHeaderOffset
+     * @param int|null    $diskStart
+     * @param string|null $localBinaryData
+     * @param string|null $cdBinaryData
+     *
+     * @throws ZipException
+     *
+     * @noinspection PhpTooManyParametersInspection
+     */
+    public function testExtraField(
+        $uncompressedSize,
+        $compressedSize,
+        $localHeaderOffset,
+        $diskStart,
+        $localBinaryData,
+        $cdBinaryData
+    ) {
+        $extraField = new Zip64ExtraField(
+            $uncompressedSize,
+            $compressedSize,
+            $localHeaderOffset,
+            $diskStart
+        );
+        self::assertSame($extraField->getHeaderId(), Zip64ExtraField::HEADER_ID);
+        self::assertSame($extraField->getUncompressedSize(), $uncompressedSize);
+        self::assertSame($extraField->getCompressedSize(), $compressedSize);
+        self::assertSame($extraField->getLocalHeaderOffset(), $localHeaderOffset);
+        self::assertSame($extraField->getDiskStart(), $diskStart);
+
+        $zipEntry = new ZipEntry('entry');
+        $zipEntry->setUncompressedSize($uncompressedSize !== null ? ZipConstants::ZIP64_MAGIC : 0xfffff);
+        $zipEntry->setCompressedSize($compressedSize !== null ? ZipConstants::ZIP64_MAGIC : 0xffff);
+        $zipEntry->setLocalHeaderOffset($localHeaderOffset !== null ? ZipConstants::ZIP64_MAGIC : 0xfff);
+
+        if ($localBinaryData !== null) {
+            self::assertSame($localBinaryData, $extraField->packLocalFileData());
+            self::assertEquals(Zip64ExtraField::unpackLocalFileData($localBinaryData, $zipEntry), $extraField);
+        }
+
+        if ($cdBinaryData !== null) {
+            self::assertSame($cdBinaryData, $extraField->packCentralDirData());
+            self::assertEquals(Zip64ExtraField::unpackCentralDirData($cdBinaryData, $zipEntry), $extraField);
+        }
+    }
+
+    /**
+     * @return array
+     */
+    public function provideExtraField()
+    {
+        return [
+            [
+                0,
+                2,
+                null,
+                null,
+                "\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00\x00\x00\x00\x00\x00",
+                null,
+            ],
+            [
+                5368709120,
+                5369580144,
+                null,
+                null,
+                null,
+                "\x00\x00\x00@\x01\x00\x00\x00pJ\x0D@\x01\x00\x00\x00",
+            ],
+            [
+                null,
+                null,
+                4945378839,
+                null,
+                null,
+                "\x17~\xC4&\x01\x00\x00\x00",
+            ],
+        ];
+    }
+
+    public function testSetter()
+    {
+        $extraField = new Zip64ExtraField();
+        self::assertNull($extraField->getUncompressedSize());
+        self::assertNull($extraField->getCompressedSize());
+        self::assertNull($extraField->getLocalHeaderOffset());
+        self::assertNull($extraField->getDiskStart());
+
+        $uncompressedSize = 12222;
+        $extraField->setUncompressedSize($uncompressedSize);
+        self::assertSame($extraField->getUncompressedSize(), $uncompressedSize);
+
+        $compressedSize = 12222;
+        $extraField->setCompressedSize($uncompressedSize);
+        self::assertSame($extraField->getCompressedSize(), $compressedSize);
+
+        $localHeaderOffset = 12222;
+        $extraField->setLocalHeaderOffset($localHeaderOffset);
+        self::assertSame($extraField->getLocalHeaderOffset(), $localHeaderOffset);
+
+        $diskStart = 2;
+        $extraField->setDiskStart($diskStart);
+        self::assertSame($extraField->getDiskStart(), $diskStart);
+    }
+}

Daži faili netika attēloti, jo izmaiņu fails ir pārāk liels