<?php
declare(strict_types=1);
namespace Tests\git2;
use git2\git;
use git2\git_error_code;
use git2\git_filemode_t;
use git2\git_object;
use git2\git_object_t;
use git2\git_tree;
use git2\git_tree_entry;
use git2\git_tree_update;
use git2\git_tree_update_t;
use git2\git_treewalk_mode;
final class TreeTest extends GitTestCase
{
public function testLookup(): void
{
$dir = $this->mkdir('lookup');
$this->assertOK(git::repository_init($repo, $dir, false));
$this->assertOK(git::repository_index($index, $repo));
$this->assertOK(git::index_write_tree($treeId, $index));
$this->assertOK(git::tree_lookup($tree, $repo, $treeId));
$this->assertInstanceOf(git_tree::class, $tree);
$this->assertOK(git::tree_lookup_prefix($treePrefix, $repo, $treeId, 7));
$this->assertInstanceOf(git_tree::class, $treePrefix);
$this->assertSame('4b825dc642cb6eb9a060e54bf8d69288fbee4904', git::oid_tostr_s(git::tree_id($tree)));
$this->assertSame($repo, git::tree_owner($tree));
}
public function testCreateUpdated(): void
{
$dir = $this->mkdir('create_updated');
touch($dir . '/foo');
touch($dir . '/bar');
touch($dir . '/fuz');
git::repository_init($repo, $dir, false);
git::repository_index($index, $repo);
git::index_add_bypath($index, 'foo');
git::index_add_bypath($index, 'bar');
git::index_add_bypath($index, 'fuz');
git::index_write_tree($treeId, $index);
git::tree_lookup($tree, $repo, $treeId);
$update1 = new git_tree_update;
$update1->action = git_tree_update_t::REMOVE;
$update1->filemode = git_filemode_t::BLOB;
$update1->path = 'foo';
$update2 = new git_tree_update;
$update2->action = git_tree_update_t::REMOVE;
$update2->filemode = git_filemode_t::BLOB;
$update2->path = 'bar';
$this->assertOK(git::tree_create_updated(
$oid,
$repo,
$tree,
[$update1, $update2],
));
$this->assertOK(git::tree_lookup($result, $repo, $oid));
$this->assertSame(1, git::tree_entrycount($result));
$entry = git::tree_entry_byindex($result, 0);
$this->assertSame('fuz', git::tree_entry_name($entry));
}
public function testDup(): void
{
$dir = $this->mkdir('dup');
touch($dir . '/foo');
git::repository_init($repo, $dir, false);
git::repository_index($index, $repo);
git::index_add_bypath($index, 'foo');
git::index_write_tree($treeId, $index);
git::tree_lookup($tree, $repo, $treeId);
$this->assertOK(git::tree_dup($dup, $tree));
$this->assertSame(1, git::tree_entrycount($dup));
}
public function testEntryBy(): void
{
$dir = $this->mkdir('entry_by');
touch($dir . '/foo');
git::repository_init($repo, $dir, false);
git::repository_index($index, $repo);
git::index_add_bypath($index, 'foo');
git::index_write_tree($treeId, $index);
git::tree_lookup($tree, $repo, $treeId);
$this->assertNull(git::tree_entry_byindex($tree, 1));
$this->assertSame(
'e69de29bb2d1d6434b8b29ae775ad8c2e48c5391',
git::oid_tostr_s(git::tree_entry_id(git::tree_entry_byindex($tree, 0)))
);
$this->assertNull(git::tree_entry_byname($tree, 'bar'));
$this->assertSame(
'e69de29bb2d1d6434b8b29ae775ad8c2e48c5391',
git::oid_tostr_s(git::tree_entry_id(git::tree_entry_byname($tree, 'foo')))
);
git::oid_fromstr($oid1, '0000000000000000000000000000000000000000');
git::oid_fromstr($oid2, 'e69de29bb2d1d6434b8b29ae775ad8c2e48c5391');
$this->assertNull(git::tree_entry_byid($tree, $oid1));
$this->assertSame(
'e69de29bb2d1d6434b8b29ae775ad8c2e48c5391',
git::oid_tostr_s(git::tree_entry_id(git::tree_entry_byid($tree, $oid2)))
);
$this->assertSame(git_error_code::ENOTFOUND, git::tree_entry_bypath($_, $tree, 'bar'));
$this->assertOK(git::tree_entry_bypath($entry, $tree, 'foo'));
$this->assertSame(
'e69de29bb2d1d6434b8b29ae775ad8c2e48c5391',
git::oid_tostr_s(git::tree_entry_id($entry))
);
git::tree_entry_bypath($byPath, $tree, 'foo');
$byIndex = git::tree_entry_byindex($tree, 0);
$byName = git::tree_entry_byname($tree, 'foo');
$this->assertSame($byIndex, $byName);
$this->assertNotSame($byPath, $byIndex);
}
public function testEntryCmp(): void
{
$dir = $this->mkdir('entry_cmp');
touch($dir . '/foo');
touch($dir . '/bar');
git::repository_init($repo, $dir, false);
git::repository_index($index, $repo);
git::index_add_bypath($index, 'foo');
git::index_add_bypath($index, 'bar');
git::index_write_tree($treeId, $index);
git::tree_lookup($tree, $repo, $treeId);
$foo = git::tree_entry_byname($tree, 'foo');
$bar = git::tree_entry_byname($tree, 'bar');
$this->assertSame(0, git::tree_entry_cmp($foo, $foo));
$this->assertSame(0, git::tree_entry_cmp($bar, $bar));
$this->assertGreaterThan(0, git::tree_entry_cmp($foo, $bar));
$this->assertLessThan(0, git::tree_entry_cmp($bar, $foo));
}
public function testEntryOwnerRetain(): void
{
$entry = (function(): git_tree_entry {
$dir = $this->mkdir('entry_owner_retain');
touch($dir . '/foo');
git::repository_init($repo, $dir, false);
git::repository_index($index, $repo);
git::index_add_bypath($index, 'foo');
git::index_write_tree($treeId, $index);
git::tree_lookup($tree, $repo, $treeId);
return git::tree_entry_byindex($tree, 0);
})();
$this->assertSame('foo', git::tree_entry_name($entry));
}
public function testEntryDup(): void
{
$entry = (function(): git_tree_entry {
$dir = $this->mkdir('entry_dup');
touch($dir . '/foo');
git::repository_init($repo, $dir, false);
git::repository_index($index, $repo);
git::index_add_bypath($index, 'foo');
git::index_write_tree($treeId, $index);
git::tree_lookup($tree, $repo, $treeId);
$src = git::tree_entry_byindex($tree, 0);
$this->assertOK(git::tree_entry_dup($dest, $src));
return $dest;
})();
$this->assertSame('foo', git::tree_entry_name($entry));
}
public function testEntry(): void
{
$dir = $this->mkdir('entry');
touch($dir . '/foo');
git::repository_init($repo, $dir, false);
git::repository_index($index, $repo);
git::index_add_bypath($index, 'foo');
git::index_write_tree($treeId, $index);
git::tree_lookup($tree, $repo, $treeId);
$entry = git::tree_entry_byindex($tree, 0);
$this->assertSame(git_filemode_t::BLOB, git::tree_entry_filemode($entry));
$this->assertSame(git_filemode_t::BLOB, git::tree_entry_filemode_raw($entry));
$this->assertSame(git_object_t::BLOB, git::tree_entry_type($entry));
}
public function testEntryToObject(): void
{
$dir = $this->mkdir('entry');
touch($dir . '/foo');
git::repository_init($repo, $dir, false);
git::repository_index($index, $repo);
git::index_add_bypath($index, 'foo');
git::index_write_tree($treeId, $index);
git::tree_lookup($tree, $repo, $treeId);
$entry = git::tree_entry_byindex($tree, 0);
$this->assertOK(git::tree_entry_to_object($object, $repo, $entry));
$this->assertInstanceOf(git_object::class, $object);
$this->assertSame('e69de29bb2d1d6434b8b29ae775ad8c2e48c5391', git::oid_tostr_s(git::object_id($object)));
}
public function testWalk(): void
{
$dir = $this->mkdir('walk');
touch($dir . '/foo');
git::repository_init($repo, $dir, false);
git::repository_index($index, $repo);
git::index_add_bypath($index, 'foo');
git::index_write_tree($treeId, $index);
git::tree_lookup($tree, $repo, $treeId);
$this->assertOK(git::tree_walk($tree, git_treewalk_mode::PRE, function(string $root, git_tree_entry $entry): int {
$this->assertSame('', $root);
$this->assertSame('foo', git::tree_entry_name($entry));
return 0;
}));
}
}