Skip to content

Commit

Permalink
tests and fixes
Browse files Browse the repository at this point in the history
  • Loading branch information
tomvodi committed Sep 5, 2024
1 parent c5d7574 commit e52a097
Show file tree
Hide file tree
Showing 5 changed files with 209 additions and 59 deletions.
5 changes: 5 additions & 0 deletions .testcoverage.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -33,3 +33,8 @@ exclude:
- ^internal/health # simply just configuration for health check
- ^internal/pluginloader/process_handler\.go # too much effort to test
- ^cmd/limepipes-cli/cmd/arguments.go$ # only setup code
- ^cmd/limepipes-cli/cmd/import.go$ # only setup code
- ^cmd/limepipes-cli/cmd/parse.go$ # only setup code
- ^cmd/limepipes-cli/cmd/root.go$ # only setup code
- ^cmd/limepipes-cli/cmd/main.go$ # only setup code
- ^cmd/limepipes-cli/cmd/setup.go$ # only setup code
92 changes: 35 additions & 57 deletions cmd/limepipes-cli/cmd/common.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,10 @@ import (
"fmt"
"github.com/rs/zerolog/log"
"github.com/spf13/afero"
"github.com/tomvodi/limepipes-plugin-api/plugin/v1/fileformat"
"github.com/tomvodi/limepipes-plugin-api/plugin/v1/messages"
"github.com/tomvodi/limepipes/cmd/limepipes-cli/importtype"
"github.com/tomvodi/limepipes/internal/api"
"github.com/tomvodi/limepipes/internal/common"
"github.com/tomvodi/limepipes/internal/config"
"github.com/tomvodi/limepipes/internal/database"
"github.com/tomvodi/limepipes/internal/interfaces"
"github.com/tomvodi/limepipes/internal/pluginloader"
"io/fs"
"os"
"path/filepath"
Expand All @@ -27,41 +22,6 @@ type GetFilesOptions struct {
FileExtensions []string // only search for files with these extensions
}

func setupPluginLoader(
afs afero.Fs,
cfg *config.Config,
) (*pluginloader.Loader, error) {
// TODO: Load plugins from config
LoadPlugins := []string{
fileformat.Format_BWW.String(),
}

var pluginProcHandler interfaces.PluginProcessHandler = pluginloader.NewProcessHandler(LoadPlugins)
pluginLoader := pluginloader.NewPluginLoader(
afs,
pluginProcHandler,
LoadPlugins,
)
err := pluginLoader.LoadPluginsFromDir(cfg.PluginsDirectoryPath)
if err != nil {
return nil, fmt.Errorf("failed loading plugins: %w", err)
}

return pluginLoader, nil
}

func setupDbService(
cfg config.DbConfig,
) (*database.Service, error) {
db, err := database.GetInitPostgreSQLDB(cfg)
if err != nil {
return nil, fmt.Errorf("failed initializing database: %s", err.Error())
}
ginValidator := api.NewGinValidator()
apiModelValidator := api.NewAPIModelValidator(ginValidator)
return database.NewDbDataService(db, apiModelValidator), nil
}

// invalidImportTypesPassed takes a list of passed import types and returns
// a list of the import types that are not valid.
// It returns nil if all given import types are valid.
Expand Down Expand Up @@ -206,6 +166,10 @@ func fileHasValidExtension(

// checkForInvalidImportTypes checks if the given import types are valid.
func checkForInvalidImportTypes(iTypes []string) error {
if len(iTypes) == 0 {
return fmt.Errorf("no import types passed")
}

invalidTypes := invalidImportTypesPassed(iTypes)
if len(invalidTypes) > 0 {
return fmt.Errorf(
Expand All @@ -216,26 +180,43 @@ func checkForInvalidImportTypes(iTypes []string) error {
return nil
}

// moveProcessFile moves the file to the output directory if the MoveToOutputDir option is set.
func moveProcessFile(
pfc *ProcessFileContext,
opts *Options,
pfo *ProcessFilesOptions,
) error {
if pfo.MoveToOutputDir {
err := moveFileToDir(pfc.Filepath, opts.OutputDir)
err := moveFileToDir(pfo.Fs, pfc.Filepath, opts.OutputDir)
if err != nil {
log.Error().Err(err).Msgf("failed moving file %s to dir %s", pfc.Filepath, opts.OutputDir)
return err
}
}

return nil
}

func moveFileToDir(
afs afero.Fs,
file string,
dir string,
) error {
if dir == "" {
return fmt.Errorf("no output directory given")
}

fileName := filepath.Base(file)
newPath := filepath.Join(dir, fileName)
return afs.Rename(file, newPath)
}

func parseProcessFile(
pfc *ProcessFileContext,
opts *Options,
pfo *ProcessFilesOptions,
) ([]*messages.ImportedTune, error) {
tunes, err := parseFile(pfc.Filepath, pfc.PluginLoader)
tunes, err := parseFile(pfc, pfo)
if err != nil {
if opts.SkipFailedFiles {
log.Error().Err(err).Msgf("failed parsing file %s", pfc.Filepath)
Expand All @@ -249,28 +230,31 @@ func parseProcessFile(
}

func parseFile(
fPath string,
pluginLoader interfaces.PluginLoader,
pfc *ProcessFileContext,
pfo *ProcessFilesOptions,
) ([]*messages.ImportedTune, error) {
fExt := filepath.Ext(fPath)
fExt := filepath.Ext(pfc.Filepath)
if fExt == "" {
return nil, fmt.Errorf("import file %s does not have an extension", fPath)
return nil, fmt.Errorf(
"import file %s does not have an extension",
pfc.Filepath,
)
}

filePlugin, err := pluginLoader.PluginForFileExtension(fExt)
filePlugin, err := pfc.PluginLoader.PluginForFileExtension(fExt)
if err != nil {
return nil, fmt.Errorf("failed getting plugin for file %s with extension %s",
fPath, fExt)
pfc.Filepath, fExt)
}

fileData, err := os.ReadFile(fPath)
fileData, err := afero.ReadFile(pfo.Fs, pfc.Filepath)
if err != nil {
return nil, fmt.Errorf("failed reading file %s", fPath)
return nil, fmt.Errorf("failed reading file %s", pfc.Filepath)
}

tunesImport, err := filePlugin.Import(fileData)
if err != nil {
return nil, fmt.Errorf("failed parsing file %s", fPath)
return nil, fmt.Errorf("failed parsing file %s", pfc.Filepath)
}

return tunesImport.ImportedTunes, nil
Expand Down Expand Up @@ -322,9 +306,3 @@ func validFileExtensionsForImportTypes(

return fileExtensions, nil
}

func moveFileToDir(file string, dir string) error {
fileName := filepath.Base(file)
newPath := filepath.Join(dir, fileName)
return os.Rename(file, newPath)
}
122 changes: 121 additions & 1 deletion cmd/limepipes-cli/cmd/common_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,9 @@ func Test_getAllFilesFromPaths(t *testing.T) {
{
name: "no file extensions given",
prepare: func(f *fields) {
f.opts.FileExtensions = nil
f.opts = &GetFilesOptions{
FileExtensions: nil,
}
f.wantErr = true
},
},
Expand Down Expand Up @@ -160,3 +162,121 @@ func Test_getAllFilesFromPaths(t *testing.T) {
})
}
}

func Test_checkForInvalidImportTypes(t *testing.T) {
utils.SetupConsoleLogger()
type args struct {
iTypes []string
}
tests := []struct {
name string
args args
wantErr bool
}{
{
name: "no import types passed",
args: args{
iTypes: []string{},
},
wantErr: true,
},
{
name: "all possible import types passed",
args: args{
iTypes: importtype.AllTypes(),
},
wantErr: false,
},
{
name: "an invalid import type passed",
args: args{
iTypes: []string{"invalid"},
},
wantErr: true,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
if err := checkForInvalidImportTypes(tt.args.iTypes); (err != nil) != tt.wantErr {
t.Errorf("checkForInvalidImportTypes() error = %v, wantErr %v", err, tt.wantErr)
}
})
}
}

func Test_moveProcessFile(t *testing.T) {
g := NewGomegaWithT(t)
type fields struct {
pfc *ProcessFileContext
opts *Options
pfo *ProcessFilesOptions
expectedFile string
wantErr bool
}
tests := []struct {
name string
prepare func(f *fields)
}{
{
name: "no move configured",
prepare: func(f *fields) {
f.pfo.MoveToOutputDir = false
f.pfc.Filepath = "tune1.bww"
f.wantErr = false
},
},
{
name: "move configured but no output dir given",
prepare: func(f *fields) {
f.pfo.MoveToOutputDir = true
f.pfc.Filepath = "tune1.bww"
f.wantErr = true
},
},
{
name: "move and output dir configured",
prepare: func(f *fields) {
f.pfo.MoveToOutputDir = true
f.pfc.Filepath = "tune1.bww"
f.opts.OutputDir = "output"
f.expectedFile = "output/tune1.bww"
f.wantErr = false
},
},
}
for _, tt := range tests {
t.Run(tt.name, func(*testing.T) {
f := &fields{
pfc: &ProcessFileContext{},
opts: &Options{},
pfo: &ProcessFilesOptions{},
}

if tt.prepare != nil {
tt.prepare(f)
}

afs := afero.NewMemMapFs()
f.pfo.Fs = afs
_, err := afs.Create(f.pfc.Filepath)
g.Expect(err).To(BeNil())

err = moveProcessFile(
f.pfc,
f.opts,
f.pfo,
)
if f.wantErr {
g.Expect(err).Should(HaveOccurred())
} else {
g.Expect(err).ShouldNot(HaveOccurred())
}

if f.expectedFile != "" {
afs := f.pfo.Fs
_, err := afs.Stat(f.expectedFile)
g.Expect(err).NotTo(HaveOccurred())
}
})
}
}
2 changes: 1 addition & 1 deletion cmd/limepipes-cli/cmd/process_files.go
Original file line number Diff line number Diff line change
Expand Up @@ -206,7 +206,7 @@ func processFile(
opts *Options,
pfo *ProcessFilesOptions,
) error {
tunes, err := parseProcessFile(pfc, opts)
tunes, err := parseProcessFile(pfc, opts, pfo)
if errors.Is(err, common.ErrSkipped) {
return nil
}
Expand Down
47 changes: 47 additions & 0 deletions cmd/limepipes-cli/cmd/setup.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
package cmd

import (
"fmt"
"github.com/spf13/afero"
"github.com/tomvodi/limepipes-plugin-api/plugin/v1/fileformat"
"github.com/tomvodi/limepipes/internal/api"
"github.com/tomvodi/limepipes/internal/config"
"github.com/tomvodi/limepipes/internal/database"
"github.com/tomvodi/limepipes/internal/interfaces"
"github.com/tomvodi/limepipes/internal/pluginloader"
)

func setupPluginLoader(
afs afero.Fs,
cfg *config.Config,
) (*pluginloader.Loader, error) {
// TODO: Load plugins from config
LoadPlugins := []string{
fileformat.Format_BWW.String(),
}

var pluginProcHandler interfaces.PluginProcessHandler = pluginloader.NewProcessHandler(LoadPlugins)
pluginLoader := pluginloader.NewPluginLoader(
afs,
pluginProcHandler,
LoadPlugins,
)
err := pluginLoader.LoadPluginsFromDir(cfg.PluginsDirectoryPath)
if err != nil {
return nil, fmt.Errorf("failed loading plugins: %w", err)
}

return pluginLoader, nil
}

func setupDbService(
cfg config.DbConfig,
) (*database.Service, error) {
db, err := database.GetInitPostgreSQLDB(cfg)
if err != nil {
return nil, fmt.Errorf("failed initializing database: %s", err.Error())
}
ginValidator := api.NewGinValidator()
apiModelValidator := api.NewAPIModelValidator(ginValidator)
return database.NewDbDataService(db, apiModelValidator), nil
}

0 comments on commit e52a097

Please sign in to comment.