<?php
declare(strict_types=1);
namespace Tests\git2;
use git2\git;
use git2\git_error_code;
use git2\git_filemode_t;
use git2\git_index;
use git2\git_index_add_option_t;
use git2\git_index_capability_t;
use git2\git_index_conflict_iterator;
use git2\git_index_entry;
use git2\git_index_iterator;
use git2\git_index_stage_t;
use git2\git_oid;
use git2\git_strarray;
final class IndexTest extends GitTestCase
{
public function testNew(): void
{
$this->assertOK(git::index_new($index));
$this->assertInstanceOf(git_index::class, $index);
$this->assertNull(git::index_path($index));
$this->assertFalse(git::index_has_conflicts($index));
}
public function testWriteTree(): void
{
$dir = $this->mkdir('write_tree');
$this->assertOK(git::repository_init($repo, $dir, false));
$this->assertOK(git::repository_index($index, $repo));
$this->assertOK(git::index_write_tree($treeId, $index));
$this->assertInstanceOf(git_oid::class, $treeId);
$this->assertSame('4b825dc642cb6eb9a060e54bf8d69288fbee4904', git::oid_tostr_s($treeId));
}
public function testOpen(): void
{
$dir = $this->mkdir('open');
$this->assertOK(git::repository_init($repo, $dir, true));
$this->assertOK(git::index_open($index, $dir . '/index'));
$this->assertInstanceOf(git_index::class, $index);
$this->assertSame(0, git::index_entrycount($index));
$this->assertSame(git_error_code::ERROR, git::index_open($index, $dir . '/description'));
$this->assertNull(git::index_owner($index));
$this->assertSame(realpath($dir . '/index'), realpath(git::index_path($index)));
$this->assertOK(git::index_read($index, false));
$this->assertOK(git::index_read($index, true));
}
public function testAddRemovePath(): void
{
$dir = $this->mkdir('add_remove');
$this->assertOK(git::repository_init($repo, $dir, false));
$this->assertOK(git::repository_index($index, $repo));
$this->assertTrue(mkdir($dir . '/dir'));
$this->assertGreaterThan(0, file_put_contents($dir . '/dir/foo', 'foo'));
$this->assertSame(0, git::index_entrycount($index));
$this->assertOK(git::index_add_bypath($index, 'dir/foo'));
$this->assertSame(1, git::index_entrycount($index));
$this->assertOK(git::index_remove_bypath($index, 'dir/foo'));
$this->assertSame(0, git::index_entrycount($index));
$this->assertOK(git::index_add_bypath($index, 'dir/foo'));
$this->assertSame('19102815663d23f8b75a47e7a01965dcdc96468c', git::oid_tostr_s(git::index_get_bypath($index, 'dir/foo', 0)->id));
$this->assertSame('19102815663d23f8b75a47e7a01965dcdc96468c', git::oid_tostr_s(git::index_get_byindex($index, 0)->id));
$this->assertSame(1, git::index_entrycount($index));
$this->assertOK(git::index_remove_directory($index, 'dir', git_index_stage_t::NORMAL));
$this->assertSame(0, git::index_entrycount($index));
$this->assertOK(git::index_write($index));
$this->assertSame(2, git::index_version($index));
$this->assertOK(git::index_set_version($index, 3));
$this->assertSame(3, git::index_version($index));
$this->assertSame('39d890139ee5356c7ef572216cebcd27aa41f9df', git::oid_tostr_s(git::index_checksum($index)));
$this->assertOK(git::index_clear($index));
}
public function testCaps(): void
{
$caps = git_index_capability_t::IGNORE_CASE | git_index_capability_t::NO_SYMLINKS;
$this->assertOK(git::index_new($index));
$this->assertSame(0, git::index_caps($index));
$this->assertOK(git::index_set_caps($index, $caps));
$this->assertSame($caps, git::index_caps($index));
}
public function testAdd(): void
{
$entry = new git_index_entry;
$this->assertSame(0, $entry->ctime->seconds);
$this->assertSame(0, $entry->ctime->nanoseconds);
$this->assertSame(0, $entry->mtime->seconds);
$this->assertSame(0, $entry->mtime->nanoseconds);
$this->assertSame(0, $entry->dev);
$this->assertSame(git_filemode_t::UNREADABLE, $entry->mode);
$this->assertTrue(git::oid_is_zero($entry->id));
$this->assertNull($entry->path);
$entry->ctime->seconds = 1640263000;
$entry->ctime->nanoseconds = 1234;
$entry->mtime->seconds = 1640264000;
$entry->mtime->nanoseconds = 5678;
$entry->file_size = 3;
$entry->mode = git_filemode_t::BLOB;
$entry->path = 'foo';
$this->assertSame(1640263000, $entry->ctime->seconds);
$this->assertSame(1234, $entry->ctime->nanoseconds);
$this->assertSame(1640264000, $entry->mtime->seconds);
$this->assertSame(5678, $entry->mtime->nanoseconds);
$this->assertSame(3, $entry->file_size);
$this->assertSame(git_filemode_t::BLOB, $entry->mode);
$this->assertSame('foo', $entry->path);
git::index_new($index);
$this->assertOK(git::index_add($index, $entry));
$this->assertSame(0, git::index_entry_stage($entry));
$this->assertOK(git::index_find($atPos, $index, 'foo'));
$this->assertSame(0, $atPos);
$this->assertOK(git::index_find_prefix($atPos, $index, 'f'));
$this->assertSame(0, $atPos);
}
public function testAddFromBuffer(): void
{
$entry = new git_index_entry;
$entry->ctime->seconds = 1640263000;
$entry->ctime->nanoseconds = 1234;
$entry->mtime->seconds = 1640264000;
$entry->mtime->nanoseconds = 5678;
$entry->file_size = 3;
$entry->mode = git_filemode_t::BLOB;
$entry->path = 'foo';
$dir = $this->mkdir('add_from_buffer');
git::repository_init($repo, $dir, false);
git::repository_index($index, $repo);
$this->assertOK(git::index_add_from_buffer($index, $entry, 'foo'));
$this->assertFalse(git::index_entry_is_conflict($entry));
}
public function testAddAll(): void
{
$dir = $this->mkdir('add_all');
git::repository_init($repo, $dir, false);
git::repository_index($index, $repo);
touch($dir . '/foo');
touch($dir . '/bar');
$matches = [];
$this->assertOK(git::index_add_all(
$index,
git_strarray::from(['*']),
git_index_add_option_t::DEFAULT,
function(string $path, string $matched_pathspec) use(&$matches): int {
$matches[] = [$path, $matched_pathspec];
return 0;
},
));
$this->assertSame([['bar', '*'], ['foo', '*']], $matches);
}
public function testConflictAdd(): void
{
$our = new git_index_entry;
$our->ctime->seconds = 1640263000;
$our->ctime->nanoseconds = 1234;
$our->mtime->seconds = 1640264000;
$our->mtime->nanoseconds = 5678;
$our->file_size = 3;
$our->mode = git_filemode_t::BLOB;
$our->path = 'foo';
$their = new git_index_entry;
$their->ctime->seconds = 1640263000;
$their->ctime->nanoseconds = 1234;
$their->mtime->seconds = 1640264000;
$their->mtime->nanoseconds = 5678;
$their->file_size = 3;
$their->mode = git_filemode_t::BLOB;
$their->path = 'foo';
git::index_new($index);
$this->assertOK(git::index_conflict_add($index, null, $our, $their));
$this->assertOK(git::index_conflict_get($gAncestor, $gOur, $gTheir, $index, 'foo'));
$this->assertNull($gAncestor);
$this->assertNotNull($gOur);
$this->assertNotNull($gTheir);
$this->assertOK(git::index_conflict_iterator_new($iterator, $index));
$this->assertInstanceOf(git_index_conflict_iterator::class, $iterator);
$this->assertOK(git::index_conflict_next($iAncestor, $iOur, $iTheir, $iterator));
$this->assertNull($iAncestor);
$this->assertNotNull($iOur);
$this->assertNotNull($iTheir);
$this->assertSame(git_error_code::ITEROVER, git::index_conflict_next($iAncestor, $iOur, $iTheir, $iterator));
$this->assertOK(git::index_conflict_remove($index, 'foo'));
$this->assertOK(git::index_conflict_cleanup($index));
}
public function testIterator(): void
{
$dir = $this->mkdir('iterator');
git::repository_init($repo, $dir, false);
git::repository_index($index, $repo);
touch($dir . '/foo');
touch($dir . '/bar');
git::index_add_bypath($index, 'foo');
git::index_add_bypath($index, 'bar');
$this->assertOK(git::index_iterator_new($iterator, $index));
$this->assertInstanceOf(git_index_iterator::class, $iterator);
$this->assertOK(git::index_iterator_next($out, $iterator));
$this->assertInstanceOf(git_index_entry::class, $out);
$this->assertSame('bar', $out->path);
$this->assertOK(git::index_iterator_next($out, $iterator));
$this->assertInstanceOf(git_index_entry::class, $out);
$this->assertSame('foo', $out->path);
$this->assertSame(git_error_code::ITEROVER, git::index_iterator_next($out, $iterator));
}
public function testRemove(): void
{
$dir = $this->mkdir('remove');
git::repository_init($repo, $dir, false);
git::repository_index($index, $repo);
touch($dir . '/foo');
git::index_add_bypath($index, 'foo');
$this->assertSame(git_error_code::ENOTFOUND, git::index_remove($index, 'bar', 0));
$this->assertOK(git::index_remove($index, 'foo', 0));
}
public function testRemoveAll(): void
{
$dir = $this->mkdir('remove_all');
git::repository_init($repo, $dir, false);
git::repository_index($index, $repo);
touch($dir . '/foo');
touch($dir . '/bar');
git::index_add_bypath($index, 'foo');
git::index_add_bypath($index, 'bar');
$matches = [];
$this->assertOK(git::index_remove_all(
$index,
git_strarray::from(['*']),
function(string $path, string $matched_pathspec) use(&$matches): int {
$matches[] = [$path, $matched_pathspec];
return 0;
},
));
$this->assertSame([['bar', '*'], ['foo', '*']], $matches);
}
public function testUpdateAll(): void
{
$dir = $this->mkdir('update_all');
git::repository_init($repo, $dir, false);
git::repository_index($index, $repo);
touch($dir . '/foo');
touch($dir . '/bar');
git::index_add_bypath($index, 'foo');
git::index_add_bypath($index, 'bar');
file_put_contents($dir . '/foo', 'foo');
file_put_contents($dir . '/bar', 'bar');
$matches = [];
$this->assertOK(git::index_update_all(
$index,
git_strarray::from(['*']),
function(string $path, string $matched_pathspec) use(&$matches): int {
$matches[] = [$path, $matched_pathspec];
return 0;
},
));
$this->assertSame([['bar', '*'], ['foo', '*']], $matches);
}
public function testWriteTreeTo(): void
{
$dir = $this->mkdir('write_tree_to');
touch($dir . '/foo');
git::repository_init($repo, $dir, false);
git::repository_index($index, $repo);
git::index_add_bypath($index, 'foo');
git::index_write_tree_to($treeId, $index, $repo);
git::index_write_tree($treeId, $index);
git::tree_lookup($tree, $repo, $treeId);
$this->assertSame('4d5fcadc293a348e88f777dc0920f11e7d71441c', git::oid_tostr_s($treeId));
}
public function testReadTree(): void
{
$dir = $this->mkdir('read_tree');
touch($dir . '/foo');
git::repository_init($repo, $dir, false);
git::repository_index($index, $repo);
git::index_add_bypath($index, 'foo');
git::index_write_tree_to($treeId, $index, $repo);
git::index_write_tree($treeId, $index);
git::tree_lookup($tree, $repo, $treeId);
git::index_new($index2);
git::index_read_tree($index2, $tree);
$this->assertSame(1, git::index_entrycount($index2));
}
}