Преглед изворни кода

Make CountLines() and BlobToString() public

Vadim Markovtsev пре 7 година
родитељ
комит
d2a2093e49
5 измењених фајлова са 116 додато и 36 уклоњено
  1. 2 28
      burndown.go
  2. 34 4
      diff.go
  3. 50 0
      diff_test.go
  4. 19 4
      dummies.go
  5. 11 0
      dummies_test.go

+ 2 - 28
burndown.go

@@ -1,7 +1,6 @@
 package hercules
 
 import (
-	"bufio"
 	"errors"
 	"fmt"
 	"io"
@@ -334,31 +333,6 @@ func checkClose(c io.Closer) {
 	}
 }
 
-func countLines(file *object.Blob) (int, error) {
-	reader, err := file.Reader()
-	if err != nil {
-		return 0, err
-	}
-	defer checkClose(reader)
-	var scanner *bufio.Scanner
-	buffer := make([]byte, bufio.MaxScanTokenSize)
-	counter := 0
-	for scanner == nil || scanner.Err() == bufio.ErrTooLong {
-		if scanner != nil && !utf8.Valid(scanner.Bytes()) {
-			return -1, errors.New("binary")
-		}
-		scanner = bufio.NewScanner(reader)
-		scanner.Buffer(buffer, 0)
-		for scanner.Scan() {
-			if !utf8.Valid(scanner.Bytes()) {
-				return -1, errors.New("binary")
-			}
-			counter++
-		}
-	}
-	return counter, nil
-}
-
 func (analyser *BurndownAnalysis) packPersonWithDay(person int, day int) int {
 	if analyser.PeopleNumber == 0 {
 		return day
@@ -441,7 +415,7 @@ func (analyser *BurndownAnalysis) newFile(
 func (analyser *BurndownAnalysis) handleInsertion(
 	change *object.Change, author int, cache map[plumbing.Hash]*object.Blob) error {
 	blob := cache[change.To.TreeEntry.Hash]
-	lines, err := countLines(blob)
+	lines, err := CountLines(blob)
 	if err != nil {
 		if err.Error() == "binary" {
 			return nil
@@ -463,7 +437,7 @@ func (analyser *BurndownAnalysis) handleDeletion(
 	change *object.Change, author int, cache map[plumbing.Hash]*object.Blob) error {
 
 	blob := cache[change.From.TreeEntry.Hash]
-	lines, err := countLines(blob)
+	lines, err := CountLines(blob)
 	if err != nil {
 		if err.Error() == "binary" {
 			return nil

+ 34 - 4
diff.go

@@ -1,8 +1,10 @@
 package hercules
 
 import (
+	"bufio"
 	"bytes"
 	"errors"
+	"unicode/utf8"
 
 	"github.com/sergi/go-diff/diffmatchpatch"
 	"gopkg.in/src-d/go-git.v4"
@@ -58,11 +60,11 @@ func (diff *FileDiff) Consume(deps map[string]interface{}) (map[string]interface
 			blob_to := cache[change.To.TreeEntry.Hash]
 			// we are not validating UTF-8 here because for example
 			// git/git 4f7770c87ce3c302e1639a7737a6d2531fe4b160 fetch-pack.c is invalid UTF-8
-			str_from, err := blobToString(blob_from)
+			str_from, err := BlobToString(blob_from)
 			if err != nil {
 				return nil, err
 			}
-			str_to, err := blobToString(blob_to)
+			str_to, err := BlobToString(blob_to)
 			if err != nil {
 				return nil, err
 			}
@@ -81,9 +83,37 @@ func (diff *FileDiff) Consume(deps map[string]interface{}) (map[string]interface
 	return map[string]interface{}{"file_diff": result}, nil
 }
 
-func blobToString(file *object.Blob) (string, error) {
+func CountLines(file *object.Blob) (int, error) {
 	if file == nil {
-		return "", errors.New("Blob not cached.")
+		return -1, errors.New("Blob is nil: probably not cached.")
+	}
+	reader, err := file.Reader()
+	if err != nil {
+		return -1, err
+	}
+	defer checkClose(reader)
+	var scanner *bufio.Scanner
+	buffer := make([]byte, bufio.MaxScanTokenSize)
+	counter := 0
+	for scanner == nil || scanner.Err() == bufio.ErrTooLong {
+		if scanner != nil && !utf8.Valid(scanner.Bytes()) {
+			return -1, errors.New("binary")
+		}
+		scanner = bufio.NewScanner(reader)
+		scanner.Buffer(buffer, 0)
+		for scanner.Scan() {
+			if !utf8.Valid(scanner.Bytes()) {
+				return -1, errors.New("binary")
+			}
+			counter++
+		}
+	}
+	return counter, nil
+}
+
+func BlobToString(file *object.Blob) (string, error) {
+	if file == nil {
+		return "", errors.New("Blob is nil: probably not cached.")
 	}
 	reader, err := file.Reader()
 	if err != nil {

+ 50 - 0
diff_test.go

@@ -177,3 +177,53 @@ func TestFileDiffConsumeInvalidBlob(t *testing.T) {
 	assert.Nil(t, res)
 	assert.NotNil(t, err)
 }
+
+func TestCountLines(t *testing.T) {
+	blob, _ := testRepository.BlobObject(
+		plumbing.NewHash("291286b4ac41952cbd1389fda66420ec03c1a9fe"))
+	lines, err := CountLines(blob)
+	assert.Equal(t, lines, 12)
+	assert.Nil(t, err)
+	lines, err = CountLines(nil)
+	assert.Equal(t, lines, -1)
+	assert.NotNil(t, err)
+	blob, _ = createDummyBlob(plumbing.NewHash("291286b4ac41952cbd1389fda66420ec03c1a9fe"), true)
+	lines, err = CountLines(blob)
+	assert.Equal(t, lines, -1)
+	assert.NotNil(t, err)
+	// test_data/blob
+	blob, err = testRepository.BlobObject(
+		plumbing.NewHash("c86626638e0bc8cf47ca49bb1525b40e9737ee64"))
+	assert.Nil(t, err)
+	lines, err = CountLines(blob)
+	assert.Equal(t, lines, -1)
+	assert.NotNil(t, err)
+	assert.EqualError(t, err, "binary")
+}
+
+func TestBlobToString(t *testing.T) {
+	blob, _ := testRepository.BlobObject(
+		plumbing.NewHash("291286b4ac41952cbd1389fda66420ec03c1a9fe"))
+	str, err := BlobToString(blob)
+	assert.Nil(t, err)
+	assert.Equal(t, str, `language: go
+
+go:
+  - 1.7
+
+go_import_path: gopkg.in/src-d/hercules.v1
+`+"  "+`
+script:
+  - go test -v -cpu=1,2 ./...
+
+notifications:
+  email: false
+`)
+	str, err = BlobToString(nil)
+	assert.Equal(t, str, "")
+	assert.NotNil(t, err)
+	blob, _ = createDummyBlob(plumbing.NewHash("291286b4ac41952cbd1389fda66420ec03c1a9fe"), true)
+	str, err = BlobToString(blob)
+	assert.Equal(t, str, "")
+	assert.NotNil(t, err)
+}

+ 19 - 4
dummies.go

@@ -3,6 +3,7 @@ package hercules
 import (
 	"io"
 
+	"github.com/pkg/errors"
 	"gopkg.in/src-d/go-git.v4/plumbing"
 	"gopkg.in/src-d/go-git.v4/plumbing/object"
 )
@@ -24,6 +25,7 @@ func (dummyIO) Close() error {
 
 type dummyEncodedObject struct {
 	FakeHash plumbing.Hash
+	Fails    bool
 }
 
 func (obj dummyEncodedObject) Hash() plumbing.Hash {
@@ -45,13 +47,26 @@ func (obj dummyEncodedObject) SetSize(int64) {
 }
 
 func (obj dummyEncodedObject) Reader() (io.ReadCloser, error) {
-	return dummyIO{}, nil
+	if !obj.Fails {
+		return dummyIO{}, nil
+	}
+	return nil, errors.New("dummy failure")
 }
 
 func (obj dummyEncodedObject) Writer() (io.WriteCloser, error) {
-	return dummyIO{}, nil
+	if !obj.Fails {
+		return dummyIO{}, nil
+	}
+	return nil, errors.New("dummy failure")
 }
 
-func createDummyBlob(hash plumbing.Hash) (*object.Blob, error) {
-	return object.DecodeBlob(dummyEncodedObject{hash})
+func createDummyBlob(hash plumbing.Hash, fails ...bool) (*object.Blob, error) {
+	if len(fails) > 1 {
+		panic("invalid usage of createDummyBlob() - this is a bug")
+	}
+	var realFails bool
+	if len(fails) == 1 {
+		realFails = fails[0]
+	}
+	return object.DecodeBlob(dummyEncodedObject{FakeHash: hash, Fails: realFails})
 }

+ 11 - 0
dummies_test.go

@@ -24,6 +24,17 @@ func TestCreateDummyBlob(t *testing.T) {
 	reader.Close()
 }
 
+func TestCreateDummyBlobFails(t *testing.T) {
+	dummy, err := createDummyBlob(plumbing.NewHash("334cde09da4afcb74f8d2b3e6fd6cce61228b485"), true)
+	assert.Nil(t, err)
+	reader, err := dummy.Reader()
+	assert.Nil(t, reader)
+	assert.NotNil(t, err)
+	assert.Panics(t, func() {
+		createDummyBlob(plumbing.NewHash("334cde09da4afcb74f8d2b3e6fd6cce61228b485"), true, true)
+	})
+}
+
 func TestNotUsedDummyStuff(t *testing.T) {
 	dio := dummyIO{}
 	n, err := dio.Write([]byte{})