diff --git a/example/reference_example.dart b/example/reference_example.dart index 1855d6f..97844c3 100644 --- a/example/reference_example.dart +++ b/example/reference_example.dart @@ -5,9 +5,9 @@ import 'package:libgit2dart/libgit2dart.dart'; void main() { final repo = Repository.open(Directory.current.path); - print('Repository references: ${Reference.list(repo)}'); + print('Repository references: ${repo.references.list()}'); - final ref = Reference.get(repo, 'refs/heads/master'); + final ref = repo.references['refs/heads/master']; print('Reference SHA hex: ${ref.target.sha}'); print('Is reference a local branch: ${ref.isBranch}'); diff --git a/lib/libgit2dart.dart b/lib/libgit2dart.dart index 5e63534..60e97ec 100644 --- a/lib/libgit2dart.dart +++ b/lib/libgit2dart.dart @@ -1,5 +1,4 @@ export 'src/repository.dart'; export 'src/config.dart'; export 'src/error.dart'; -export 'src/reference.dart'; export 'src/types.dart'; diff --git a/lib/src/reference.dart b/lib/src/reference.dart index 6ca68a9..7350716 100644 --- a/lib/src/reference.dart +++ b/lib/src/reference.dart @@ -5,21 +5,44 @@ import 'bindings/repository.dart' as repo_bindings; import 'odb.dart'; import 'oid.dart'; import 'reflog.dart'; -import 'repository.dart'; +import 'types.dart'; import 'util.dart'; -enum ReferenceType { direct, symbolic } +class References { + /// Initializes a new instance of the [References] class + /// from provided pointer to repository object in memory. + References(this._repoPointer); + + final Pointer _repoPointer; + + /// Returns a list of all the references that can be found in a repository. + /// + /// Throws a [LibGit2Error] if error occured. + List list() => bindings.list(_repoPointer); + + /// Returns a [Reference] by lookingup [name] in a repository. + /// + /// Should be freed with `free()` to release allocated memory. + /// + /// The name will be checked for validity. + /// + /// Throws a [LibGit2Error] if error occured. + Reference operator [](String name) { + final refPointer = bindings.lookup(_repoPointer, name); + return Reference(_repoPointer, refPointer); + } +} class Reference { /// Initializes a new instance of the [Reference] class. /// Should be freed with `free()` to release allocated memory. - Reference(this._refPointer) { + Reference(this._repoPointer, this._refPointer) { libgit2.git_libgit2_init(); } - /// Initializes a new instance of the [Reference] class by creating a new reference. + /// Initializes a new instance of the [Reference] class by creating a new direct reference. /// - /// The reference will be created in the repository and written to the disk. + /// The direct reference will be created in the repository and written to the disk. /// The generated [Reference] object must be freed by the user. /// /// Valid reference names must follow one of two patterns: @@ -29,104 +52,63 @@ class Reference { /// Names prefixed with "refs/" can be almost anything. You must avoid the characters /// '~', '^', ':', '\', '?', '[', and '*', and the sequences ".." and "@{" which have /// special meaning to revparse. + /// /// Throws a [LibGit2Error] if a reference already exists with the given name /// unless force is true, in which case it will be overwritten. /// /// The message for the reflog will be ignored if the reference does not belong in the /// standard set (HEAD, branches and remote-tracking branches) and it does not have a reflog. - Reference.create({ - required Repository repository, + Reference.createDirect({ + required Pointer repo, required String name, - required Object target, - bool force = false, + required Pointer oid, + required bool force, String? logMessage, }) { - late final Oid oid; - late final bool isDirect; - - if (target is Oid) { - oid = target; - isDirect = true; - } else if (isValidShaHex(target as String)) { - if (target.length == 40) { - oid = Oid.fromSHA(target); - } else { - final shortOid = Oid.fromSHAn(target); - final odb = repository.odb; - oid = Oid(odb.existsPrefix(shortOid.pointer, target.length)); - odb.free(); - } - isDirect = true; - } else { - isDirect = false; - } - - if (isDirect) { - _refPointer = bindings.createDirect( - repository.pointer, - name, - oid.pointer, - force, - logMessage, - ); - } else { - _refPointer = bindings.createSymbolic( - repository.pointer, - name, - target as String, - force, - logMessage, - ); - } + _repoPointer = repo; + _refPointer = bindings.createDirect(repo, name, oid, force, logMessage); } - /// Initializes a new instance of the [Reference] class by - /// lookingup a reference by [name] in a [repository]. + /// Initializes a new instance of the [Reference] class by creating a new symbolic reference. /// - /// Should be freed with `free()` to release allocated memory. + /// A symbolic reference is a reference name that refers to another reference name. + /// If the other name moves, the symbolic name will move, too. As a simple example, + /// the "HEAD" reference might refer to "refs/heads/master" while on the "master" branch + /// of a repository. /// - /// The name will be checked for validity. + /// The symbolic reference will be created in the repository and written to the disk. + /// The generated reference object must be freed by the user. /// - /// Throws a [LibGit2Error] if error occured. - Reference.get(Repository repository, String name) { - libgit2.git_libgit2_init(); - _refPointer = bindings.lookup(repository.pointer, name); - } - - /// Initializes a new instance of the [Reference] class by - /// lookingup a reference by DWIMing it's short [name] in a [repository]. + /// Valid reference names must follow one of two patterns: /// - /// Should be freed with `free()` to release allocated memory. + /// Top-level names must contain only capital letters and underscores, and must begin and end + /// with a letter. (e.g. "HEAD", "ORIG_HEAD"). + /// Names prefixed with "refs/" can be almost anything. You must avoid the characters + /// '~', '^', ':', '\', '?', '[', and '*', and the sequences ".." and "@{" which have special + /// meaning to revparse. + /// This function will throw an [LibGit2Error] if a reference already exists with the given + /// name unless force is true, in which case it will be overwritten. /// - /// The name will be checked for validity. - /// - /// Throws a [LibGit2Error] if error occured. - Reference.getDWIM(Repository repository, String name) { - libgit2.git_libgit2_init(); - _refPointer = bindings.lookupDWIM(repository.pointer, name); + /// The message for the reflog will be ignored if the reference does not belong in the standard + /// set (HEAD, branches and remote-tracking branches) and it does not have a reflog. + Reference.createSymbolic({ + required Pointer repo, + required String name, + required String target, + required bool force, + String? logMessage, + }) { + _repoPointer = repo; + _refPointer = + bindings.createSymbolic(repo, name, target, force, logMessage); } /// Pointer to memory address for allocated reference object. late Pointer _refPointer; - /// Checks if the reference [name] is well-formed. - /// - /// Valid reference names must follow one of two patterns: - /// - /// Top-level names must contain only capital letters and underscores, - /// and must begin and end with a letter. (e.g. "HEAD", "ORIG_HEAD"). - /// Names prefixed with "refs/" can be almost anything. You must avoid - /// the characters '~', '^', ':', '\', '?', '[', and '*', and the sequences ".." - /// and "@{" which have special meaning to revparse. - static bool isValidName(String name) { - libgit2.git_libgit2_init(); - final result = bindings.isValidName(name); - libgit2.git_libgit2_shutdown(); + late final Pointer _repoPointer; - return result; - } - - /// Returns the type of the reference + /// Returns the type of the reference. ReferenceType get type { return bindings.referenceType(_refPointer) == 1 ? ReferenceType.direct @@ -166,7 +148,10 @@ class Reference { odb.free(); } } else { - final ref = Reference(bindings.lookup(owner, target)); + final ref = Reference( + _repoPointer, + bindings.lookup(_repoPointer, target), + ); oid = ref.target; ref.free(); } @@ -204,31 +189,15 @@ class Reference { _refPointer = bindings.rename(_refPointer, newName, force, logMessage); } - /// Returns a list with all the references that can be found in a [repository]. - /// - /// Throws a [LibGit2Error] if error occured. - static List list(Repository repository) { - return bindings.list(repository.pointer); - } - /// Checks if a reflog exists for the specified reference [name]. /// /// Throws a [LibGit2Error] if error occured. - static bool hasLog(Repository repository, String name) { - return bindings.hasLog(repository.pointer, name); - } + bool get hasLog => bindings.hasLog(_repoPointer, name); - /// Returns a list with entries of reference log. - List get log { - final reflog = RefLog(this); - var log = []; - - for (var i = 0; i < reflog.count; i++) { - log.add(reflog.entryAt(i)); - } - - return log; - } + /// Returns a [RefLog] object. + /// + /// Should be freed when no longer needed. + RefLog get log => RefLog(this); /// Checks if a reference is a local branch. bool get isBranch => bindings.isBranch(_refPointer); diff --git a/lib/src/reflog.dart b/lib/src/reflog.dart index f27ec23..9de7019 100644 --- a/lib/src/reflog.dart +++ b/lib/src/reflog.dart @@ -19,6 +19,17 @@ class RefLog { /// Pointer to memory address for allocated reflog object. late final Pointer _reflogPointer; + /// Returns a list with entries of reference log. + List list() { + var log = []; + + for (var i = 0; i < count; i++) { + log.add(entryAt(i)); + } + + return log; + } + /// Returns the number of log entries in a reflog. int get count => bindings.entryCount(_reflogPointer); diff --git a/lib/src/repository.dart b/lib/src/repository.dart index b50ff02..dc6fc9b 100644 --- a/lib/src/repository.dart +++ b/lib/src/repository.dart @@ -191,7 +191,72 @@ class Repository { /// Returns [Reference] object pointing to repository head. /// /// Must be freed once it's no longer being used. - Reference get head => Reference(bindings.head(_repoPointer)); + Reference get head => Reference(_repoPointer, bindings.head(_repoPointer)); + + /// Returns [References] object. + References get references => References(_repoPointer); + + /// Creates a new reference. + /// + /// The reference will be created in the repository and written to the disk. + /// The generated [Reference] object must be freed by the user. + /// + /// Valid reference names must follow one of two patterns: + /// + /// Top-level names must contain only capital letters and underscores, and must begin and end + /// with a letter. (e.g. "HEAD", "ORIG_HEAD"). + /// Names prefixed with "refs/" can be almost anything. You must avoid the characters + /// '~', '^', ':', '\', '?', '[', and '*', and the sequences ".." and "@{" which have + /// special meaning to revparse. + /// Throws a [LibGit2Error] if a reference already exists with the given name + /// unless force is true, in which case it will be overwritten. + /// + /// The message for the reflog will be ignored if the reference does not belong in the + /// standard set (HEAD, branches and remote-tracking branches) and it does not have a reflog. + Reference createReference({ + required String name, + required Object target, + bool force = false, + String? logMessage, + }) { + late final Oid oid; + late final bool isDirect; + + if (target.runtimeType == Oid) { + oid = target as Oid; + isDirect = true; + } else if (isValidShaHex(target as String)) { + if (target.length == 40) { + oid = Oid.fromSHA(target); + } else { + final shortOid = Oid.fromSHAn(target); + final odb = this.odb; + oid = Oid(odb.existsPrefix(shortOid.pointer, target.length)); + odb.free(); + } + isDirect = true; + } else { + isDirect = false; + } + + if (isDirect) { + return Reference.createDirect( + repo: _repoPointer, + name: name, + oid: oid.pointer, + force: force, + logMessage: logMessage, + ); + } else { + return Reference.createSymbolic( + repo: _repoPointer, + name: name, + target: target as String, + force: force, + logMessage: logMessage, + ); + } + } /// Returns [Index] file for this repository. /// diff --git a/lib/src/types.dart b/lib/src/types.dart index 03b7efd..0a7bdfc 100644 --- a/lib/src/types.dart +++ b/lib/src/types.dart @@ -1,3 +1,5 @@ +enum ReferenceType { direct, symbolic } + /// Valid modes for index and tree entries. abstract class GitFilemode { static const int unreadable = 0; diff --git a/test/index_test.dart b/test/index_test.dart index ae249f0..861ee36 100644 --- a/test/index_test.dart +++ b/test/index_test.dart @@ -3,9 +3,6 @@ import 'dart:io'; import 'package:libgit2dart/libgit2dart.dart'; import 'package:test/test.dart'; import 'package:libgit2dart/src/index.dart'; -import 'package:libgit2dart/src/repository.dart'; -import 'package:libgit2dart/src/types.dart'; -import 'package:libgit2dart/src/error.dart'; import 'helpers/util.dart'; diff --git a/test/reference_test.dart b/test/reference_test.dart index 93b9fa7..2713129 100644 --- a/test/reference_test.dart +++ b/test/reference_test.dart @@ -1,11 +1,7 @@ import 'dart:io'; -import 'package:libgit2dart/src/reflog.dart'; import 'package:test/test.dart'; -import 'package:libgit2dart/src/repository.dart'; -import 'package:libgit2dart/src/reference.dart'; -import 'package:libgit2dart/src/error.dart'; - +import 'package:libgit2dart/libgit2dart.dart'; import 'helpers/util.dart'; void main() { @@ -32,225 +28,11 @@ void main() { await Directory(tmpDir).delete(recursive: true); }); - group('.createDirect()', () { - test('successfully creates with Oid as target', () { - final ref = Reference.get(repo, 'refs/heads/master'); - final refFromOid = Reference.create( - repository: repo, - name: 'refs/tags/from.oid', - target: ref.target, - ); - - expect(Reference.list(repo), contains('refs/tags/from.oid')); - - refFromOid.free(); - ref.free(); - }); - - test('successfully creates with SHA hash as target', () { - final refFromHash = Reference.create( - repository: repo, - name: 'refs/tags/from.hash', - target: lastCommit, - ); - - expect(Reference.list(repo), contains('refs/tags/from.hash')); - - refFromHash.free(); - }); - - test('successfully creates with short SHA hash as target', () { - final refFromHash = Reference.create( - repository: repo, - name: 'refs/tags/from.short.hash', - target: '78b8bf', - ); - - expect(Reference.list(repo), contains('refs/tags/from.short.hash')); - - refFromHash.free(); - }); - - test('successfully creates with log message', () { - repo.setIdentity(name: 'name', email: 'email'); - final ref = Reference.create( - repository: repo, - name: 'refs/heads/log.message', - target: lastCommit, - logMessage: 'log message', - ); - - final reflog = RefLog(ref); - final reflogEntry = reflog.entryAt(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', () { - expect( - () => Reference.create( - repository: repo, - name: 'refs/tags/invalid', - target: '78b', - ), - throwsA(isA()), - ); - }); - - test('throws if name is not valid', () { - expect( - () => Reference.create( - repository: repo, - name: 'refs/tags/invalid~', - target: lastCommit, - ), - throwsA(isA()), - ); - }); - - test('successfully creates with force flag if name already exists', () { - final ref = Reference.create( - repository: repo, - name: 'refs/tags/test', - target: lastCommit, - ); - - final forceRef = Reference.create( - repository: repo, - name: 'refs/tags/test', - target: lastCommit, - force: true, - ); - - expect(forceRef.target.sha, lastCommit); - - ref.free(); - forceRef.free(); - }); - - test('throws if name already exists', () { - final ref = Reference.create( - repository: repo, - name: 'refs/tags/test', - target: lastCommit, - ); - - expect( - () => Reference.create( - repository: repo, - name: 'refs/tags/test', - target: lastCommit, - ), - throwsA(isA()), - ); - - ref.free(); - }); - }); - - group('.createSymbolic()', () { - test('successfully creates with valid target', () { - final ref = Reference.create( - repository: repo, - name: 'refs/tags/symbolic', - target: 'refs/heads/master', - ); - - expect(Reference.list(repo), contains('refs/tags/symbolic')); - expect(ref.type, ReferenceType.symbolic); - - ref.free(); - }); - - test('successfully creates with force flag if name already exists', () { - final ref = Reference.create( - repository: repo, - name: 'refs/tags/test', - target: 'refs/heads/master', - ); - - final forceRef = Reference.create( - repository: repo, - name: 'refs/tags/test', - target: 'refs/heads/master', - force: true, - ); - - expect(forceRef.target.sha, lastCommit); - expect(forceRef.type, ReferenceType.symbolic); - - ref.free(); - forceRef.free(); - }); - - test('throws if name already exists', () { - final ref = Reference.create( - repository: repo, - name: 'refs/tags/exists', - target: 'refs/heads/master', - ); - - expect( - () => Reference.create( - repository: repo, - name: 'refs/tags/exists', - target: 'refs/heads/master', - ), - throwsA(isA()), - ); - - ref.free(); - }); - - test('throws if name is not valid', () { - expect( - () => Reference.create( - repository: repo, - name: 'refs/tags/invalid~', - target: 'refs/heads/master', - ), - throwsA(isA()), - ); - }); - - test('successfully creates with log message', () { - repo.setIdentity(name: 'name', email: 'email'); - final ref = Reference.create( - repository: repo, - name: 'HEAD', - target: 'refs/heads/feature', - force: true, - logMessage: 'log message', - ); - - final reflog = RefLog(ref); - final reflogEntry = reflog.entryAt(0); - - expect(reflogEntry.message, 'log message'); - expect(reflogEntry.committer['name'], 'name'); - expect(reflogEntry.committer['email'], 'email'); - - reflog.free(); - ref.free(); - }); - }); - - test('successfully deletes reference', () { - final ref = Reference.create( - repository: repo, - name: 'refs/tags/test', - target: lastCommit, + test('returns a list', () { + expect( + repo.references.list(), + ['refs/heads/feature', 'refs/heads/master', 'refs/tags/v0.1'], ); - expect(Reference.list(repo), contains('refs/tags/test')); - - ref.delete(); - expect(Reference.list(repo), isNot(contains('refs/tags/test'))); - ref.free(); }); test('returns correct type of reference', () { @@ -258,7 +40,7 @@ void main() { expect(head.type, ReferenceType.direct); head.free(); - final ref = Reference.get(repo, 'HEAD'); + final ref = repo.references['HEAD']; expect(ref.type, ReferenceType.symbolic); ref.free(); }); @@ -270,7 +52,7 @@ void main() { }); test('returns SHA hex of symbolic reference', () { - final ref = Reference.get(repo, 'HEAD'); + final ref = repo.references['HEAD']; expect(ref.target.sha, lastCommit); ref.free(); }); @@ -282,8 +64,7 @@ void main() { }); test('returns the short name', () { - final ref = Reference.create( - repository: repo, + final ref = repo.createReference( name: 'refs/remotes/origin/master', target: lastCommit, ); @@ -297,33 +78,20 @@ void main() { ref.free(); }); - test('returns a map with all the references of repository', () { - expect( - Reference.list(repo), - ['refs/heads/feature', 'refs/heads/master', 'refs/tags/v0.1'], - ); - }); - - test('checks if reflog exists for the reference', () { - expect(Reference.hasLog(repo, 'refs/heads/master'), true); - expect(Reference.hasLog(repo, 'refs/tags/v0.1'), false); - }); - test('checks if reference is a local branch', () { - final ref = Reference.get(repo, 'refs/heads/feature'); + final ref = repo.references['refs/heads/feature']; expect(ref.isBranch, true); ref.free(); }); test('checks if reference is a note', () { - final ref = Reference.get(repo, 'refs/heads/master'); + final ref = repo.references['refs/heads/master']; expect(ref.isNote, false); ref.free(); }); test('checks if reference is a remote branch', () { - final ref = Reference.create( - repository: repo, + final ref = repo.createReference( name: 'refs/remotes/origin/master', target: lastCommit, ); @@ -334,76 +102,251 @@ void main() { }); test('checks if reference is a tag', () { - final ref = Reference.get(repo, 'refs/tags/v0.1'); + final ref = repo.references['refs/tags/v0.1']; expect(ref.isTag, true); ref.free(); }); - group('.lookup()', () { - test('finds a reference with provided name', () { - final ref = Reference.get(repo, 'refs/heads/master'); + test('checks if reflog exists for the reference', () { + var ref = repo.references['refs/heads/master']; + expect(ref.hasLog, true); + + ref = repo.references['refs/tags/v0.1']; + expect(ref.hasLog, false); + + ref.free(); + }); + + group('create direct', () { + test('successfully creates with Oid as target', () { + final ref = repo.references['refs/heads/master']; + final refFromOid = repo.createReference( + name: 'refs/tags/from.oid', + target: ref.target, + ); + + expect(repo.references.list(), contains('refs/tags/from.oid')); + + refFromOid.free(); + ref.free(); + }); + + test('successfully creates with SHA hash as target', () { + final refFromHash = repo.createReference( + name: 'refs/tags/from.hash', + target: lastCommit, + ); + + expect(repo.references.list(), contains('refs/tags/from.hash')); + + refFromHash.free(); + }); + + test('successfully creates with short SHA hash as target', () { + final refFromHash = repo.createReference( + name: 'refs/tags/from.short.hash', + target: '78b8bf', + ); + + expect(repo.references.list(), contains('refs/tags/from.short.hash')); + + refFromHash.free(); + }); + + test('successfully creates with log message', () { + repo.setIdentity(name: 'name', email: 'email'); + final ref = repo.createReference( + name: 'refs/heads/log.message', + target: lastCommit, + logMessage: 'log message', + ); + + final reflog = ref.log; + final reflogEntry = reflog.entryAt(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', () { + expect( + () => repo.createReference( + name: 'refs/tags/invalid', + target: '78b', + ), + throwsA(isA()), + ); + }); + + test('throws if name is not valid', () { + expect( + () => repo.createReference( + name: 'refs/tags/invalid~', + target: lastCommit, + ), + throwsA(isA()), + ); + }); + + test('successfully creates with force flag if name already exists', () { + final ref = repo.createReference( + name: 'refs/tags/test', + target: lastCommit, + ); + + final forceRef = repo.createReference( + name: 'refs/tags/test', + target: lastCommit, + force: true, + ); + + expect(forceRef.target.sha, lastCommit); + + ref.free(); + forceRef.free(); + }); + + test('throws if name already exists', () { + final ref = repo.createReference( + name: 'refs/tags/test', + target: lastCommit, + ); + + expect( + () => repo.createReference( + name: 'refs/tags/test', + target: lastCommit, + ), + throwsA(isA()), + ); + + ref.free(); + }); + }); + + group('create symbolic', () { + test('successfully creates with valid target', () { + final ref = repo.createReference( + name: 'refs/tags/symbolic', + target: 'refs/heads/master', + ); + + expect(repo.references.list(), contains('refs/tags/symbolic')); + expect(ref.type, ReferenceType.symbolic); + + ref.free(); + }); + + test('successfully creates with force flag if name already exists', () { + final ref = repo.createReference( + name: 'refs/tags/test', + target: 'refs/heads/master', + ); + + final forceRef = repo.createReference( + name: 'refs/tags/test', + target: 'refs/heads/master', + force: true, + ); + + expect(forceRef.target.sha, lastCommit); + expect(forceRef.type, ReferenceType.symbolic); + + ref.free(); + forceRef.free(); + }); + + test('throws if name already exists', () { + final ref = repo.createReference( + name: 'refs/tags/exists', + target: 'refs/heads/master', + ); + + expect( + () => repo.createReference( + name: 'refs/tags/exists', + target: 'refs/heads/master', + ), + throwsA(isA()), + ); + + ref.free(); + }); + + test('throws if name is not valid', () { + expect( + () => repo.createReference( + name: 'refs/tags/invalid~', + target: 'refs/heads/master', + ), + throwsA(isA()), + ); + }); + + test('successfully creates with log message', () { + repo.setIdentity(name: 'name', email: 'email'); + final ref = repo.createReference( + name: 'HEAD', + target: 'refs/heads/feature', + force: true, + logMessage: 'log message', + ); + + final reflog = ref.log; + final reflogEntry = reflog.entryAt(0); + + expect(reflogEntry.message, 'log message'); + expect(reflogEntry.committer['name'], 'name'); + expect(reflogEntry.committer['email'], 'email'); + + reflog.free(); + ref.free(); + }); + }); + + test('successfully deletes reference', () { + final ref = repo.createReference( + name: 'refs/tags/test', + target: lastCommit, + ); + expect(repo.references.list(), contains('refs/tags/test')); + + ref.delete(); + expect(repo.references.list(), isNot(contains('refs/tags/test'))); + ref.free(); + }); + + group('finds', () { + test('with provided name', () { + final ref = repo.references['refs/heads/master']; expect(ref.target.sha, lastCommit); ref.free(); }); test('throws when error occured', () { expect( - () => Reference.get(repo, 'refs/heads/not/there'), - throwsA(isA()), - ); - }); - }); - - group('.lookupDWIM()', () { - test('finds a reference with provided name', () { - final remoteRef = Reference.create( - repository: repo, - name: 'refs/remotes/origin/master', - target: lastCommit, - ); - expect(remoteRef.shorthand, 'origin/master'); - - final tagRef = Reference.create( - repository: repo, - name: 'refs/tags/v1', - target: lastCommit, - ); - expect(tagRef.shorthand, 'v1'); - - var ref = Reference.getDWIM(repo, 'refs/heads/master'); - expect(ref.name, 'refs/heads/master'); - - ref = Reference.getDWIM(repo, 'master'); - expect(ref.name, 'refs/heads/master'); - - ref = Reference.getDWIM(repo, 'origin/master'); - expect(ref.name, 'refs/remotes/origin/master'); - - ref = Reference.getDWIM(repo, 'v1'); - expect(ref.name, 'refs/tags/v1'); - - remoteRef.free(); - tagRef.free(); - ref.free(); - }); - - test('throws when error occured', () { - expect( - () => Reference.getDWIM(repo, 'refs/heads/not/there'), + () => repo.references['refs/heads/not/there'], throwsA(isA()), ); }); }); test('returns log for reference', () { - final ref = Reference.get(repo, 'refs/heads/master'); - expect(ref.log.last.message, 'commit (initial): init'); + final ref = repo.references['refs/heads/master']; + final reflog = ref.log; + expect(reflog.list().last.message, 'commit (initial): init'); + + reflog.free(); ref.free(); }); - group('.setTarget()', () { - test('successfully sets target with SHA hex', () { - final ref = Reference.get(repo, 'refs/heads/master'); + group('set target', () { + test('successfully sets with SHA hex', () { + final ref = repo.references['refs/heads/master']; ref.setTarget(newCommit); expect(ref.target.sha, newCommit); @@ -411,7 +354,7 @@ void main() { }); test('successfully sets target with short SHA hex', () { - final ref = Reference.get(repo, 'refs/heads/master'); + final ref = repo.references['refs/heads/master']; ref.setTarget(newCommit.substring(0, 5)); expect(ref.target.sha, newCommit); @@ -419,7 +362,7 @@ void main() { }); test('successfully sets symbolic target', () { - final ref = Reference.get(repo, 'HEAD'); + final ref = repo.references['HEAD']; expect(ref.target.sha, lastCommit); ref.setTarget('refs/heads/feature'); @@ -429,21 +372,23 @@ void main() { }); test('successfully sets target with log message', () { - final ref = Reference.get(repo, 'HEAD'); + final ref = repo.references['HEAD']; expect(ref.target.sha, lastCommit); repo.setIdentity(name: 'name', email: 'email'); ref.setTarget('refs/heads/feature', 'log message'); expect(ref.target.sha, '5aecfa0fb97eadaac050ccb99f03c3fb65460ad4'); - expect(ref.log.first.message, 'log message'); - expect(ref.log.first.committer['name'], 'name'); - expect(ref.log.first.committer['email'], 'email'); + final reflog = ref.log; + expect(reflog.list().first.message, 'log message'); + expect(reflog.list().first.committer['name'], 'name'); + expect(reflog.list().first.committer['email'], 'email'); + reflog.free(); ref.free(); }); test('throws on invalid target', () { - final ref = Reference.get(repo, 'HEAD'); + final ref = repo.references['HEAD']; expect( () => ref.setTarget('refs/heads/invalid~'), throwsA(isA()), @@ -453,10 +398,9 @@ void main() { }); }); - group('.rename()', () { + group('rename', () { test('successfully renames reference', () { - final ref = Reference.create( - repository: repo, + final ref = repo.createReference( name: 'refs/tags/v1', target: lastCommit, ); @@ -469,8 +413,7 @@ void main() { }); test('throws on invalid name', () { - final ref = Reference.create( - repository: repo, + final ref = repo.createReference( name: 'refs/tags/v1', target: lastCommit, ); @@ -484,14 +427,12 @@ void main() { }); test('throws if name already exists', () { - final ref1 = Reference.create( - repository: repo, + final ref1 = repo.createReference( name: 'refs/tags/v1', target: lastCommit, ); - final ref2 = Reference.create( - repository: repo, + final ref2 = repo.createReference( name: 'refs/tags/v2', target: lastCommit, ); @@ -506,14 +447,12 @@ void main() { }); test('successfully renames with force flag set to true', () { - final ref1 = Reference.create( - repository: repo, + final ref1 = repo.createReference( name: 'refs/tags/v1', target: lastCommit, ); - final ref2 = Reference.create( - repository: repo, + final ref2 = repo.createReference( name: 'refs/tags/v2', target: newCommit, ); @@ -529,9 +468,9 @@ void main() { }); test('checks equality', () { - final ref1 = Reference.get(repo, 'refs/heads/master'); - final ref2 = Reference.get(repo, 'refs/heads/master'); - final ref3 = Reference.get(repo, 'refs/heads/feature'); + final ref1 = repo.references['refs/heads/master']; + final ref2 = repo.references['refs/heads/master']; + final ref3 = repo.references['refs/heads/feature']; expect(ref1 == ref2, true); expect(ref1 != ref2, false); @@ -542,32 +481,5 @@ void main() { ref2.free(); ref3.free(); }); - - group('isValidName()', () { - test('returns true for valid names', () { - expect(Reference.isValidName('HEAD'), true); - expect(Reference.isValidName('refs/heads/master'), true); - expect(Reference.isValidName('refs/heads/perfectly/valid'), true); - expect(Reference.isValidName('refs/tags/v1'), true); - expect(Reference.isValidName('refs/special/ref'), true); - expect(Reference.isValidName('refs/heads/ünicöde'), true); - expect(Reference.isValidName('refs/tags/😀'), true); - }); - - test('returns false for invalid names', () { - expect(Reference.isValidName(''), false); - expect(Reference.isValidName(' refs/heads/master'), false); - expect(Reference.isValidName('refs/heads/in..valid'), false); - expect(Reference.isValidName('refs/heads/invalid~'), false); - expect(Reference.isValidName('refs/heads/invalid^'), false); - expect(Reference.isValidName('refs/heads/invalid:'), false); - expect(Reference.isValidName('refs/heads/invalid\\'), false); - expect(Reference.isValidName('refs/heads/invalid?'), false); - expect(Reference.isValidName('refs/heads/invalid['), false); - expect(Reference.isValidName('refs/heads/invalid*'), false); - expect(Reference.isValidName('refs/heads/@{no}'), false); - expect(Reference.isValidName('refs/heads/foo//bar'), false); - }); - }); }); } diff --git a/test/repository_test.dart b/test/repository_test.dart index 4b41af0..ce16cc0 100644 --- a/test/repository_test.dart +++ b/test/repository_test.dart @@ -1,8 +1,7 @@ import 'dart:io'; import 'package:test/test.dart'; -import 'package:libgit2dart/src/repository.dart'; -import 'package:libgit2dart/src/error.dart'; +import 'package:libgit2dart/libgit2dart.dart'; import 'helpers/util.dart'; void main() {