Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 2 additions & 21 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,24 +1,6 @@
# Pull Request Agent 🤖
# Scribe 🤖 ![CI](https://github.com/theoboldalex/pull_request_agent/actions/workflows/go.yml/badge.svg)

A really basic pull request agent that will take the diff of the current branch against the previous commit on the main branch. It uses this diff to write a brief pull request title and description.

## Prerequisites

Ensure you have a valid `OPENAI_API_KEY` variable set in your environment.

## Building and Running

TBC

## Running tests

Run the unit tests with:

![CI](https://github.com/theoboldalex/pull_request_agent/actions/workflows/go.yml/badge.svg)

# Pull Request Agent 🤖

A really basic pull request agent that takes the diff of the current branch against the main branch and uses that diff to generate a short pull request title and description.
Scribe is a basic pull request agent that takes the diff of the current branch against the main branch and uses that diff to generate a short pull request title and description.

## Prerequisites

Expand All @@ -36,4 +18,3 @@ Run the unit tests with:
go test ./...
```

The tests mock external git and file IO, so they are deterministic and do not require a git repository or an `instructions.md` file to be present.
166 changes: 83 additions & 83 deletions main_test.go
Original file line number Diff line number Diff line change
@@ -1,106 +1,106 @@
package main

import (
"errors"
"testing"
"errors"
"testing"
)

func TestGetCodeDiff_SameBranch_NoDiff(t *testing.T) {
origRun := runCommand
defer func() { runCommand = origRun }()

runCommand = func(name string, args ...string) ([]byte, error) {
if len(args) >= 1 && args[0] == "rev-parse" {
return []byte("main\n"), nil
}
if len(args) >= 1 && args[0] == "branch" {
return []byte("main\n"), nil
}
if len(args) >= 1 && args[0] == "diff" {
return []byte(""), nil
}
return nil, errors.New("unexpected git command")
}

diff, err := GetCodeDiff()
if err != nil {
t.Fatalf("expected no error, got %v", err)
}
if diff != "" {
t.Fatalf("expected empty diff, got %q", diff)
}
origRun := runCommand
defer func() { runCommand = origRun }()

runCommand = func(name string, args ...string) ([]byte, error) {
if len(args) >= 1 && args[0] == "rev-parse" {
return []byte("main\n"), nil
}
if len(args) >= 1 && args[0] == "branch" {
return []byte("main\n"), nil
}
if len(args) >= 1 && args[0] == "diff" {
return []byte(""), nil
}
return nil, errors.New("unexpected git command")
}

diff, err := GetCodeDiff()
if err != nil {
t.Fatalf("expected no error, got %v", err)
}
if diff != "" {
t.Fatalf("expected empty diff, got %q", diff)
}
}

func TestGetCodeDiff_DifferentBranch_WithDiff(t *testing.T) {
origRun := runCommand
defer func() { runCommand = origRun }()

runCommand = func(name string, args ...string) ([]byte, error) {
if len(args) >= 1 && args[0] == "rev-parse" {
return []byte("main\n"), nil
}
if len(args) >= 1 && args[0] == "branch" {
return []byte("feature-1\n"), nil
}
if len(args) >= 1 && args[0] == "diff" {
return []byte("diff --git a/foo b/foo\n"), nil
}
return nil, errors.New("unexpected git command")
}

diff, err := GetCodeDiff()
if err != nil {
t.Fatalf("expected no error, got %v", err)
}
if diff == "" {
t.Fatalf("expected non-empty diff")
}
origRun := runCommand
defer func() { runCommand = origRun }()

runCommand = func(name string, args ...string) ([]byte, error) {
if len(args) >= 1 && args[0] == "rev-parse" {
return []byte("main\n"), nil
}
if len(args) >= 1 && args[0] == "branch" {
return []byte("feature-1\n"), nil
}
if len(args) >= 1 && args[0] == "diff" {
return []byte("diff --git a/foo b/foo\n"), nil
}
return nil, errors.New("unexpected git command")
}

diff, err := GetCodeDiff()
if err != nil {
t.Fatalf("expected no error, got %v", err)
}
if diff == "" {
t.Fatalf("expected non-empty diff")
}
}

func TestGetCodeDiff_CommandError(t *testing.T) {
origRun := runCommand
defer func() { runCommand = origRun }()
origRun := runCommand
defer func() { runCommand = origRun }()

runCommand = func(name string, args ...string) ([]byte, error) {
return nil, errors.New("git failed")
}
runCommand = func(name string, args ...string) ([]byte, error) {
return nil, errors.New("git failed")
}

_, err := GetCodeDiff()
if err == nil {
t.Fatalf("expected error, got nil")
}
_, err := GetCodeDiff()
if err == nil {
t.Fatalf("expected error, got nil")
}
}

func TestGetAgentInstructions_Success(t *testing.T) {
origRead := readFile
defer func() { readFile = origRead }()

readFile = func(path string) ([]byte, error) {
if path != "instructions.md" {
return nil, errors.New("unexpected path")
}
return []byte("Do X\n"), nil
}

s, err := GetAgentInstructions()
if err != nil {
t.Fatalf("expected no error, got %v", err)
}
if s != "Do X\n" {
t.Fatalf("unexpected instructions: %q", s)
}
origRead := readFile
defer func() { readFile = origRead }()

readFile = func(path string) ([]byte, error) {
if path != "instructions.md" {
return nil, errors.New("unexpected path")
}
return []byte("Do X\n"), nil
}

s, err := GetAgentInstructions()
if err != nil {
t.Fatalf("expected no error, got %v", err)
}
if s != "Do X\n" {
t.Fatalf("unexpected instructions: %q", s)
}
}

func TestGetAgentInstructions_FileError(t *testing.T) {
origRead := readFile
defer func() { readFile = origRead }()
origRead := readFile
defer func() { readFile = origRead }()

readFile = func(path string) ([]byte, error) {
return nil, errors.New("read failed")
}
readFile = func(path string) ([]byte, error) {
return nil, errors.New("read failed")
}

_, err := GetAgentInstructions()
if err == nil {
t.Fatalf("expected error, got nil")
}
_, err := GetAgentInstructions()
if err == nil {
t.Fatalf("expected error, got nil")
}
}
Loading