Skip to content

Commit

Permalink
Add tests, CI steps, and linting
Browse files Browse the repository at this point in the history
  • Loading branch information
sgerhardt committed Jul 19, 2024
1 parent a723697 commit bbc59f2
Show file tree
Hide file tree
Showing 6 changed files with 220 additions and 2 deletions.
18 changes: 18 additions & 0 deletions .github/workflows/.golangci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
linters:
enable:
- govet
- golint
- errcheck
- staticcheck
- unused
- structcheck
- varcheck
- paralleltest

issues:
exclude-rules:
- path: _test\.go
linters:
- golint
- staticcheck

37 changes: 37 additions & 0 deletions .github/workflows/golangci-lint.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
name: Go Lint

on:
push:
branches:
- main
pull_request:
branches:
- main

jobs:
lint:

runs-on: ubuntu-latest

steps:
- name: Checkout code
uses: actions/checkout@v3

- name: Set up Go
uses: actions/setup-go@v4
with:
go-version: 1.22

- name: Install golangci-lint
run: |
curl -sSfL https://raw.githubusercontent.com/golangci/golangci-lint/master/install.sh | sh -s -- -b $(go env GOPATH)/bin v1.59.1
- name: Install dependencies
run: go mod download

- name: Run golangci-lint
run: |
golangci-lint run
- name: Run tests
run: go test -v ./...
6 changes: 5 additions & 1 deletion Makefile
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
MOCKERY_CMD = mockery --name=Http --dir=./internal/client --output=./internal/client/mocks --outpkg=mocks
GOLANGCI_LINT := $(GOPATH)/bin/golangci-lint

# Define the target to generate mocks
.PHONY: mocks
mocks:
@echo "Generating mocks..."
Expand Down Expand Up @@ -31,6 +31,10 @@ test: install-mockery mocks
go test ./...
@echo "Tests completed."

.PHONY: lint
lint: $(GOLANGCI_LINT)
$(GOLANGCI_LINT) run

.PHONY: build
build:
@echo "Building binary..."
Expand Down
2 changes: 1 addition & 1 deletion internal/client/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ func (c *ElevenLabs) fileWithTimestamp() string {
} else if !strings.HasSuffix(c.Config.OutputDir, string(os.PathSeparator)) {
prefix = c.Config.OutputDir + string(os.PathSeparator)
}
return prefix + fmt.Sprintf("%s", formattedTime) + ".mp3"
return prefix + formattedTime + ".mp3"
}

func (c *ElevenLabs) Write(data []byte) (int, error) {
Expand Down
92 changes: 92 additions & 0 deletions internal/client/client_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
package client

import (
"bytes"
"chatter/internal/client/mocks"
"chatter/internal/config"
"errors"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/mock"
"github.com/stretchr/testify/require"
"io"
"net/http"
"testing"
)

func TestClient_GenerateVoiceFromText(t *testing.T) {
type fields struct {
apiKey string
outputFilePath string
}
type args struct {
text string
voiceID string
}

tests := []struct {
name string
fields fields
args args
error error
mockSetup func(client *mocks.Http)
}{
{
name: "errors if voice id is not populated",
args: args{
text: "test",
voiceID: "",
},
error: errors.New("voice ID is required"),
mockSetup: func(client *mocks.Http) {},
},
{
name: "marshals a payload to json",
fields: fields{},
args: args{
text: "testing",
voiceID: "stephen_hawking",
},

mockSetup: func(client *mocks.Http) {
mockResp := &http.Response{
StatusCode: http.StatusOK,
Body: io.NopCloser(bytes.NewReader([]byte("bytes representing the mp3 file..."))),
}

mockResp.StatusCode = http.StatusOK
mockResp.Body = io.NopCloser(bytes.NewReader([]byte("bytes representing the mp3 file...")))
// Set up the expectation
client.On("Do", mock.AnythingOfType("*http.Request")).Return(mockResp, nil).Run(func(args mock.Arguments) {
req := args.Get(0).(*http.Request)
// Verify the body of the request is the expected json
body := new(bytes.Buffer)
_, err := body.ReadFrom(req.Body)
require.NoError(t, err)
assert.Equal(t, body.String(), `{"text":"testing","model_id":"eleven_monolingual_v1","voice_settings":{"stability":0,"similarity_boost":0}}`)
})
},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
mockClient := mocks.NewHttp(t)
tt.mockSetup(mockClient)
cfg := config.AppConfig{
CharacterRequestLimit: 100,
OutputDir: tt.fields.outputFilePath,
APIKey: tt.fields.apiKey,
VoiceID: tt.args.voiceID,
}
c := New(cfg, mockClient)
_, err := c.FromText(tt.args.text, tt.args.voiceID)
if tt.error != nil {
assert.EqualError(t, err, tt.error.Error())
return
}

require.NoError(t, err)

mockClient.AssertExpectations(t)
})
}
}
67 changes: 67 additions & 0 deletions internal/client/web_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
package client

import (
"chatter/internal/client/mocks"
"chatter/internal/config"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/mock"
"io"
"net/http"
"strings"
"testing"
)

func TestWebReader(t *testing.T) {

tests := []struct {
name string
want []string

error error
charLimit int
mockSetup func(client *mocks.Http)
}{
{
name: "Given a website, read the header and body",
want: []string{"This is the h1\nThis is paragraph text\n"},
charLimit: 100,
mockSetup: func(client *mocks.Http) {
client.On("Do", mock.Anything).Return(&http.Response{
StatusCode: http.StatusOK,
Body: io.NopCloser(strings.NewReader(`<html><body><h1>This is the h1</h1><p>This is paragraph text</p></body></html>`)),
}, nil)
},
},
{
name: "Given a website that requires batching requests",
want: []string{"This ", "is th", "e h1\n", "This ", "is pa", "ragra", "ph te", "xt\n"},
charLimit: 5,
mockSetup: func(client *mocks.Http) {
client.On("Do", mock.Anything).Return(&http.Response{
StatusCode: http.StatusOK,
Body: io.NopCloser(strings.NewReader(`<html><body><h1>This is the h1</h1><p>This is paragraph text</p></body></html>`)),
}, nil)
},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
mockClient := mocks.NewHttp(t)
tt.mockSetup(mockClient)
appConfig := config.AppConfig{
CharacterRequestLimit: tt.charLimit,
APIKey: "testkey",
VoiceID: "testvoice",
WebsiteURL: "https://test.com",
}
c := New(appConfig, mockClient)
texts, err := c.FromWebsite("https://test.com")
if tt.error != nil {
assert.EqualError(t, err, tt.error.Error())
return
}
assert.Equal(t, tt.want, texts)
mockClient.AssertExpectations(t)
})
}
}

0 comments on commit bbc59f2

Please sign in to comment.