synapsecns/sanguine

View on GitHub
contrib/git-changes-action/detector/gitmock/repo.go

Summary

Maintainability
A
0 mins
Test Coverage
// Package gitmock provides utilities for testing git repos w/ mock data
package gitmock

import (
    "fmt"
    "github.com/brianvoe/gofakeit/v6"
    "github.com/go-git/go-git/v5"
    "github.com/go-git/go-git/v5/plumbing"
    "github.com/go-git/go-git/v5/plumbing/object"
    "github.com/stretchr/testify/assert"
    "github.com/synapsecns/sanguine/contrib/git-changes-action/detector/tree"
    "os"
    "path/filepath"
    "strings"
    "testing"
    "time"
)

// Repo is a test repo.
type Repo struct {
    repo         *git.Repository
    dir          string
    changedFiles []string
    tree         tree.Tree
    tb           testing.TB
}

// NewTestRepo creates a new test repo.
func NewTestRepo(tb testing.TB, r *git.Repository, dir string) (*Repo, error) {
    tb.Helper()

    testTree := tree.NewTree()
    // create a tree with the following structure:
    // we'll use this to add some paths
    err := tree.AddDirectoryPaths(testTree, dir, dir)
    assert.Nil(tb, err, "should not return an error")

    return &Repo{
        repo: r,
        dir:  dir,
        tb:   tb,
        tree: testTree,
    }, nil
}

// trimFiles trims files from a list of paths.
func (t *Repo) trimFiles(paths []string) (res []string) {
    t.tb.Helper()

    for _, path := range paths {
        stats, err := os.Stat(filepath.Join(t.dir, path))
        assert.Nil(t.tb, err)

        if stats.IsDir() {
            res = append(res, path)
        }
    }
    return res
}

// AddRandomFiles adds random files to the git repo
// addedFiles are returned relative to the repo.
func (t *Repo) AddRandomFiles(fileCount int) (addedFiles []string) {
    if fileCount > 0 {
        defer t.Commit()
    }

    dirPaths := t.trimFiles(t.tree.AllPaths())

    for i := 0; i < fileCount; i++ {
        newFile := filepath.Join(t.dir, gofakeit.RandomString(dirPaths), fmt.Sprintf("%s.dontignoreme", gofakeit.Word()))
        //nolint: gosec
        testFile, err := os.Create(newFile)
        assert.Nil(t.tb, err, "should not return an error")

        _, err = testFile.Write(gofakeit.ImageJpeg(20, 20))
        assert.Nil(t.tb, err, "should not return an error")

        addedFiles = append(addedFiles, strings.TrimPrefix(newFile, t.dir))
    }
    t.changedFiles = append(t.changedFiles, addedFiles...)
    return addedFiles
}

// Commit commits all changed files to the repo.
func (t *Repo) Commit() (hash string) {
    wt, err := t.repo.Worktree()
    assert.Nil(t.tb, err, "should be able to load work tree")

    err = wt.AddGlob(".")
    assert.Nil(t.tb, err, "should be able to add all files")

    var commitHash plumbing.Hash
    commitHash, err = wt.Commit("test Commit", &git.CommitOptions{
        Author: &object.Signature{
            Name:  gofakeit.Name(),
            Email: gofakeit.Email(),
            When:  time.Now(),
        },
    })
    assert.Nil(t.tb, err, "should be able to Commit")

    return commitHash.String()
}