add basic tests for Bug and OperationIterator

Michael MurΓ© created

Change summary

bug/bug.go                      | 27 +++++++++++++++++--
bug/operation_iterator.go       |  6 ++--
bug/operation_pack.go           |  6 +++
repository/git.go               |  2 -
test/bug_test.go                | 44 ++++++++++++++++++++++++++++++++
test/operation_iterator_test.go | 48 +++++++++++++++++++++++++++++++++++
6 files changed, 124 insertions(+), 9 deletions(-)

Detailed changes

bug/bug.go πŸ”—

@@ -37,7 +37,7 @@ func NewBug() (*Bug, error) {
 // IsValid check if the Bug data is valid
 func (bug *Bug) IsValid() bool {
 	// non-empty
-	if len(bug.Packs) == 0 {
+	if len(bug.Packs) == 0 && bug.Staging.IsEmpty() {
 		return false
 	}
 
@@ -48,9 +48,16 @@ func (bug *Bug) IsValid() bool {
 		}
 	}
 
+	// check if Staging is valid if needed
+	if !bug.Staging.IsEmpty() {
+		if !bug.Staging.IsValid() {
+			return false
+		}
+	}
+
 	// The very first Op should be a CREATE
-	firstOp := bug.Packs[0].Operations[0]
-	if firstOp.OpType() != CREATE {
+	firstOp := bug.firstOp()
+	if firstOp == nil || firstOp.OpType() != CREATE {
 		return false
 	}
 
@@ -82,3 +89,17 @@ func (bug *Bug) Commit() {
 func (bug *Bug) HumanId() string {
 	return bug.Id.String()
 }
+
+func (bug *Bug) firstOp() Operation {
+	for _, pack := range bug.Packs {
+		for _, op := range pack.Operations {
+			return op
+		}
+	}
+
+	if !bug.Staging.IsEmpty() {
+		return bug.Staging.Operations[0]
+	}
+
+	return nil
+}

bug/operation_iterator.go πŸ”—

@@ -16,7 +16,7 @@ func NewOperationIterator(bug *Bug) *OperationIterator {
 
 func (it *OperationIterator) Next() bool {
 	// Special case of the staging area
-	if it.packIndex == len(it.bug.Packs)+1 {
+	if it.packIndex == len(it.bug.Packs) {
 		pack := it.bug.Staging
 		it.opIndex++
 		return it.opIndex < len(pack.Operations)
@@ -39,7 +39,7 @@ func (it *OperationIterator) Next() bool {
 	it.packIndex++
 
 	// Special case of the non-empty staging area
-	if it.packIndex == len(it.bug.Packs)+1 && len(it.bug.Staging.Operations) > 0 {
+	if it.packIndex == len(it.bug.Packs) && len(it.bug.Staging.Operations) > 0 {
 		return true
 	}
 
@@ -48,7 +48,7 @@ func (it *OperationIterator) Next() bool {
 
 func (it *OperationIterator) Value() Operation {
 	// Special case of the staging area
-	if it.packIndex == len(it.bug.Packs)+1 {
+	if it.packIndex == len(it.bug.Packs) {
 		pack := it.bug.Staging
 
 		if it.opIndex >= len(pack.Operations) {

bug/operation_pack.go πŸ”—

@@ -15,6 +15,10 @@ func (opp *OperationPack) Append(op Operation) {
 	opp.Operations = append(opp.Operations, op)
 }
 
+func (opp *OperationPack) IsEmpty() bool {
+	return len(opp.Operations) == 0
+}
+
 func (opp *OperationPack) IsValid() bool {
-	return len(opp.Operations) > 0
+	return !opp.IsEmpty()
 }

repository/git.go πŸ”—

@@ -12,8 +12,6 @@ import (
 	"strings"
 )
 
-const branchRefPrefix = "refs/heads/"
-
 // GitRepo represents an instance of a (local) git repository.
 type GitRepo struct {
 	Path string

test/bug_test.go πŸ”—

@@ -0,0 +1,44 @@
+package test
+
+import (
+	"github.com/MichaelMure/git-bug/bug"
+	"github.com/MichaelMure/git-bug/bug/operations"
+	"testing"
+)
+
+func TestBug(t *testing.T) {
+	var rene = bug.Person{
+		Name:  "RenΓ© Descartes",
+		Email: "rene@descartes.fr",
+	}
+
+	var createOp = operations.NewCreateOp(rene, "title", "message")
+
+	bug1, err := bug.NewBug()
+
+	if err != nil {
+		t.Error(err)
+	}
+
+	if bug1.IsValid() {
+		t.Fatal("Empty bug should be invalid")
+	}
+
+	bug1.Append(createOp)
+
+	if !bug1.IsValid() {
+		t.Fatal("Bug with just a CREATE should be valid")
+	}
+
+	bug1.Append(createOp)
+
+	if bug1.IsValid() {
+		t.Fatal("Bug with multiple CREATE should be invalid")
+	}
+
+	bug1.Commit()
+
+	if bug1.IsValid() {
+		t.Fatal("Bug with multiple CREATE should be invalid")
+	}
+}

test/operation_iterator_test.go πŸ”—

@@ -0,0 +1,48 @@
+package test
+
+import (
+	"github.com/MichaelMure/git-bug/bug"
+	"github.com/MichaelMure/git-bug/bug/operations"
+	"testing"
+)
+
+func TestOpIterator(t *testing.T) {
+	var rene = bug.Person{
+		Name:  "RenΓ© Descartes",
+		Email: "rene@descartes.fr",
+	}
+
+	var createOp = operations.NewCreateOp(rene, "title", "message")
+	var setTitleOp = operations.NewSetTitleOp("title2")
+
+	bug1, err := bug.NewBug()
+
+	if err != nil {
+		t.Fatal(err)
+	}
+
+	bug1.Append(createOp)
+	bug1.Append(setTitleOp)
+	bug1.Commit()
+
+	bug1.Append(setTitleOp)
+	bug1.Append(setTitleOp)
+	bug1.Append(setTitleOp)
+	bug1.Commit()
+
+	bug1.Append(setTitleOp)
+	bug1.Append(setTitleOp)
+	bug1.Append(setTitleOp)
+
+	it := bug.NewOperationIterator(bug1)
+
+	counter := 0
+	for it.Next() {
+		_ = it.Value()
+		counter++
+	}
+
+	if counter != 8 {
+		t.Fatalf("Wrong count of value iterated (%d instead of 8)", counter)
+	}
+}