diff --git a/.env b/.env new file mode 100644 index 0000000..a38d23d --- /dev/null +++ b/.env @@ -0,0 +1,4 @@ +#This is a comment 1 +#This is a comment 2 +#This is a comment 3 +#This is a comment 4 \ No newline at end of file diff --git a/go.sum b/go.sum new file mode 100644 index 0000000..e20fa14 --- /dev/null +++ b/go.sum @@ -0,0 +1,9 @@ +github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= +github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= +github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg= +github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= +gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= diff --git a/pkg/dotenv.go b/pkg/dotenv.go index 9128659..7abfe29 100644 --- a/pkg/dotenv.go +++ b/pkg/dotenv.go @@ -3,8 +3,8 @@ package dotenv import ( "errors" + "fmt" "os" - "reflect" "strings" ) @@ -22,11 +22,17 @@ type EnvContent struct { // LoadFromString loads the content of .env file from multi-lined string. func (env *EnvContent) LoadFromString(envContents string) (map[string]string, error) { + env.keyValuePairs = make(map[string]string) + return env.loadFromString(envContents) +} + +func (env *EnvContent) loadFromString(envContents string) (map[string]string, error) { lines := strings.Split(envContents, "\n") for _, line := range lines { + line = strings.TrimSpace(line) if len(line) == 0 { continue } else if string(line[0]) == "#" { @@ -46,6 +52,11 @@ func (env *EnvContent) LoadFromString(envContents string) (map[string]string, er } } + emptyMap := make(map[string]string) + if fmt.Sprint(emptyMap) == fmt.Sprint(env.keyValuePairs) { + return emptyMap, errFileIsEmpty + } + return env.keyValuePairs, nil } @@ -63,13 +74,13 @@ func (env *EnvContent) LoadFromFile(fileName string) (map[string]string, error) return emptyMap, errReadingFile } - _, err = env.LoadFromString(string(fileContent)) + _, err = env.loadFromString(string(fileContent)) if err != nil { return emptyMap, err } - if reflect.DeepEqual(env.keyValuePairs, emptyMap) { + if fmt.Sprint(emptyMap) == fmt.Sprint(env.keyValuePairs) { return emptyMap, errFileIsEmpty } @@ -93,10 +104,10 @@ func (env *EnvContent) LoadFromFiles(fileNames []string) (map[string]string, err continue } - _, err = env.LoadFromString(string(fileContent)) + _, err = env.loadFromString(string(fileContent)) } - if reflect.DeepEqual(env.keyValuePairs, emptyMap) { + if fmt.Sprint(emptyMap) == fmt.Sprint(env.keyValuePairs) { return emptyMap, errFileIsEmpty } return env.keyValuePairs, err diff --git a/pkg/dotenv_test.go b/pkg/dotenv_test.go index b082e38..8d30d6c 100644 --- a/pkg/dotenv_test.go +++ b/pkg/dotenv_test.go @@ -29,19 +29,20 @@ type LoadFromFilesTestCase struct { } type GetEnvTestCase struct { - desc string - inputOutputMap map[string]string + desc string + input string + expectedMap map[string]string } type GetTestCase struct { desc string - inputMap map[string]string + input string key string value string expectedError error } -func TestINI_LoadFromString(t *testing.T) { +func TestENV_LoadFromString(t *testing.T) { parser := EnvContent{} emptyMap := make(map[string]string) testCases := []LoadFromStringTestCase{ @@ -281,15 +282,15 @@ func TestINI_LoadFromString(t *testing.T) { { desc: "Normal test case 5", input: "\n\n\n\n" + - "#comment 1" + + "#comment 1\n" + "key1:value1\n " + "key2:value2\n" + "\n\n\n\n" + - "#Comment 2" + + "#Comment 2\n" + "key3=value3\n" + - "key4=value4" + - "#comment 3" + - "#comment 4" + + "key4=value4\n" + + "#comment 3\n" + + "#comment 4\n" + "\n\n\n\n", expectedError: nil, expectedMap: map[string]string{ @@ -315,7 +316,7 @@ func TestINI_LoadFromString(t *testing.T) { } -func TestINI_loadFromFile(t *testing.T) { +func TestENV_LoadFromFile(t *testing.T) { parser := EnvContent{} emptyMap := make(map[string]string) testCases := []LoadFromFileTestCase{ @@ -389,7 +390,7 @@ func TestINI_loadFromFile(t *testing.T) { }, { desc: "Only keys = values as input with spaces", - path: "testdata/test_9.txt", + path: "testdata/test_09.txt", expectedError: nil, expectedMap: map[string]string{ "key1": "value1", @@ -528,3 +529,203 @@ func TestINI_loadFromFile(t *testing.T) { }) } } + +func TestENV_GetEnv(t *testing.T) { + parser := EnvContent{} + emptyMap := make(map[string]string) + testCases := []GetEnvTestCase{ + { + desc: "Empty Map", + input: "", + expectedMap: emptyMap, + }, + { + desc: "Only one key = value", + input: "key=value", + expectedMap: map[string]string{ + "key": "value", + }, + }, + { + desc: "Normal test case 1", + input: "key1:value1\n " + + "key2:value2\n" + + "key3:value3\n" + + "key4:value4", + expectedMap: map[string]string{ + "key1": "value1", + "key2": "value2", + "key3": "value3", + "key4": "value4", + }, + }, + { + desc: "Normal test case 2", + input: "key1:value1\n " + + "key2:value2\n" + + "key3:value3\n" + + "key4:value4\n" + + "key5:value5\n" + + "key6:value6", + expectedMap: map[string]string{ + "key1": "value1", + "key2": "value2", + "key3": "value3", + "key4": "value4", + "key5": "value5", + "key6": "value6", + }, + }, + { + desc: "Normal test case 3", + input: "key1:value1\n " + + "key2:value2\n" + + "key3:value3\n" + + "key4:value4\n" + + "key5:value5\n" + + "key6:value6\n" + + "key7:value7\n" + + "key8:value8", + expectedMap: map[string]string{ + "key1": "value1", + "key2": "value2", + "key3": "value3", + "key4": "value4", + "key5": "value5", + "key6": "value6", + "key7": "value7", + "key8": "value8", + }, + }, + { + desc: "Normal test case 4", + input: "key1:value1\n " + + "key2:value2\n" + + "key3:value3", + expectedMap: map[string]string{ + "key1": "value1", + "key2": "value2", + "key3": "value3", + }, + }, + { + desc: "Normal test case 5", + input: "key1:value1\n " + + "key2:value2\n" + + "key3:value3\n" + + "key4:value4\n" + + "key5:value5\n" + + "key6:value6\n" + + "key7:value7\n" + + "key8:value8\n" + + "key9:value9\n" + + "key10:value10", + expectedMap: map[string]string{ + "key1": "value1", + "key2": "value2", + "key3": "value3", + "key4": "value4", + "key5": "value5", + "key6": "value6", + "key7": "value7", + "key8": "value8", + "key9": "value9", + "key10": "value10", + }, + }, + } + + for _, test := range testCases { + t.Run(test.desc, func(t *testing.T) { + + _: + parser.LoadFromString(test.input) + resultedMap := parser.GetEnv() + + if !reflect.DeepEqual(test.expectedMap, resultedMap) { + t.Fail() + } + + }) + } +} + +func TestINI_Get(t *testing.T) { + parser := EnvContent{} + testCases := []GetTestCase{ + { + desc: "Empty map as input", + input: "", + key: "key1", + value: "", + expectedError: errMissingValue, + }, + { + desc: "Normal case 1", + input: "key1:value1", + key: "key1", + value: "value1", + expectedError: nil, + }, + { + desc: "Normal case 2", + input: "key1:value1\n " + + "key2:value2\n" + + "key3:value3\n" + + "key4:value4\n" + + "key5:value5\n" + + "key6:value6\n" + + "key7:value7\n" + + "key8:value8\n" + + "key9:value9\n" + + "key10:value10", + key: "key2", + value: "value2", + expectedError: nil, + }, + { + desc: "Normal case 3", + input: "key1:value1\n " + + "key2:value2\n" + + "key3:value3\n" + + "key4:value4", + key: "key5", + value: "", + expectedError: errMissingValue, + }, + { + desc: "Normal case 4", + input: "key1:value1\n " + + "key2:value2\n" + + "key3:value3\n" + + "key4:value4\n" + + "key5:value5\n" + + "key6:value6\n" + + "key7:value7", + key: "key1", + value: "value1", + expectedError: nil, + }, + { + desc: "Normal case 5", + input: "key1:value1\n " + + "key2:value2\n" + + "key3:value3", + key: "key4", + value: "", + expectedError: errMissingValue, + }, + } + for _, test := range testCases { + t.Run(test.desc, func(t *testing.T) { + _, _ = parser.LoadFromString(test.input) + resultedValue, resultedError := parser.Get(test.key) + + assert.Equal(t, test.expectedError, resultedError) + if resultedValue != test.value { + t.Fail() + } + + }) + } +}