Skip to content

Commit

Permalink
added tests, fixed a bug, add MustLoad
Browse files Browse the repository at this point in the history
  • Loading branch information
rayjlinden committed Apr 11, 2019
1 parent 7a654f5 commit 5200d1e
Show file tree
Hide file tree
Showing 5 changed files with 183 additions and 14 deletions.
2 changes: 1 addition & 1 deletion Version
Original file line number Diff line number Diff line change
@@ -1 +1 @@
0.2.6
0.2.7
51 changes: 49 additions & 2 deletions file.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ const doubleQuoteSpecialChars = "\\\n\r\"!$`"
//
// You can otherwise tell it which files to load (there can be more than one) like
//
// env.Load("fileone", "filetwo")
// err := env.Load("fileone", "filetwo")
//
// It's important to note that it WILL NOT OVERRIDE an env variable that already exists - consider the .env file to set dev vars or sensible defaults
func Load(filenames ...string) (err error) {
Expand All @@ -36,6 +36,30 @@ func Load(filenames ...string) (err error) {
return
}

// MustLoad will read your env file(s) and load them into ENV for this process.
//
// Call this function as close as possible to the start of your program (ideally in main)
//
// If you call Load without any args it will default to loading .env in the current path.
// If there are any errors the function will panic.
//
// You can otherwise tell it which files to load (there can be more than one) like
//
// env.MustLoad("fileone", "filetwo")
//
// It's important to note that it WILL NOT OVERRIDE an env variable that already exists - consider the .env file to set dev vars or sensible defaults
func MustLoad(filenames ...string) {
filenames = filenamesOrDefault(filenames)

for _, filename := range filenames {
err := loadFile(filename, false)
if err != nil {
panic(err)
}
}
return
}

// Overload will read your env file(s) and load them into ENV for this process.
//
// Call this function as close as possible to the start of your program (ideally in main)
Expand All @@ -44,7 +68,7 @@ func Load(filenames ...string) (err error) {
//
// You can otherwise tell it which files to load (there can be more than one) like
//
// env.Overload("fileone", "filetwo")
// err := env.Overload("fileone", "filetwo")
//
// It's important to note this WILL OVERRIDE an env variable that already exists - consider the .env file to forcefilly set all vars.
func Overload(filenames ...string) (err error) {
Expand All @@ -59,6 +83,29 @@ func Overload(filenames ...string) (err error) {
return
}

// MustOverload will read your env file(s) and load them into ENV for this process.
//
// Call this function as close as possible to the start of your program (ideally in main)
//
// If you call Overload without any args it will default to loading .env in the current path
//
// You can otherwise tell it which files to load (there can be more than one) like
//
// env.MustOverload("fileone", "filetwo")
//
// It's important to note this WILL OVERRIDE an env variable that already exists - consider the .env file to forcefilly set all vars.
func MustOverload(filenames ...string) {
filenames = filenamesOrDefault(filenames)

for _, filename := range filenames {
err := loadFile(filename, true)
if err != nil {
panic(err)
}
}
return
}

// Read all env (with same file loading semantics as Load) but return values as
// a map rather than automatically writing values into env
func Read(filenames ...string) (envMap map[string]string, err error) {
Expand Down
6 changes: 6 additions & 0 deletions file_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ import (
"reflect"
"strings"
"testing"

"github.com/stretchr/testify/assert"
)

var noopPresets = make(map[string]string)
Expand Down Expand Up @@ -61,13 +63,17 @@ func TestLoadFileNotFound(t *testing.T) {
if err == nil {
t.Error("File wasn't found but Load didn't return an error")
}

assert.Panics(t, func() { MustLoad("somefilethatwillneverexistever.env") }, "The code did not panic")
}

func TestOverloadFileNotFound(t *testing.T) {
err := Overload("somefilethatwillneverexistever.env")
if err == nil {
t.Error("File wasn't found but Overload didn't return an error")
}

assert.Panics(t, func() { MustOverload("somefilethatwillneverexistever.env") }, "The code did not panic")
}

func TestReadPlainEnv(t *testing.T) {
Expand Down
22 changes: 11 additions & 11 deletions util.go
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ func GetOrBool(key string, defaultValue bool) bool {
strValue, ok := os.LookupEnv(key)
if ok {
value, err := strconv.ParseBool(strValue)
if err != nil {
if err == nil {
return value
}
}
Expand All @@ -61,7 +61,7 @@ func MustGetBool(key string) bool {
strValue, ok := os.LookupEnv(key)
if ok {
value, err := strconv.ParseBool(strValue)
if err != nil {
if err == nil {
return value
} else {
panic(fmt.Sprintf("environment variable \"%s\" could not be convert to boolean", key))
Expand All @@ -81,7 +81,7 @@ func GetOrInt(key string, defaultValue int) int {
strValue, ok := os.LookupEnv(key)
if ok {
value, err := strconv.ParseInt(strValue, 10, 32)
if err != nil {
if err == nil {
return int(value)
}
}
Expand All @@ -93,7 +93,7 @@ func MustGetInt(key string) int {
strValue, ok := os.LookupEnv(key)
if ok {
value, err := strconv.ParseInt(strValue, 10, 32)
if err != nil {
if err == nil {
return int(value)
} else {
panic(fmt.Sprintf("environment variable \"%s\" could not be convert to int", key))
Expand All @@ -113,7 +113,7 @@ func GetOrUint(key string, defaultValue uint) uint {
strValue, ok := os.LookupEnv(key)
if ok {
value, err := strconv.ParseUint(strValue, 10, 32)
if err != nil {
if err == nil {
return uint(value)
}
}
Expand All @@ -125,7 +125,7 @@ func MustGetUint(key string) uint {
strValue, ok := os.LookupEnv(key)
if ok {
value, err := strconv.ParseUint(strValue, 10, 32)
if err != nil {
if err == nil {
return uint(value)
} else {
panic(fmt.Sprintf("environment variable \"%s\" could not be convert to uint", key))
Expand All @@ -135,29 +135,29 @@ func MustGetUint(key string) uint {
}

// GetFloat - get an environment variable as float32
func GetFloat(key string) (float32, error) {
func GetFloat32(key string) (float32, error) {
value, err := strconv.ParseFloat(os.Getenv(key), 32)
return float32(value), err
}

// GetOrFloat - get an environment variable or return default value if does not exist
func GetOrFloat(key string, defaultValue float32) float32 {
func GetOrFloat32(key string, defaultValue float32) float32 {
strValue, ok := os.LookupEnv(key)
if ok {
value, err := strconv.ParseFloat(strValue, 32)
if err != nil {
if err == nil {
return float32(value)
}
}
return defaultValue
}

// MustGetUFloat - get an environment variable or panic if does not exist
func MustGetFloat(key string) float32 {
func MustGetFloat32(key string) float32 {
strValue, ok := os.LookupEnv(key)
if ok {
value, err := strconv.ParseFloat(strValue, 32)
if err != nil {
if err == nil {
return float32(value)
} else {
panic(fmt.Sprintf("environment variable \"%s\" could not be convert to float32", key))
Expand Down
116 changes: 116 additions & 0 deletions util_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,116 @@
package env

import (
"testing"
"os"

"github.com/stretchr/testify/assert"
)

func TestBoolFuncs(t *testing.T) {
os.Setenv("BOOL_ENV", "1")

// env exists
val, err := GetBool("BOOL_ENV")
assert.Equal(t, true, val)
assert.Nil(t, err)
assert.Equal(t, true, MustGetBool("BOOL_ENV"))
assert.Equal(t, true, GetOrBool("BOOL_ENV", false))

// env not exists
val, err = GetBool("ENV_NO_EXISTS")
assert.Equal(t, false, val)
assert.Error(t, err)
assert.Equal(t, true, GetOrBool("ENV_NO_EXISTS", true))
assert.Panics(t, func() { MustGetBool("ENV_NO_EXISTS") }, "The code did not panic")

// env bad format
os.Setenv("BAD_BOOL", "bad_bool")

val, err = GetBool("BAD_BOOL")
assert.Equal(t, false, val)
assert.Error(t, err)
assert.Equal(t, true, GetOrBool("BAD_BOOL", true))
assert.Panics(t, func() { MustGetBool("BAD_BOOL") }, "The code did not panic")
}

func TestIntFuncs(t *testing.T) {
os.Setenv("INT_ENV", "-34")

// env exists
val, err := GetInt("INT_ENV")
assert.Equal(t, -34, val)
assert.Nil(t, err)
assert.Equal(t, -34, MustGetInt("INT_ENV"))
assert.Equal(t, -34, GetOrInt("INT_ENV", 99))

// env not exists
val, err = GetInt("ENV_NO_EXISTS")
assert.Equal(t, 0, val)
assert.Error(t, err)
assert.Equal(t, 99, GetOrInt("ENV_NO_EXISTS", 99))
assert.Panics(t, func() { MustGetInt("ENV_NO_EXISTS") }, "The code did not panic")

// env bad format
os.Setenv("BAD_INT", "bad_int")

val, err = GetInt("BAD_INT")
assert.Equal(t, 0, val)
assert.Error(t, err)
assert.Equal(t, 99, GetOrInt("BAD_INT", 99))
assert.Panics(t, func() { MustGetInt("BAD_INT") }, "The code did not panic")
}

func TestUintFuncs(t *testing.T) {
os.Setenv("UINT_ENV", "106")

// env exists
val, err := GetUint("UINT_ENV")
assert.Equal(t, uint(106), val)
assert.Nil(t, err)
assert.Equal(t, uint(106), MustGetUint("UINT_ENV"))
assert.Equal(t, uint(106), GetOrUint("UINT_ENV", 99))

// env not exists
val, err = GetUint("ENV_NO_EXISTS")
assert.Equal(t, uint(0), val)
assert.Error(t, err)
assert.Equal(t, uint(99), GetOrUint("ENV_NO_EXISTS", 99))
assert.Panics(t, func() { MustGetUint("ENV_NO_EXISTS") }, "The code did not panic")

// env bad format
os.Setenv("BAD_UINT", "-10")

val, err = GetUint("BAD_UINT")
assert.Equal(t, uint(0), val)
assert.Error(t, err)
assert.Equal(t, uint(99), GetOrUint("BAD_UINT", 99))
assert.Panics(t, func() { MustGetUint("BAD_UINT") }, "The code did not panic")
}

func TestFloatFuncs(t *testing.T) {
os.Setenv("FLOAT_ENV", "12.34")

// env exists
val, err := GetFloat32("FLOAT_ENV")
assert.Equal(t, float32(12.34), val)
assert.Nil(t, err)
assert.Equal(t, float32(12.34), MustGetFloat32("FLOAT_ENV"))
assert.Equal(t, float32(12.34), GetOrFloat32("FLOAT_ENV", 66.6))

// env not exists
val, err = GetFloat32("ENV_NO_EXISTS")
assert.Equal(t, float32(0), val)
assert.Error(t, err)
assert.Equal(t, float32(66.6), GetOrFloat32("ENV_NO_EXISTS", 66.6))
assert.Panics(t, func() { MustGetFloat32("ENV_NO_EXISTS") }, "The code did not panic")

// env bad format
os.Setenv("BAD_FLOAT", "bad_float")

val, err = GetFloat32("BAD_FLOAT")
assert.Equal(t, float32(0), val)
assert.Error(t, err)
assert.Equal(t, float32(1.23), GetOrFloat32("BAD_FLOAT", 1.23))
assert.Panics(t, func() { MustGetFloat32("BAD_FLOAT") }, "The code did not panic")
}

0 comments on commit 5200d1e

Please sign in to comment.