refactor config file type

This commit is contained in:
2025-09-05 23:51:21 +04:00
parent 1eb969480b
commit c3292dee5f
8 changed files with 94 additions and 179 deletions

View File

@@ -1,7 +1,6 @@
package parser package parser
import ( import (
"errors"
"flag" "flag"
"fmt" "fmt"
"net/url" "net/url"
@@ -173,17 +172,6 @@ func (parser ConfigCLIParser) Parse() (*config.Config, error) {
configFileParsed, err := types.ParseConfigFile(configFile) configFileParsed, err := types.ParseConfigFile(configFile)
_ = utils.HandleErrorOrDie(err, _ = utils.HandleErrorOrDie(err,
utils.OnSentinelError(types.ErrConfigFileExtensionNotFound, func(err error) error {
fieldParseErrors = append(
fieldParseErrors,
*types.NewFieldParseError(
fmt.Sprintf("config-file[%d]", i),
configFile,
errors.New("file extension not found"),
),
)
return nil
}),
utils.OnCustomError(func(err types.RemoteConfigFileParseError) error { utils.OnCustomError(func(err types.RemoteConfigFileParseError) error {
fieldParseErrors = append( fieldParseErrors = append(
fieldParseErrors, fieldParseErrors,
@@ -195,17 +183,6 @@ func (parser ConfigCLIParser) Parse() (*config.Config, error) {
) )
return nil return nil
}), }),
utils.OnCustomError(func(err types.UnknownConfigFileTypeError) error {
fieldParseErrors = append(
fieldParseErrors,
*types.NewFieldParseError(
fmt.Sprintf("config-file[%d]", i),
configFile,
fmt.Errorf("file type '%s' not supported (supported types: %s)", err.Type, types.ConfigFileTypeYAML),
),
)
return nil
}),
) )
if err == nil { if err == nil {

View File

@@ -317,31 +317,24 @@ func TestConfigCLIParser_Parse(t *testing.T) {
assert.Len(t, config.Files, 1) assert.Len(t, config.Files, 1)
}) })
t.Run("Parse with config-file flag invalid extension", func(t *testing.T) { t.Run("Parse with config-file flag without extension returns unknown type", func(t *testing.T) {
parser := NewConfigCLIParser([]string{"dodo", "-f", "/path/to/config"}) parser := NewConfigCLIParser([]string{"dodo", "-f", "/path/to/config"})
config, err := parser.Parse() config, err := parser.Parse()
assert.Nil(t, config) require.NoError(t, err)
var fieldErr types.FieldParseErrors require.NotNil(t, config)
require.ErrorAs(t, err, &fieldErr) assert.Len(t, config.Files, 1)
assert.Len(t, fieldErr.Errors, 1) assert.Equal(t, types.ConfigFileTypeUnknown, config.Files[0].Type())
assert.Equal(t, "config-file[0]", fieldErr.Errors[0].Field)
assert.Equal(t, "/path/to/config", fieldErr.Errors[0].Value)
assert.Contains(t, fieldErr.Errors[0].Err.Error(), "file extension not found")
}) })
t.Run("Parse with config-file flag unsupported file type", func(t *testing.T) { t.Run("Parse with config-file flag unsupported file type returns unknown type", func(t *testing.T) {
parser := NewConfigCLIParser([]string{"dodo", "-f", "/path/to/config.json"}) parser := NewConfigCLIParser([]string{"dodo", "-f", "/path/to/config.json"})
config, err := parser.Parse() config, err := parser.Parse()
assert.Nil(t, config) require.NoError(t, err)
var fieldErr types.FieldParseErrors require.NotNil(t, config)
require.ErrorAs(t, err, &fieldErr) assert.Len(t, config.Files, 1)
assert.Len(t, fieldErr.Errors, 1) assert.Equal(t, types.ConfigFileTypeUnknown, config.Files[0].Type())
assert.Equal(t, "config-file[0]", fieldErr.Errors[0].Field)
assert.Equal(t, "/path/to/config.json", fieldErr.Errors[0].Value)
assert.Contains(t, fieldErr.Errors[0].Err.Error(), "file type")
assert.Contains(t, fieldErr.Errors[0].Err.Error(), "not supported")
}) })
t.Run("Parse with config-file flag remote URL", func(t *testing.T) { t.Run("Parse with config-file flag remote URL", func(t *testing.T) {

View File

@@ -35,17 +35,6 @@ func (parser ConfigENVParser) Parse() (*config.Config, error) {
configFileParsed, err := types.ParseConfigFile(configFile) configFileParsed, err := types.ParseConfigFile(configFile)
_ = utils.HandleErrorOrDie(err, _ = utils.HandleErrorOrDie(err,
utils.OnSentinelError(types.ErrConfigFileExtensionNotFound, func(err error) error {
fieldParseErrors = append(
fieldParseErrors,
*types.NewFieldParseError(
parser.getFullEnvName("CONFIG_FILE"),
configFile,
errors.New("file extension not found"),
),
)
return nil
}),
utils.OnCustomError(func(err types.RemoteConfigFileParseError) error { utils.OnCustomError(func(err types.RemoteConfigFileParseError) error {
fieldParseErrors = append( fieldParseErrors = append(
fieldParseErrors, fieldParseErrors,
@@ -57,17 +46,6 @@ func (parser ConfigENVParser) Parse() (*config.Config, error) {
) )
return nil return nil
}), }),
utils.OnCustomError(func(err types.UnknownConfigFileTypeError) error {
fieldParseErrors = append(
fieldParseErrors,
*types.NewFieldParseError(
parser.getFullEnvName("CONFIG_FILE"),
configFile,
fmt.Errorf("file type '%s' not supported (supported types: %s)", err.Type, types.ConfigFileTypeYAML),
),
)
return nil
}),
) )
if err == nil { if err == nil {

View File

@@ -74,39 +74,34 @@ func TestConfigENVParser_Parse_ConfigFile(t *testing.T) {
require.NoError(t, err) require.NoError(t, err)
require.NotNil(t, config) require.NotNil(t, config)
assert.Len(t, config.Files, 1) assert.Len(t, config.Files, 1)
assert.Equal(t, "/path/to/config.yaml", config.Files[0].String()) assert.Equal(t, "/path/to/config.yaml", config.Files[0].Path())
assert.Equal(t, types.ConfigFileTypeYAML, config.Files[0].Type()) assert.Equal(t, types.ConfigFileTypeYAML, config.Files[0].Type())
}) })
t.Run("Parse with config file without extension", func(t *testing.T) { t.Run("Parse with config file without extension returns unknown type", func(t *testing.T) {
t.Setenv("CONFIG_FILE", "/path/to/config") t.Setenv("CONFIG_FILE", "/path/to/config")
parser := NewConfigENVParser("") parser := NewConfigENVParser("")
config, err := parser.Parse() config, err := parser.Parse()
assert.Nil(t, config) require.NoError(t, err)
var fieldErr types.FieldParseErrors require.NotNil(t, config)
require.ErrorAs(t, err, &fieldErr) assert.Len(t, config.Files, 1)
assert.Len(t, fieldErr.Errors, 1) assert.Equal(t, "/path/to/config", config.Files[0].Path())
assert.Equal(t, "CONFIG_FILE", fieldErr.Errors[0].Field) assert.Equal(t, types.ConfigFileTypeUnknown, config.Files[0].Type())
assert.Equal(t, "/path/to/config", fieldErr.Errors[0].Value)
assert.Contains(t, fieldErr.Errors[0].Err.Error(), "file extension not found")
}) })
t.Run("Parse with unsupported config file type", func(t *testing.T) { t.Run("Parse with unsupported config file type returns unknown type", func(t *testing.T) {
t.Setenv("CONFIG_FILE", "/path/to/config.json") t.Setenv("CONFIG_FILE", "/path/to/config.json")
parser := NewConfigENVParser("") parser := NewConfigENVParser("")
config, err := parser.Parse() config, err := parser.Parse()
assert.Nil(t, config) require.NoError(t, err)
var fieldErr types.FieldParseErrors require.NotNil(t, config)
require.ErrorAs(t, err, &fieldErr) assert.Len(t, config.Files, 1)
assert.Len(t, fieldErr.Errors, 1) assert.Equal(t, "/path/to/config.json", config.Files[0].Path())
assert.Equal(t, "CONFIG_FILE", fieldErr.Errors[0].Field) assert.Equal(t, types.ConfigFileTypeUnknown, config.Files[0].Type())
assert.Equal(t, "/path/to/config.json", fieldErr.Errors[0].Value)
assert.Contains(t, fieldErr.Errors[0].Err.Error(), "file type")
assert.Contains(t, fieldErr.Errors[0].Err.Error(), "not supported")
}) })
t.Run("Parse with remote config file URL", func(t *testing.T) { t.Run("Parse with remote config file URL", func(t *testing.T) {
@@ -118,7 +113,7 @@ func TestConfigENVParser_Parse_ConfigFile(t *testing.T) {
require.NoError(t, err) require.NoError(t, err)
require.NotNil(t, config) require.NotNil(t, config)
assert.Len(t, config.Files, 1) assert.Len(t, config.Files, 1)
assert.Equal(t, "https://example.com/config.yaml", config.Files[0].String()) assert.Equal(t, "https://example.com/config.yaml", config.Files[0].Path())
assert.Equal(t, types.ConfigFileTypeYAML, config.Files[0].Type()) assert.Equal(t, types.ConfigFileTypeYAML, config.Files[0].Type())
assert.Equal(t, types.ConfigFileLocationRemote, config.Files[0].LocationType()) assert.Equal(t, types.ConfigFileLocationRemote, config.Files[0].LocationType())
}) })
@@ -661,7 +656,7 @@ func TestConfigENVParser_Parse_AllFields(t *testing.T) {
// Verify all fields // Verify all fields
assert.Len(t, config.Files, 1) assert.Len(t, config.Files, 1)
assert.Equal(t, "/path/to/config.yaml", config.Files[0].String()) assert.Equal(t, "/path/to/config.yaml", config.Files[0].Path())
require.NotNil(t, config.Yes) require.NotNil(t, config.Yes)
assert.True(t, *config.Yes) assert.True(t, *config.Yes)
@@ -728,7 +723,7 @@ func TestConfigENVParser_Parse_AllFields(t *testing.T) {
// Verify all fields // Verify all fields
assert.Len(t, config.Files, 1) assert.Len(t, config.Files, 1)
assert.Equal(t, "/app/config.yml", config.Files[0].String()) assert.Equal(t, "/app/config.yml", config.Files[0].Path())
require.NotNil(t, config.Yes) require.NotNil(t, config.Yes)
assert.False(t, *config.Yes) assert.False(t, *config.Yes)
@@ -765,7 +760,7 @@ func TestConfigENVParser_Parse_AllFields(t *testing.T) {
func TestConfigENVParser_Parse_MultipleErrors(t *testing.T) { func TestConfigENVParser_Parse_MultipleErrors(t *testing.T) {
t.Run("Parse with multiple field errors", func(t *testing.T) { t.Run("Parse with multiple field errors", func(t *testing.T) {
// Set multiple invalid values // Set multiple invalid values
t.Setenv("CONFIG_FILE", "/path/to/config") // Missing extension t.Setenv("CONFIG_FILE", "/path/to/config") // Now this is valid (returns unknown type)
t.Setenv("YES", "invalid_bool") t.Setenv("YES", "invalid_bool")
t.Setenv("SKIP_VERIFY", "not_a_bool") t.Setenv("SKIP_VERIFY", "not_a_bool")
t.Setenv("URL", "://invalid-url") t.Setenv("URL", "://invalid-url")
@@ -782,8 +777,8 @@ func TestConfigENVParser_Parse_MultipleErrors(t *testing.T) {
var fieldErr types.FieldParseErrors var fieldErr types.FieldParseErrors
require.ErrorAs(t, err, &fieldErr) require.ErrorAs(t, err, &fieldErr)
// Should have 9 errors // Should have 8 errors (CONFIG_FILE is no longer an error)
assert.Len(t, fieldErr.Errors, 9) assert.Len(t, fieldErr.Errors, 8)
// Check that all expected fields have errors // Check that all expected fields have errors
errorFields := make(map[string]bool) errorFields := make(map[string]bool)
@@ -791,7 +786,7 @@ func TestConfigENVParser_Parse_MultipleErrors(t *testing.T) {
errorFields[e.Field] = true errorFields[e.Field] = true
} }
assert.True(t, errorFields["CONFIG_FILE"]) assert.False(t, errorFields["CONFIG_FILE"]) // CONFIG_FILE should not have an error
assert.True(t, errorFields["YES"]) assert.True(t, errorFields["YES"])
assert.True(t, errorFields["SKIP_VERIFY"]) assert.True(t, errorFields["SKIP_VERIFY"])
assert.True(t, errorFields["URL"]) assert.True(t, errorFields["URL"])

View File

@@ -9,7 +9,8 @@ import (
type ConfigFileType string type ConfigFileType string
const ( const (
ConfigFileTypeYAML ConfigFileType = "yaml/yml" ConfigFileTypeUnknown ConfigFileType = "unknown"
ConfigFileTypeYAML ConfigFileType = "yaml/yml"
) )
type ConfigFileLocationType string type ConfigFileLocationType string
@@ -25,7 +26,7 @@ type ConfigFile struct {
locationType ConfigFileLocationType locationType ConfigFileLocationType
} }
func (configFile ConfigFile) String() string { func (configFile ConfigFile) Path() string {
return configFile.path return configFile.path
} }
@@ -41,9 +42,7 @@ func (configFile ConfigFile) LocationType() ConfigFileLocationType {
// path or URL and returns a ConfigFile struct. // path or URL and returns a ConfigFile struct.
// It determines the file's type and location (local or remote) based on the string. // It determines the file's type and location (local or remote) based on the string.
// It can return the following errors: // It can return the following errors:
// - ErrConfigFileExtensionNotFound
// - RemoteConfigFileParseError // - RemoteConfigFileParseError
// - UnknownConfigFileTypeError
func ParseConfigFile(configFileRaw string) (*ConfigFile, error) { func ParseConfigFile(configFileRaw string) (*ConfigFile, error) {
configFileParsed := &ConfigFile{ configFileParsed := &ConfigFile{
path: configFileRaw, path: configFileRaw,
@@ -64,15 +63,12 @@ func ParseConfigFile(configFileRaw string) (*ConfigFile, error) {
} }
configFileExtension, _ := strings.CutPrefix(filepath.Ext(configFilePath), ".") configFileExtension, _ := strings.CutPrefix(filepath.Ext(configFilePath), ".")
if configFileExtension == "" {
return nil, ErrConfigFileExtensionNotFound
}
switch strings.ToLower(configFileExtension) { switch strings.ToLower(configFileExtension) {
case "yml", "yaml": case "yml", "yaml":
configFileParsed._type = ConfigFileTypeYAML configFileParsed._type = ConfigFileTypeYAML
default: default:
return nil, NewUnknownConfigFileTypeError(configFileExtension) configFileParsed._type = ConfigFileTypeUnknown
} }
return configFileParsed, nil return configFileParsed, nil

View File

@@ -10,20 +10,25 @@ import (
func TestConfigFile_String(t *testing.T) { func TestConfigFile_String(t *testing.T) {
t.Run("String returns the file path", func(t *testing.T) { t.Run("String returns the file path", func(t *testing.T) {
configFile := ConfigFile{path: "/path/to/config.yaml"} configFile := ConfigFile{path: "/path/to/config.yaml"}
assert.Equal(t, "/path/to/config.yaml", configFile.String()) assert.Equal(t, "/path/to/config.yaml", configFile.Path())
}) })
t.Run("String returns empty path", func(t *testing.T) { t.Run("String returns empty path", func(t *testing.T) {
configFile := ConfigFile{path: ""} configFile := ConfigFile{path: ""}
assert.Empty(t, configFile.String()) assert.Empty(t, configFile.Path())
}) })
} }
func TestConfigFile_Type(t *testing.T) { func TestConfigFile_Type(t *testing.T) {
t.Run("Type returns the config file type", func(t *testing.T) { t.Run("Type returns YAML config file type", func(t *testing.T) {
configFile := ConfigFile{_type: ConfigFileTypeYAML} configFile := ConfigFile{_type: ConfigFileTypeYAML}
assert.Equal(t, ConfigFileTypeYAML, configFile.Type()) assert.Equal(t, ConfigFileTypeYAML, configFile.Type())
}) })
t.Run("Type returns Unknown config file type", func(t *testing.T) {
configFile := ConfigFile{_type: ConfigFileTypeUnknown}
assert.Equal(t, ConfigFileTypeUnknown, configFile.Type())
})
} }
func TestConfigFile_LocationType(t *testing.T) { func TestConfigFile_LocationType(t *testing.T) {
@@ -44,7 +49,7 @@ func TestParseConfigFile(t *testing.T) {
require.NoError(t, err) require.NoError(t, err)
require.NotNil(t, configFile) require.NotNil(t, configFile)
assert.Equal(t, "config.yml", configFile.String()) assert.Equal(t, "config.yml", configFile.Path())
assert.Equal(t, ConfigFileTypeYAML, configFile.Type()) assert.Equal(t, ConfigFileTypeYAML, configFile.Type())
assert.Equal(t, ConfigFileLocationLocal, configFile.LocationType()) assert.Equal(t, ConfigFileLocationLocal, configFile.LocationType())
}) })
@@ -54,7 +59,7 @@ func TestParseConfigFile(t *testing.T) {
require.NoError(t, err) require.NoError(t, err)
require.NotNil(t, configFile) require.NotNil(t, configFile)
assert.Equal(t, "config.yaml", configFile.String()) assert.Equal(t, "config.yaml", configFile.Path())
assert.Equal(t, ConfigFileTypeYAML, configFile.Type()) assert.Equal(t, ConfigFileTypeYAML, configFile.Type())
assert.Equal(t, ConfigFileLocationLocal, configFile.LocationType()) assert.Equal(t, ConfigFileLocationLocal, configFile.LocationType())
}) })
@@ -68,7 +73,7 @@ func TestParseConfigFile(t *testing.T) {
require.NoError(t, err) require.NoError(t, err)
require.NotNil(t, configFile) require.NotNil(t, configFile)
assert.Equal(t, testCase, configFile.String()) assert.Equal(t, testCase, configFile.Path())
assert.Equal(t, ConfigFileTypeYAML, configFile.Type()) assert.Equal(t, ConfigFileTypeYAML, configFile.Type())
assert.Equal(t, ConfigFileLocationLocal, configFile.LocationType()) assert.Equal(t, ConfigFileLocationLocal, configFile.LocationType())
}) })
@@ -80,7 +85,7 @@ func TestParseConfigFile(t *testing.T) {
require.NoError(t, err) require.NoError(t, err)
require.NotNil(t, configFile) require.NotNil(t, configFile)
assert.Equal(t, "http://example.com/config.yaml", configFile.String()) assert.Equal(t, "http://example.com/config.yaml", configFile.Path())
assert.Equal(t, ConfigFileTypeYAML, configFile.Type()) assert.Equal(t, ConfigFileTypeYAML, configFile.Type())
assert.Equal(t, ConfigFileLocationRemote, configFile.LocationType()) assert.Equal(t, ConfigFileLocationRemote, configFile.LocationType())
}) })
@@ -90,7 +95,7 @@ func TestParseConfigFile(t *testing.T) {
require.NoError(t, err) require.NoError(t, err)
require.NotNil(t, configFile) require.NotNil(t, configFile)
assert.Equal(t, "https://example.com/path/config.yml", configFile.String()) assert.Equal(t, "https://example.com/path/config.yml", configFile.Path())
assert.Equal(t, ConfigFileTypeYAML, configFile.Type()) assert.Equal(t, ConfigFileTypeYAML, configFile.Type())
assert.Equal(t, ConfigFileLocationRemote, configFile.LocationType()) assert.Equal(t, ConfigFileLocationRemote, configFile.LocationType())
}) })
@@ -100,26 +105,29 @@ func TestParseConfigFile(t *testing.T) {
require.NoError(t, err) require.NoError(t, err)
require.NotNil(t, configFile) require.NotNil(t, configFile)
assert.Equal(t, "/path/to/config.yaml", configFile.String()) assert.Equal(t, "/path/to/config.yaml", configFile.Path())
assert.Equal(t, ConfigFileTypeYAML, configFile.Type()) assert.Equal(t, ConfigFileTypeYAML, configFile.Type())
assert.Equal(t, ConfigFileLocationLocal, configFile.LocationType()) assert.Equal(t, ConfigFileLocationLocal, configFile.LocationType())
}) })
t.Run("Parse file without extension returns error", func(t *testing.T) { t.Run("Parse file without extension returns unknown type", func(t *testing.T) {
configFile, err := ParseConfigFile("config") configFile, err := ParseConfigFile("config")
require.Error(t, err) require.NoError(t, err)
assert.Equal(t, ErrConfigFileExtensionNotFound, err) require.NotNil(t, configFile)
assert.Nil(t, configFile) assert.Equal(t, "config", configFile.Path())
assert.Equal(t, ConfigFileTypeUnknown, configFile.Type())
assert.Equal(t, ConfigFileLocationLocal, configFile.LocationType())
}) })
t.Run("Parse file with unsupported extension returns error", func(t *testing.T) { t.Run("Parse file with unsupported extension returns unknown type", func(t *testing.T) {
configFile, err := ParseConfigFile("config.json") configFile, err := ParseConfigFile("config.json")
require.Error(t, err) require.NoError(t, err)
assert.IsType(t, UnknownConfigFileTypeError{}, err) require.NotNil(t, configFile)
assert.Contains(t, err.Error(), "json") assert.Equal(t, "config.json", configFile.Path())
assert.Nil(t, configFile) assert.Equal(t, ConfigFileTypeUnknown, configFile.Type())
assert.Equal(t, ConfigFileLocationLocal, configFile.LocationType())
}) })
t.Run("Parse remote file with invalid URL returns error", func(t *testing.T) { t.Run("Parse remote file with invalid URL returns error", func(t *testing.T) {
@@ -130,29 +138,34 @@ func TestParseConfigFile(t *testing.T) {
assert.Nil(t, configFile) assert.Nil(t, configFile)
}) })
t.Run("Parse remote file without extension returns error", func(t *testing.T) { t.Run("Parse remote file without extension returns unknown type", func(t *testing.T) {
configFile, err := ParseConfigFile("https://example.com/config") configFile, err := ParseConfigFile("https://example.com/config")
require.Error(t, err) require.NoError(t, err)
assert.Equal(t, ErrConfigFileExtensionNotFound, err) require.NotNil(t, configFile)
assert.Nil(t, configFile) assert.Equal(t, "https://example.com/config", configFile.Path())
assert.Equal(t, ConfigFileTypeUnknown, configFile.Type())
assert.Equal(t, ConfigFileLocationRemote, configFile.LocationType())
}) })
t.Run("Parse remote file with unsupported extension returns error", func(t *testing.T) { t.Run("Parse remote file with unsupported extension returns unknown type", func(t *testing.T) {
configFile, err := ParseConfigFile("https://example.com/config.txt") configFile, err := ParseConfigFile("https://example.com/config.txt")
require.Error(t, err) require.NoError(t, err)
assert.IsType(t, UnknownConfigFileTypeError{}, err) require.NotNil(t, configFile)
assert.Contains(t, err.Error(), "txt") assert.Equal(t, "https://example.com/config.txt", configFile.Path())
assert.Nil(t, configFile) assert.Equal(t, ConfigFileTypeUnknown, configFile.Type())
assert.Equal(t, ConfigFileLocationRemote, configFile.LocationType())
}) })
t.Run("Parse empty string returns error", func(t *testing.T) { t.Run("Parse empty string returns unknown type", func(t *testing.T) {
configFile, err := ParseConfigFile("") configFile, err := ParseConfigFile("")
require.Error(t, err) require.NoError(t, err)
assert.Equal(t, ErrConfigFileExtensionNotFound, err) require.NotNil(t, configFile)
assert.Nil(t, configFile) assert.Empty(t, configFile.Path())
assert.Equal(t, ConfigFileTypeUnknown, configFile.Type())
assert.Equal(t, ConfigFileLocationLocal, configFile.LocationType())
}) })
t.Run("Parse file with multiple dots in name", func(t *testing.T) { t.Run("Parse file with multiple dots in name", func(t *testing.T) {
@@ -160,7 +173,7 @@ func TestParseConfigFile(t *testing.T) {
require.NoError(t, err) require.NoError(t, err)
require.NotNil(t, configFile) require.NotNil(t, configFile)
assert.Equal(t, "config.test.yaml", configFile.String()) assert.Equal(t, "config.test.yaml", configFile.Path())
assert.Equal(t, ConfigFileTypeYAML, configFile.Type()) assert.Equal(t, ConfigFileTypeYAML, configFile.Type())
assert.Equal(t, ConfigFileLocationLocal, configFile.LocationType()) assert.Equal(t, ConfigFileLocationLocal, configFile.LocationType())
}) })
@@ -170,7 +183,7 @@ func TestParseConfigFile(t *testing.T) {
require.NoError(t, err) require.NoError(t, err)
require.NotNil(t, configFile) require.NotNil(t, configFile)
assert.Equal(t, "https://example.com/path/config.yaml?version=1&format=yaml#section", configFile.String()) assert.Equal(t, "https://example.com/path/config.yaml?version=1&format=yaml#section", configFile.Path())
assert.Equal(t, ConfigFileTypeYAML, configFile.Type()) assert.Equal(t, ConfigFileTypeYAML, configFile.Type())
assert.Equal(t, ConfigFileLocationRemote, configFile.LocationType()) assert.Equal(t, ConfigFileLocationRemote, configFile.LocationType())
}) })
@@ -180,7 +193,7 @@ func TestParseConfigFile(t *testing.T) {
require.NoError(t, err) require.NoError(t, err)
require.NotNil(t, configFile) require.NotNil(t, configFile)
assert.Equal(t, "https://example.com:8080/config.yml", configFile.String()) assert.Equal(t, "https://example.com:8080/config.yml", configFile.Path())
assert.Equal(t, ConfigFileTypeYAML, configFile.Type()) assert.Equal(t, ConfigFileTypeYAML, configFile.Type())
assert.Equal(t, ConfigFileLocationRemote, configFile.LocationType()) assert.Equal(t, ConfigFileLocationRemote, configFile.LocationType())
}) })

View File

@@ -13,9 +13,6 @@ var (
// CLI // CLI
ErrCLINoArgs = errors.New("CLI expects arguments but received none") ErrCLINoArgs = errors.New("CLI expects arguments but received none")
ErrCLIUnexpectedArgs = errors.New("CLI received unexpected arguments") ErrCLIUnexpectedArgs = errors.New("CLI received unexpected arguments")
// Config File
ErrConfigFileExtensionNotFound = errors.New("config file extension not found")
) )
// ======================================== General ======================================== // ======================================== General ========================================
@@ -101,14 +98,21 @@ func (e RemoteConfigFileParseError) Unwrap() error {
return e.error return e.error
} }
type UnknownConfigFileTypeError struct { type ConfigFileReadError struct {
Type string error error
} }
func NewUnknownConfigFileTypeError(_type string) UnknownConfigFileTypeError { func NewConfigFileReadError(err error) ConfigFileReadError {
return UnknownConfigFileTypeError{_type} if err == nil {
err = ErrNoError
}
return ConfigFileReadError{err}
} }
func (e UnknownConfigFileTypeError) Error() string { func (e ConfigFileReadError) Error() string {
return "Unknown config file type: " + e.Type return "Config file read error: " + e.error.Error()
}
func (e ConfigFileReadError) Unwrap() error {
return e.error
} }

View File

@@ -205,37 +205,6 @@ func TestNewRemoteConfigFileParseError(t *testing.T) {
}) })
} }
func TestUnknownConfigFileTypeError_Error(t *testing.T) {
t.Run("Error returns formatted message", func(t *testing.T) {
err := NewUnknownConfigFileTypeError("json")
expected := "Unknown config file type: json"
assert.Equal(t, expected, err.Error())
})
t.Run("Error with empty type", func(t *testing.T) {
err := NewUnknownConfigFileTypeError("")
expected := "Unknown config file type: "
assert.Equal(t, expected, err.Error())
})
t.Run("Error with special characters in type", func(t *testing.T) {
err := NewUnknownConfigFileTypeError("type.with.dots")
expected := "Unknown config file type: type.with.dots"
assert.Equal(t, expected, err.Error())
})
}
func TestNewUnknownConfigFileTypeError(t *testing.T) {
t.Run("Creates UnknownConfigFileTypeError with correct values", func(t *testing.T) {
err := NewUnknownConfigFileTypeError("xml")
assert.Equal(t, "xml", err.Type)
})
}
func TestErrorConstants(t *testing.T) { func TestErrorConstants(t *testing.T) {
t.Run("ErrNoError has correct message", func(t *testing.T) { t.Run("ErrNoError has correct message", func(t *testing.T) {
expected := "no error (internal)" expected := "no error (internal)"
@@ -251,11 +220,6 @@ func TestErrorConstants(t *testing.T) {
expected := "CLI received unexpected arguments" expected := "CLI received unexpected arguments"
assert.Equal(t, expected, ErrCLIUnexpectedArgs.Error()) assert.Equal(t, expected, ErrCLIUnexpectedArgs.Error())
}) })
t.Run("ErrConfigFileExtensionNotFound has correct message", func(t *testing.T) {
expected := "config file extension not found"
assert.Equal(t, expected, ErrConfigFileExtensionNotFound.Error())
})
} }
func TestErrorImplementsErrorInterface(t *testing.T) { func TestErrorImplementsErrorInterface(t *testing.T) {
@@ -278,9 +242,4 @@ func TestErrorImplementsErrorInterface(t *testing.T) {
var err error = NewRemoteConfigFileParseError(errors.New("test")) var err error = NewRemoteConfigFileParseError(errors.New("test"))
assert.Error(t, err) assert.Error(t, err)
}) })
t.Run("UnknownConfigFileTypeError implements error interface", func(t *testing.T) {
var err error = NewUnknownConfigFileTypeError("test")
assert.Error(t, err)
})
} }