Skip to content

Commit

Permalink
refactor, Consistent naming conventions for languages, models and pro…
Browse files Browse the repository at this point in the history
…viders
  • Loading branch information
zimmski committed Apr 19, 2024
1 parent f32da41 commit 08cb0c1
Show file tree
Hide file tree
Showing 12 changed files with 131 additions and 105 deletions.
1 change: 1 addition & 0 deletions cmd/eval-dev-quality/cmd/evaluate.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import (
"github.com/symflower/eval-dev-quality/evaluate/metrics"
"github.com/symflower/eval-dev-quality/evaluate/report"
"github.com/symflower/eval-dev-quality/language"
_ "github.com/symflower/eval-dev-quality/language/golang" // Register language.
"github.com/symflower/eval-dev-quality/log"
"github.com/symflower/eval-dev-quality/model"
"github.com/symflower/eval-dev-quality/provider"
Expand Down
5 changes: 3 additions & 2 deletions evaluate/repository_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import (
"github.com/symflower/eval-dev-quality/evaluate/metrics"
metricstesting "github.com/symflower/eval-dev-quality/evaluate/metrics/testing"
"github.com/symflower/eval-dev-quality/language"
"github.com/symflower/eval-dev-quality/language/golang"
"github.com/symflower/eval-dev-quality/model"
"github.com/symflower/eval-dev-quality/model/symflower"
)
Expand Down Expand Up @@ -53,8 +54,8 @@ func TestRepository(t *testing.T) {
validate(t, &testCase{
Name: "Plain",

Model: &symflower.ModelSymflower{},
Language: &language.LanguageGolang{},
Model: symflower.NewModel(),
Language: &golang.Language{},
TestDataPath: "../testdata",
RepositoryPath: "golang/plain",

Expand Down
21 changes: 11 additions & 10 deletions language/golang.go → language/golang/golang.go
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package language
package golang

import (
"errors"
Expand All @@ -12,30 +12,31 @@ import (
pkgerrors "github.com/pkg/errors"
"github.com/zimmski/osutil"

"github.com/symflower/eval-dev-quality/language"
"github.com/symflower/eval-dev-quality/util"
)

// LanguageGolang holds a Go language to evaluate a repository.
type LanguageGolang struct{}
// Language holds a Go language to evaluate a repository.
type Language struct{}

func init() {
Register(&LanguageGolang{})
language.Register(&Language{})
}

var _ Language = (*LanguageGolang)(nil)
var _ language.Language = (*Language)(nil)

// ID returns the unique ID of this language.
func (language *LanguageGolang) ID() (id string) {
func (l *Language) ID() (id string) {
return "golang"
}

// Name is the prose name of this language.
func (language *LanguageGolang) Name() (id string) {
func (l *Language) Name() (id string) {
return "Go"
}

// Files returns a list of relative file paths of the repository that should be evaluated.
func (language *LanguageGolang) Files(log *log.Logger, repositoryPath string) (filePaths []string, err error) {
func (l *Language) Files(log *log.Logger, repositoryPath string) (filePaths []string, err error) {
repositoryPath, err = filepath.Abs(repositoryPath)
if err != nil {
return nil, pkgerrors.WithStack(err)
Expand Down Expand Up @@ -63,7 +64,7 @@ var languageGoCoverageMatch = regexp.MustCompile(`(?m)^coverage: (\d+\.?\d+)% of
var languageGoNoCoverageMatch = regexp.MustCompile(`(?m)^coverage: \[no statements\]$`)

// Execute invokes the language specific testing on the given repository.
func (language *LanguageGolang) Execute(log *log.Logger, repositoryPath string) (coverage float64, err error) {
func (l *Language) Execute(log *log.Logger, repositoryPath string) (coverage float64, err error) {
stdout, _, err := util.CommandWithResult(log, &util.Command{
Command: []string{
"gotestsum",
Expand All @@ -90,7 +91,7 @@ func (language *LanguageGolang) Execute(log *log.Logger, repositoryPath string)
if err != nil {
return 0.0, pkgerrors.WithStack(err)
} else if testCount == 0 {
return 0.0, pkgerrors.WithStack(ErrNoTestFound)
return 0.0, pkgerrors.WithStack(language.ErrNoTestFound)
}

if languageGoNoCoverageMatch.MatchString(stdout) {
Expand Down
29 changes: 15 additions & 14 deletions language/golang_test.go → language/golang/golang_test.go
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package language
package golang

import (
"os"
Expand All @@ -10,14 +10,15 @@ import (
"github.com/zimmski/osutil"
"github.com/zimmski/osutil/bytesutil"

"github.com/symflower/eval-dev-quality/language"
"github.com/symflower/eval-dev-quality/log"
)

func TestLanguageGolangFiles(t *testing.T) {
func TestLanguageFiles(t *testing.T) {
type testCase struct {
Name string

LanguageGolang *LanguageGolang
Language *Language

RepositoryPath string

Expand All @@ -34,10 +35,10 @@ func TestLanguageGolangFiles(t *testing.T) {
}
}()

if tc.LanguageGolang == nil {
tc.LanguageGolang = &LanguageGolang{}
if tc.Language == nil {
tc.Language = &Language{}
}
actualFilePaths, actualError := tc.LanguageGolang.Files(logger, tc.RepositoryPath)
actualFilePaths, actualError := tc.Language.Files(logger, tc.RepositoryPath)

assert.Equal(t, tc.ExpectedFilePaths, actualFilePaths)
assert.Equal(t, tc.ExpectedError, actualError)
Expand All @@ -47,19 +48,19 @@ func TestLanguageGolangFiles(t *testing.T) {
validate(t, &testCase{
Name: "Plain",

RepositoryPath: "../testdata/golang/plain/",
RepositoryPath: "../../testdata/golang/plain/",

ExpectedFilePaths: []string{
"plain.go",
},
})
}

func TestLanguageGolangExecute(t *testing.T) {
func TestLanguageExecute(t *testing.T) {
type testCase struct {
Name string

LanguageGolang *LanguageGolang
LanguageGolang *Language

RepositoryPath string
RepositoryChange func(t *testing.T, repositoryPath string)
Expand Down Expand Up @@ -87,7 +88,7 @@ func TestLanguageGolangExecute(t *testing.T) {
}

if tc.LanguageGolang == nil {
tc.LanguageGolang = &LanguageGolang{}
tc.LanguageGolang = &Language{}
}
actualCoverage, actualError := tc.LanguageGolang.Execute(logger, repositoryPath)

Expand All @@ -105,16 +106,16 @@ func TestLanguageGolangExecute(t *testing.T) {
validate(t, &testCase{
Name: "No test files",

RepositoryPath: "../testdata/golang/plain/",
RepositoryPath: "../../testdata/golang/plain/",

ExpectedError: ErrNoTestFound,
ExpectedError: language.ErrNoTestFound,
})

t.Run("With test file", func(t *testing.T) {
validate(t, &testCase{
Name: "Valid",

RepositoryPath: "../testdata/golang/plain/",
RepositoryPath: "../../testdata/golang/plain/",
RepositoryChange: func(t *testing.T, repositoryPath string) {
require.NoError(t, os.WriteFile(filepath.Join(repositoryPath, "plain_test.go"), []byte(bytesutil.StringTrimIndentations(`
package plain
Expand All @@ -135,7 +136,7 @@ func TestLanguageGolangExecute(t *testing.T) {
validate(t, &testCase{
Name: "Syntax error",

RepositoryPath: "../testdata/golang/plain/",
RepositoryPath: "../../testdata/golang/plain/",
RepositoryChange: func(t *testing.T, repositoryPath string) {
require.NoError(t, os.WriteFile(filepath.Join(repositoryPath, "plain_test.go"), []byte(bytesutil.StringTrimIndentations(`
foobar
Expand Down
18 changes: 9 additions & 9 deletions model/llm/llm.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,17 +18,17 @@ import (
"github.com/symflower/eval-dev-quality/provider"
)

// llm represents a LLM model accessed via a provider.
type llm struct {
// Model represents a LLM model accessed via a provider.
type Model struct {
// provider is the client to query the LLM model.
provider provider.QueryProvider
provider provider.Query
// model holds the identifier for the LLM model.
model string
}

// NewLLMModel returns an LLM model corresponding to the given identifier which is queried via the given provider.
func NewLLMModel(provider provider.QueryProvider, modelIdentifier string) model.Model {
return &llm{
// NewModel returns an LLM model corresponding to the given identifier which is queried via the given provider.
func NewModel(provider provider.Query, modelIdentifier string) model.Model {
return &Model{
provider: provider,
model: modelIdentifier,
}
Expand Down Expand Up @@ -70,15 +70,15 @@ func llmGenerateTestForFilePrompt(data *llmGenerateTestForFilePromptContext) (me
return b.String(), nil
}

var _ model.Model = (*llm)(nil)
var _ model.Model = (*Model)(nil)

// ID returns the unique ID of this model.
func (m *llm) ID() (id string) {
func (m *Model) ID() (id string) {
return m.model
}

// GenerateTestsForFile generates test files for the given implementation file in a repository.
func (m *llm) GenerateTestsForFile(log *log.Logger, language language.Language, repositoryPath string, filePath string) (assessment metrics.Assessments, err error) {
func (m *Model) GenerateTestsForFile(log *log.Logger, language language.Language, repositoryPath string, filePath string) (assessment metrics.Assessments, err error) {
data, err := os.ReadFile(filepath.Join(repositoryPath, filePath))
if err != nil {
return nil, pkgerrors.WithStack(err)
Expand Down
9 changes: 5 additions & 4 deletions model/llm/llm_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,11 +14,12 @@ import (
"github.com/symflower/eval-dev-quality/evaluate/metrics"
metricstesting "github.com/symflower/eval-dev-quality/evaluate/metrics/testing"
"github.com/symflower/eval-dev-quality/language"
"github.com/symflower/eval-dev-quality/language/golang"
"github.com/symflower/eval-dev-quality/log"
providertesting "github.com/symflower/eval-dev-quality/provider/testing"
)

func TestModelLLMGenerateTestsForFile(t *testing.T) {
func TestModelGenerateTestsForFile(t *testing.T) {
type testCase struct {
Name string

Expand Down Expand Up @@ -51,7 +52,7 @@ func TestModelLLMGenerateTestsForFile(t *testing.T) {

mock := &providertesting.MockQueryProvider{}
tc.SetupMock(mock)
llm := NewLLMModel(mock, tc.ModelID)
llm := NewModel(mock, tc.ModelID)

actualAssessment, actualError := llm.GenerateTestsForFile(logger, tc.Language, temporaryPath, tc.SourceFilePath)
assert.NoError(t, actualError)
Expand All @@ -71,7 +72,7 @@ func TestModelLLMGenerateTestsForFile(t *testing.T) {
`
sourceFilePath := "simple.go"
promptMessage, err := llmGenerateTestForFilePrompt(&llmGenerateTestForFilePromptContext{
Language: &language.LanguageGolang{},
Language: &golang.Language{},

Code: bytesutil.StringTrimIndentations(sourceFileContent),
FilePath: sourceFilePath,
Expand All @@ -91,7 +92,7 @@ func TestModelLLMGenerateTestsForFile(t *testing.T) {
`), nil)
},

Language: &language.LanguageGolang{},
Language: &golang.Language{},
ModelID: "model-id",
SourceFileContent: sourceFileContent,
SourceFilePath: sourceFilePath,
Expand Down
15 changes: 10 additions & 5 deletions model/symflower/symflower.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,18 +12,23 @@ import (
"github.com/symflower/eval-dev-quality/util"
)

// ModelSymflower holds a Symflower model using the locally installed CLI.
type ModelSymflower struct{}
// Model holds a Symflower model using the locally installed CLI.
type Model struct{}

var _ model.Model = (*ModelSymflower)(nil)
// NewModel returns a Symflower model.
func NewModel() (model model.Model) {
return &Model{}
}

var _ model.Model = (*Model)(nil)

// ID returns the unique ID of this model.
func (m *ModelSymflower) ID() (id string) {
func (m *Model) ID() (id string) {
return "symflower" + provider.ProviderModelSeparator + "symbolic-execution"
}

// GenerateTestsForFile generates test files for the given implementation file in a repository.
func (m *ModelSymflower) GenerateTestsForFile(log *log.Logger, language language.Language, repositoryPath string, filePath string) (assessment metrics.Assessments, err error) {
func (m *Model) GenerateTestsForFile(log *log.Logger, language language.Language, repositoryPath string, filePath string) (assessment metrics.Assessments, err error) {
_, _, err = util.CommandWithResult(log, &util.Command{
Command: []string{
"symflower", "unit-tests",
Expand Down
15 changes: 8 additions & 7 deletions model/symflower/symflower_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,15 +11,16 @@ import (
"github.com/symflower/eval-dev-quality/evaluate/metrics"
metricstesting "github.com/symflower/eval-dev-quality/evaluate/metrics/testing"
"github.com/symflower/eval-dev-quality/language"
"github.com/symflower/eval-dev-quality/language/golang"
"github.com/symflower/eval-dev-quality/log"
)

func TestModelSymflowerGenerateTestsForFile(t *testing.T) {
func TestModelGenerateTestsForFile(t *testing.T) {
type testCase struct {
Name string

ModelSymflower *ModelSymflower
Language language.Language
Model *Model
Language language.Language

RepositoryPath string
RepositoryChange func(t *testing.T, repositoryPath string)
Expand Down Expand Up @@ -48,10 +49,10 @@ func TestModelSymflowerGenerateTestsForFile(t *testing.T) {
tc.RepositoryChange(t, repositoryPath)
}

if tc.ModelSymflower == nil {
tc.ModelSymflower = &ModelSymflower{}
if tc.Model == nil {
tc.Model = &Model{}
}
actualAssessment, actualError := tc.ModelSymflower.GenerateTestsForFile(logger, tc.Language, repositoryPath, tc.FilePath)
actualAssessment, actualError := tc.Model.GenerateTestsForFile(logger, tc.Language, repositoryPath, tc.FilePath)

if tc.ExpectedError != nil {
assert.ErrorIs(t, tc.ExpectedError, actualError)
Expand All @@ -69,7 +70,7 @@ func TestModelSymflowerGenerateTestsForFile(t *testing.T) {
validate(t, &testCase{
Name: "Go",

Language: &language.LanguageGolang{},
Language: &golang.Language{},

RepositoryPath: "../../testdata/golang/plain/",
FilePath: "plain.go",
Expand Down
Loading

0 comments on commit 08cb0c1

Please sign in to comment.