Git-Native

 view release on metacpan or  search on metacpan

t/74-index.t  view on Meta::CPAN

        like "$err", qr/\QGit::Native::Index->$method\E requires a non-empty \Q$arg\E/,
          'the message names the method and the argument';
        like "$err", qr/got \Q$shown\E/, 'and what it was given';
        like "$err", qr{at \S*74-index\.t line \d+},
          'croak blames the caller, not Index.pm';
      };
    }
  }
};

subtest 'is_tracked_under rejects a path that is only slashes' => sub {
  # '/' survives the definedness check and is emptied by the trailing-slash
  # strip. Left alone it would ask has_prefix('/'), i.e. "is anything tracked",
  # which is not the question the caller asked.
  for my $path ( '/', '//', '///' ) {
    my $err = dies { $index->is_tracked_under($path) };
    ok !ref $err, "'$path' croaks rather than throwing a Git::Native::Error";
    like "$err", qr/\QGit::Native::Index->is_tracked_under\E requires a non-empty path/,
      "'$path' is told what is_tracked_under wanted";
    like "$err", qr/got '\Q$path\E'/, "'$path' is echoed back as given, before the strip";
  }

  # The guard is about emptiness, not about slashes: the raw string methods
  # have no path semantics and take '/' as an ordinary prefix that matches
  # nothing here.
  is $index->find_prefix('/'), undef, "find_prefix('/') is a plain miss, not a croak";
  is $index->has_path('/'),    0,     "has_path('/') is a plain miss too";
};

# ---------------------------------------------------------------------------
# Bare repositories.
# ---------------------------------------------------------------------------
subtest 'a bare repository has an index, and it is empty' => sub {
  # Measured, and worth pinning because it is not what the neighbouring
  # working-tree API does: status refuses a bare repo outright, the index
  # accessor does not. A caller that wraps ->index in an is_bare check would
  # be guarding against a failure that never happens.
  my $bare_index;
  ok lives { $bare_index = $bare->index }, '->index on a bare repo does not throw';
  isa_ok $bare_index, ['Git::Native::Index'], 'it returns an Index';
  is $bare_index->entrycount, 0, 'with no entries - a bare repo stages nothing';
  is $bare_index->is_tracked_under('tasks'), 0,
    'so nothing is tracked under any path, even one the bare repo has commits for';
  is $bare_index->find('README.md'), undef, 'and find misses rather than throwing';

  # The control group: same repository, the working-tree API, which does
  # refuse. Without this the subtest above could be passing on a repo that
  # merely is not bare.
  is $bare->is_bare, 1, 'the repository really is bare';
  my $err = dies { $bare->status };
  isa_ok $err, ['Git::Native::Error'], 'status on the same repo throws';
  is $err->is_bare_repo, 1, 'with GIT_EBAREREPO - the refusal ->index does not make';
};

# ---------------------------------------------------------------------------
# Memory ownership.
# ---------------------------------------------------------------------------
subtest 'an Index outlives the Repository variable it came from' => sub {
  # Repository->index passes _owner => $self, so the Index holds a strong ref
  # to the Repository and git_repository_free cannot run while the Index is
  # alive. Drop the only other reference and keep reading: if _owner were ever
  # dropped, the git_index* below would be reading through a freed repository.
  my $orphan;
  {
    my $r = Git::Native->open("$repo_dir");
    $orphan = $r->index;
  }   # $r out of scope - git_repository_free must NOT have run

  is $orphan->entrycount, scalar @TRACKED,
    'the Index still reads after its Repository variable is gone';
  is $orphan->is_tracked_under('tasks'), 1, 'and still answers the path question';
  is $orphan->find('tasks/1.md'), $index->find('tasks/1.md'),
    'with the same positions as an Index whose Repository is still held';
};

done_testing;



( run in 4.380 seconds using v1.01-cache-2.11-cpan-14f38c9f855 )