refactor!: use Finalizer to automatically free allocated memory for objects (#48)

BREAKING CHANGE: signature change for remote and repository callbacks during repository clone operation.
This commit is contained in:
Aleksey Kulikov 2022-04-28 11:04:48 +03:00 committed by GitHub
parent 94c40f9a94
commit a3213a88a2
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
103 changed files with 2278 additions and 2595 deletions

View file

@ -46,25 +46,22 @@ void main() {
});
test('returns correct type of reference', () {
final head = repo.head;
expect(head.type, ReferenceType.direct);
head.free();
final ref = Reference.lookup(repo: repo, name: 'HEAD');
expect(ref.type, ReferenceType.symbolic);
ref.free();
expect(repo.head.type, ReferenceType.direct);
expect(
Reference.lookup(repo: repo, name: 'HEAD').type,
ReferenceType.symbolic,
);
});
test('returns SHA hex of direct reference', () {
final head = repo.head;
expect(head.target.sha, lastCommit);
head.free();
expect(repo.head.target.sha, lastCommit);
});
test('returns SHA hex of symbolic reference', () {
final ref = Reference.lookup(repo: repo, name: 'HEAD');
expect(ref.target.sha, lastCommit);
ref.free();
expect(
Reference.lookup(repo: repo, name: 'HEAD').target.sha,
lastCommit,
);
});
test('throws when trying to resolve invalid reference', () {
@ -75,9 +72,7 @@ void main() {
});
test('returns the full name', () {
final head = repo.head;
expect(head.name, 'refs/heads/master');
head.free();
expect(repo.head.name, 'refs/heads/master');
});
test('returns the short name', () {
@ -87,25 +82,22 @@ void main() {
target: repo[lastCommit],
);
final head = repo.head;
expect(head.shorthand, 'master');
expect(repo.head.shorthand, 'master');
expect(ref.shorthand, 'origin/upstream');
head.free();
ref.free();
});
test('checks if reference is a local branch', () {
final ref = Reference.lookup(repo: repo, name: 'refs/heads/feature');
expect(ref.isBranch, true);
ref.free();
expect(
Reference.lookup(repo: repo, name: 'refs/heads/feature').isBranch,
true,
);
});
test('checks if reference is a note', () {
final ref = Reference.lookup(repo: repo, name: 'refs/heads/master');
expect(ref.isNote, false);
ref.free();
expect(
Reference.lookup(repo: repo, name: 'refs/heads/master').isNote,
false,
);
});
test('checks if reference is a remote branch', () {
@ -114,23 +106,25 @@ void main() {
name: 'refs/remotes/origin/master',
);
expect(ref.isRemote, true);
ref.free();
});
test('checks if reference is a tag', () {
final ref = Reference.lookup(repo: repo, name: 'refs/tags/v0.1');
expect(ref.isTag, true);
ref.free();
expect(
Reference.lookup(repo: repo, name: 'refs/tags/v0.1').isTag,
true,
);
});
test('checks if reflog exists for the reference', () {
var ref = Reference.lookup(repo: repo, name: 'refs/heads/master');
expect(ref.hasLog, true);
expect(
Reference.lookup(repo: repo, name: 'refs/heads/master').hasLog,
true,
);
ref = Reference.lookup(repo: repo, name: 'refs/tags/v0.1');
expect(ref.hasLog, false);
ref.free();
expect(
Reference.lookup(repo: repo, name: 'refs/tags/v0.1').hasLog,
false,
);
});
test('ensures updates to the reference will append to its log', () {
@ -141,12 +135,8 @@ void main() {
name: 'refs/tags/tag',
target: repo[lastCommit],
);
final reflog = ref.log;
expect(reflog.length, 1);
reflog.free();
ref.free();
expect(ref.log.length, 1);
});
test('throws when trying to ensure there is a reflog and error occurs', () {
@ -167,24 +157,17 @@ void main() {
expect(repo.references.length, 6);
expect(duplicate.equals(ref), true);
duplicate.free();
ref.free();
});
group('create direct', () {
test('creates with oid as target', () {
final ref = Reference.lookup(repo: repo, name: 'refs/heads/master');
final refFromOid = Reference.create(
Reference.create(
repo: repo,
name: 'refs/tags/from.oid',
target: ref.target,
target: repo.head.target,
);
expect(repo.references, contains('refs/tags/from.oid'));
refFromOid.free();
ref.free();
});
test('creates with log message', () {
@ -196,15 +179,11 @@ void main() {
logMessage: 'log message',
);
final reflog = ref.log;
final reflogEntry = reflog[0];
final reflogEntry = ref.log[0];
expect(reflogEntry.message, 'log message');
expect(reflogEntry.committer.name, 'name');
expect(reflogEntry.committer.email, 'email');
reflog.free();
ref.free();
});
test('throws if target is not valid', () {
@ -239,7 +218,7 @@ void main() {
});
test('creates with force flag if name already exists', () {
final ref = Reference.create(
Reference.create(
repo: repo,
name: 'refs/tags/test',
target: repo[lastCommit],
@ -253,13 +232,10 @@ void main() {
);
expect(forceRef.target.sha, lastCommit);
ref.free();
forceRef.free();
});
test('throws if name already exists', () {
final ref = Reference.create(
Reference.create(
repo: repo,
name: 'refs/tags/test',
target: repo[lastCommit],
@ -273,8 +249,6 @@ void main() {
),
throwsA(isA<LibGit2Error>()),
);
ref.free();
});
});
@ -288,12 +262,10 @@ void main() {
expect(repo.references, contains('refs/tags/symbolic'));
expect(ref.type, ReferenceType.symbolic);
ref.free();
});
test('creates with force flag if name already exists', () {
final ref = Reference.create(
Reference.create(
repo: repo,
name: 'refs/tags/test',
target: 'refs/heads/master',
@ -308,13 +280,10 @@ void main() {
expect(forceRef.target.sha, lastCommit);
expect(forceRef.type, ReferenceType.symbolic);
ref.free();
forceRef.free();
});
test('throws if name already exists', () {
final ref = Reference.create(
Reference.create(
repo: repo,
name: 'refs/tags/exists',
target: 'refs/heads/master',
@ -328,8 +297,6 @@ void main() {
),
throwsA(isA<LibGit2Error>()),
);
ref.free();
});
test('throws if name is not valid', () {
@ -353,21 +320,16 @@ void main() {
logMessage: 'log message',
);
final reflog = ref.log;
final reflogEntry = reflog[0];
final reflogEntry = ref.log[0];
expect(reflogEntry.message, 'log message');
expect(reflogEntry.committer.name, 'name');
expect(reflogEntry.committer.email, 'email');
reflog.free();
ref.free();
});
});
test('deletes reference', () {
expect(repo.references, contains('refs/tags/v0.1'));
Reference.delete(repo: repo, name: 'refs/tags/v0.1');
expect(repo.references, isNot(contains('refs/tags/v0.1')));
});
@ -376,7 +338,6 @@ void main() {
test('with provided name', () {
final ref = Reference.lookup(repo: repo, name: 'refs/heads/master');
expect(ref.target.sha, lastCommit);
ref.free();
});
test('throws when error occured', () {
@ -389,11 +350,7 @@ void main() {
test('returns log for reference', () {
final ref = Reference.lookup(repo: repo, name: 'refs/heads/master');
final reflog = ref.log;
expect(reflog.last.message, 'commit (initial): init');
reflog.free();
ref.free();
expect(ref.log.last.message, 'commit (initial): init');
});
group('set target', () {
@ -401,8 +358,6 @@ void main() {
final ref = Reference.lookup(repo: repo, name: 'refs/heads/master');
ref.setTarget(target: repo[newCommit]);
expect(ref.target.sha, newCommit);
ref.free();
});
test('sets symbolic target with provided reference name', () {
@ -411,8 +366,6 @@ void main() {
ref.setTarget(target: 'refs/heads/feature');
expect(ref.target.sha, '5aecfa0fb97eadaac050ccb99f03c3fb65460ad4');
ref.free();
});
test('sets target with log message', () {
@ -422,13 +375,10 @@ void main() {
repo.setIdentity(name: 'name', email: 'email');
ref.setTarget(target: 'refs/heads/feature', logMessage: 'log message');
expect(ref.target.sha, '5aecfa0fb97eadaac050ccb99f03c3fb65460ad4');
final reflog = ref.log;
expect(reflog.first.message, 'log message');
expect(reflog.first.committer.name, 'name');
expect(reflog.first.committer.email, 'email');
reflog.free();
ref.free();
final logEntry = ref.log.first;
expect(logEntry.message, 'log message');
expect(logEntry.committer.name, 'name');
expect(logEntry.committer.email, 'email');
});
test('throws on invalid target', () {
@ -444,8 +394,6 @@ void main() {
);
expect(() => ref.setTarget(target: 0), throwsA(isA<ArgumentError>()));
ref.free();
});
});
@ -508,9 +456,6 @@ void main() {
);
expect(repo.references, isNot(contains('refs/tags/v0.1')));
expect(repo.references.length, 5);
ref1.free();
ref2.free();
});
});
@ -523,10 +468,6 @@ void main() {
expect(ref1.notEquals(ref2), false);
expect(ref1.equals(ref3), false);
expect(ref1.notEquals(ref3), true);
ref1.free();
ref2.free();
ref3.free();
});
test('peels to non-tag object when no type is provided', () {
@ -535,23 +476,17 @@ void main() {
final peeled = ref.peel() as Commit;
expect(peeled.oid, commit.oid);
peeled.free();
commit.free();
ref.free();
});
test('peels to object of provided type', () {
final ref = Reference.lookup(repo: repo, name: 'refs/heads/master');
final blob = Blob.lookup(repo: repo, oid: repo['9c78c21']);
final blobRef = Reference.create(
repo: repo,
name: 'refs/tags/blob',
target: blob.oid,
target: Blob.lookup(repo: repo, oid: repo['9c78c21']).oid,
);
final tagRef = Reference.lookup(repo: repo, name: 'refs/tags/v0.2');
final commit = Commit.lookup(repo: repo, oid: ref.target);
final tree = commit.tree;
final peeledCommit = ref.peel(GitObject.commit) as Commit;
final peeledTree = ref.peel(GitObject.tree) as Tree;
@ -559,20 +494,9 @@ void main() {
final peeledTag = tagRef.peel(GitObject.tag) as Tag;
expect(peeledCommit.oid, commit.oid);
expect(peeledTree.oid, tree.oid);
expect(peeledTree.oid, commit.tree.oid);
expect(peeledBlob.content, 'Feature edit\n');
expect(peeledTag.name, 'v0.2');
peeledTag.free();
peeledBlob.free();
peeledTree.free();
peeledCommit.free();
tagRef.free();
blobRef.free();
blob.free();
commit.free();
tree.free();
ref.free();
});
test('throws when trying to peel and error occurs', () {
@ -598,10 +522,14 @@ void main() {
);
});
test('manually releases allocated memory', () {
final ref = Reference.lookup(repo: repo, name: 'refs/heads/master');
expect(() => ref.free(), returnsNormally);
});
test('returns string representation of Reference object', () {
final ref = Reference.lookup(repo: repo, name: 'refs/heads/master');
expect(ref.toString(), contains('Reference{'));
ref.free();
});
});
}