Restructure the code a bit.
Add a more complete wrapper function called Configure and ConfigureWithDefaults. Add ability to write a configmap back to a new file. Changed my mind about multiple equals signs because some data like base64 uses equals signs. Added more tests. Bump to version 0.1.0 to signal closer to completeness/stability. Changed domain name from gitea.wisellama.rocks to git.wisellama.rocks.main v0.1.0
parent
5cc5aa419e
commit
4481060613
3
Makefile
3
Makefile
|
@ -1,8 +1,9 @@
|
|||
all: linter test
|
||||
|
||||
test:
|
||||
go test ./
|
||||
go test
|
||||
|
||||
lint: linter
|
||||
linter:
|
||||
golangci-lint run
|
||||
|
||||
|
|
60
Readme.md
60
Readme.md
|
@ -1,16 +1,18 @@
|
|||
# gosimpleconf
|
||||
|
||||
```sh
|
||||
go get gitea.wisellama.rocks/Wisellama/gosimpleconf@v0.0.4
|
||||
go get git.wisellama.rocks/Wisellama/gosimpleconf@v0.1.0
|
||||
```
|
||||
|
||||
This is a small library for parsing super simple configuration files.
|
||||
This is a small library for parsing super simple configuration files
|
||||
similar to Unix conf files.
|
||||
|
||||
It expects a file with the following format:
|
||||
* Lines with key-values pairs separated by `=` (e.g. `foo = bar`)
|
||||
* Lines that start with `#` are ignored (used for comments)
|
||||
* Empty and whitespace-only lines are ignore
|
||||
* Lines with data that don't have an `=` will cause an error.
|
||||
* Empty and whitespace-only lines are ignored
|
||||
* Lines with some data but no `=` will cause an error.
|
||||
* Lines with multiple `=` are split on the literal first `=` seen, any remaining are part of the value.
|
||||
|
||||
The key-values pairs are simply parsed as strings and plopped into a
|
||||
map for you to do whatever your program wants with them. If you need a
|
||||
|
@ -25,15 +27,21 @@ url = www.wisellama.rocks
|
|||
number_of_widgets = 1337
|
||||
pi = 3.141592653589793238462643383
|
||||
environment = production
|
||||
|
||||
# Quotes are optional
|
||||
name = Dude guy
|
||||
description = "Just some dude it was"
|
||||
|
||||
# Additional equals are just part of the value
|
||||
base64_tacos = dGFjb3M=
|
||||
a=b=c
|
||||
# key: 'a', value: 'b=c'
|
||||
```
|
||||
|
||||
Then to load that config file into a map:
|
||||
|
||||
```go
|
||||
configMap, err := gosimpleconf.Load("file.conf")
|
||||
configMap, err := gosimpleconf.Configure("file.conf")
|
||||
```
|
||||
|
||||
Then everything is a string. You can parse it as needed.
|
||||
|
@ -42,19 +50,43 @@ var piStr string = configMap["pi"]
|
|||
pi, err := strconv.ParseFloat(value, 64)
|
||||
```
|
||||
|
||||
To override values with cli flags, after parsing the conf file you can
|
||||
use these functions to also parse the flags:
|
||||
```go
|
||||
flagMap := SetupFlagOverrides(configMap)
|
||||
configMap = ParseFlags(configMap, flagmap)
|
||||
```
|
||||
### Command-Line Flag Overrides
|
||||
|
||||
Then you could, for example, override the url value without modifying
|
||||
the config file:
|
||||
```go
|
||||
By default, the `Configure()` function will figure out which keys
|
||||
exist in the config map and set those as cli flags that you can
|
||||
override. For example, with the config file above, you could override
|
||||
the `url` key with a cli flag:
|
||||
```sh
|
||||
./program --url=newthing.wisellama.rocks
|
||||
```
|
||||
|
||||
If you don't want to support cli flag overrides, you can directly call
|
||||
`ReadFile("file.conf")` instead.
|
||||
|
||||
If you want to support other cli flags that don't map to a config
|
||||
setting, they must be set up before calling `Configure()`. This is
|
||||
because the `ParseFlags()` function calls `flag.Parse()` to get all
|
||||
the values for the config map overrides. You could also work around
|
||||
this by calling `ReadFile` and `ParseFlags` yourself and add your
|
||||
other logic in between the two calls.
|
||||
|
||||
### Default Config
|
||||
|
||||
You can specify a default configuration to return if the given config
|
||||
file doesn't exist. Here's an example:
|
||||
|
||||
```go
|
||||
defaultConfig := gosimpleconf.ConfigMap{
|
||||
"game.title": "Some Game",
|
||||
"log.writeToFile": "false",
|
||||
}
|
||||
configMap, err := gosimpleconf.ConfigureWithDefaults("file_that_doesnt_exist.conf", defaultConfig)
|
||||
```
|
||||
|
||||
Then if the config file can't be found, the default config map values
|
||||
will be used instead. You can still override the default values with
|
||||
cli flags.
|
||||
|
||||
## Why?
|
||||
|
||||
I've always seen configuration files similar to this show up in
|
||||
|
|
|
@ -0,0 +1,95 @@
|
|||
package gosimpleconf
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"fmt"
|
||||
"io"
|
||||
"os"
|
||||
"strings"
|
||||
)
|
||||
|
||||
type ConfigMap map[string]string
|
||||
|
||||
func Load(filename string) (ConfigMap, error) {
|
||||
return ReadFile(filename)
|
||||
}
|
||||
|
||||
func ReadFile(filename string) (ConfigMap, error) {
|
||||
var err error
|
||||
|
||||
file, err := os.Open(filename)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer file.Close()
|
||||
|
||||
parsedMap, err := parseFile(file)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return parsedMap, nil
|
||||
}
|
||||
|
||||
func WriteFile(filename string, configMap ConfigMap) error {
|
||||
file, err := os.Create(filename)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer file.Close()
|
||||
|
||||
for k, v := range configMap {
|
||||
fmt.Fprintf(file, "%s = %s\n", k, v)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func parseFile(config io.Reader) (ConfigMap, error) {
|
||||
var err error
|
||||
parsedMap := make(ConfigMap)
|
||||
|
||||
scanner := bufio.NewScanner(config)
|
||||
for scanner.Scan() {
|
||||
line := scanner.Text()
|
||||
trimmed := strings.TrimSpace(line)
|
||||
if len(trimmed) == 0 {
|
||||
// ignore empty lines
|
||||
continue
|
||||
}
|
||||
|
||||
if trimmed[0] == '#' {
|
||||
// ignore comments
|
||||
continue
|
||||
}
|
||||
|
||||
split := strings.Split(trimmed, "=")
|
||||
if len(split) < 2 {
|
||||
return nil, fmt.Errorf("failed to parse config line: %v", trimmed)
|
||||
}
|
||||
|
||||
key := trimToken(split[0])
|
||||
|
||||
value := strings.Join(split[1:], "=") // Re-add any ='s that were part of the value
|
||||
value = trimToken(value)
|
||||
|
||||
parsedMap[key] = value
|
||||
}
|
||||
|
||||
if err = scanner.Err(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return parsedMap, nil
|
||||
}
|
||||
|
||||
func trimToken(value string) string {
|
||||
// Trim off whitespace
|
||||
v := strings.TrimSpace(value)
|
||||
|
||||
// Trim off any surrounding quotes, everything is a string anyway
|
||||
v = strings.TrimPrefix(v, "\"")
|
||||
v = strings.TrimSuffix(v, "\"")
|
||||
|
||||
return v
|
||||
}
|
|
@ -0,0 +1,104 @@
|
|||
package gosimpleconf
|
||||
|
||||
import (
|
||||
"strings"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestParseWithValidConfig(t *testing.T) {
|
||||
var err error
|
||||
configFileStr := `
|
||||
# Some config file
|
||||
|
||||
foo=bar
|
||||
asdf = 1234
|
||||
|
||||
# Things
|
||||
wat.wat= thing
|
||||
foo.wat =stuff
|
||||
|
||||
immaempty=
|
||||
|
||||
technically valid = haha hmm...
|
||||
|
||||
#Done
|
||||
`
|
||||
configFile := strings.NewReader(configFileStr)
|
||||
|
||||
expectedMap := make(ConfigMap)
|
||||
expectedMap["foo"] = "bar"
|
||||
expectedMap["asdf"] = "1234"
|
||||
expectedMap["wat.wat"] = "thing"
|
||||
expectedMap["foo.wat"] = "stuff"
|
||||
expectedMap["immaempty"] = ""
|
||||
expectedMap["technically valid"] = "haha hmm..."
|
||||
|
||||
parsedMap, err := parseFile(configFile)
|
||||
if err != nil {
|
||||
t.Errorf("failed while parsing the file")
|
||||
}
|
||||
|
||||
validateMap(t, parsedMap, expectedMap)
|
||||
}
|
||||
|
||||
func TestParseWithNoEquals(t *testing.T) {
|
||||
var err error
|
||||
configFileStr := `
|
||||
Something here with no equals to split on
|
||||
`
|
||||
configFile := strings.NewReader(configFileStr)
|
||||
|
||||
_, err = parseFile(configFile)
|
||||
if err == nil {
|
||||
t.Errorf("parse did not thrown an error when it was supposed to")
|
||||
}
|
||||
}
|
||||
|
||||
func TestParseWithExtraQuotes(t *testing.T) {
|
||||
var err error
|
||||
configFileStr := `
|
||||
some.name = "This is in quotes"
|
||||
extra.quotes = ""This will keep the quotes""
|
||||
internal.quotes = "Some "thing" is here"
|
||||
"This should work too" = shrug I guess
|
||||
`
|
||||
|
||||
configFile := strings.NewReader(configFileStr)
|
||||
|
||||
expectedMap := make(ConfigMap)
|
||||
expectedMap["some.name"] = "This is in quotes"
|
||||
expectedMap["extra.quotes"] = "\"This will keep the quotes\""
|
||||
expectedMap["internal.quotes"] = "Some \"thing\" is here"
|
||||
expectedMap["This should work too"] = "shrug I guess"
|
||||
|
||||
configMap, err := parseFile(configFile)
|
||||
if err != nil {
|
||||
t.Errorf("failed while parsing the file")
|
||||
}
|
||||
|
||||
validateMap(t, configMap, expectedMap)
|
||||
}
|
||||
|
||||
func TestParseExtraEquals(t *testing.T) {
|
||||
configFileStr := `
|
||||
foo=bar=true
|
||||
base64_tacos = dGFjb3M=
|
||||
"equals=splits" the key/value, quotes and other =equals= don't matter
|
||||
yup=soup
|
||||
`
|
||||
|
||||
configFile := strings.NewReader(configFileStr)
|
||||
|
||||
expectedMap := make(ConfigMap)
|
||||
expectedMap["foo"] = "bar=true"
|
||||
expectedMap["base64_tacos"] = "dGFjb3M="
|
||||
expectedMap["equals"] = "splits\" the key/value, quotes and other =equals= don't matter"
|
||||
expectedMap["yup"] = "soup"
|
||||
|
||||
configMap, err := parseFile(configFile)
|
||||
if err != nil {
|
||||
t.Errorf("failed while parsing the file")
|
||||
}
|
||||
|
||||
validateMap(t, configMap, expectedMap)
|
||||
}
|
|
@ -0,0 +1,36 @@
|
|||
package gosimpleconf
|
||||
|
||||
import (
|
||||
"log"
|
||||
"strconv"
|
||||
)
|
||||
|
||||
func Bool(value string) bool {
|
||||
v, err := strconv.ParseBool(value)
|
||||
if err != nil {
|
||||
log.Printf("error parsing bool %v - %v\n", v, err)
|
||||
v = false
|
||||
}
|
||||
|
||||
return v
|
||||
}
|
||||
|
||||
func Int64(value string) int64 {
|
||||
v, err := strconv.ParseInt(value, 10, 64)
|
||||
if err != nil {
|
||||
log.Printf("error parsing int %v - %v\n", v, err)
|
||||
v = 0
|
||||
}
|
||||
|
||||
return v
|
||||
}
|
||||
|
||||
func Float64(value string) float64 {
|
||||
v, err := strconv.ParseFloat(value, 64)
|
||||
if err != nil {
|
||||
log.Printf("error parsing float %v - %v\n", v, err)
|
||||
v = 0.0
|
||||
}
|
||||
|
||||
return v
|
||||
}
|
|
@ -0,0 +1,28 @@
|
|||
package gosimpleconf
|
||||
|
||||
import "flag"
|
||||
|
||||
type FlagMap map[string]*string
|
||||
|
||||
func SetupFlagOverrides(configMap ConfigMap) FlagMap {
|
||||
flagMap := make(FlagMap)
|
||||
for k, v := range configMap {
|
||||
f := flag.String(k, v, "")
|
||||
flagMap[k] = f
|
||||
}
|
||||
|
||||
return flagMap
|
||||
}
|
||||
|
||||
func ParseFlags(configMap ConfigMap, flagMap FlagMap) ConfigMap {
|
||||
flag.Parse()
|
||||
|
||||
for k, v := range flagMap {
|
||||
if v != nil && len(*v) > 0 {
|
||||
configMap[k] = trimToken(*v)
|
||||
}
|
||||
}
|
||||
|
||||
return configMap
|
||||
|
||||
}
|
|
@ -0,0 +1,41 @@
|
|||
package gosimpleconf
|
||||
|
||||
import (
|
||||
"flag"
|
||||
"strings"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestFlagOverrides(t *testing.T) {
|
||||
var err error
|
||||
configFileStr := `
|
||||
foo=bar
|
||||
asdf = 1234
|
||||
foo.wat =stuff
|
||||
immaempty=
|
||||
`
|
||||
configFile := strings.NewReader(configFileStr)
|
||||
|
||||
expectedMap := make(ConfigMap)
|
||||
expectedMap["foo"] = "bar"
|
||||
expectedMap["asdf"] = "1234"
|
||||
// expect to override the 'foo.wat' value with a cli flag
|
||||
expectedMap["foo.wat"] = "iwasoverridden"
|
||||
expectedMap["immaempty"] = ""
|
||||
|
||||
configMap, err := parseFile(configFile)
|
||||
if err != nil {
|
||||
t.Errorf("failed while parsing the file")
|
||||
}
|
||||
|
||||
flagMap := SetupFlagOverrides(configMap)
|
||||
|
||||
err = flag.Set("foo.wat", "iwasoverridden")
|
||||
if err != nil {
|
||||
t.Errorf("failed to set cli flag override")
|
||||
}
|
||||
|
||||
configMap = ParseFlags(configMap, flagMap)
|
||||
|
||||
validateMap(t, configMap, expectedMap)
|
||||
}
|
2
go.mod
2
go.mod
|
@ -1,3 +1,3 @@
|
|||
module gitea.wisellama.rocks/Wisellama/gosimpleconf
|
||||
module git.wisellama.rocks/Wisellama/gosimpleconf
|
||||
|
||||
go 1.17
|
||||
|
|
109
gosimpleconf.go
109
gosimpleconf.go
|
@ -1,112 +1,31 @@
|
|||
package gosimpleconf
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"flag"
|
||||
"fmt"
|
||||
"io"
|
||||
"log"
|
||||
"os"
|
||||
"strconv"
|
||||
"strings"
|
||||
)
|
||||
import "os"
|
||||
|
||||
type ConfigMap map[string]string
|
||||
type FlagMap map[string]*string
|
||||
|
||||
func Load(filename string) (ConfigMap, error) {
|
||||
func Configure(filename string) (ConfigMap, error) {
|
||||
var err error
|
||||
|
||||
file, err := os.Open(filename)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer file.Close()
|
||||
|
||||
parsedMap, err := parseFile(file)
|
||||
configMap, err := ReadFile(filename)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return parsedMap, nil
|
||||
flagMap := SetupFlagOverrides(configMap)
|
||||
configMap = ParseFlags(configMap, flagMap)
|
||||
|
||||
return configMap, nil
|
||||
}
|
||||
|
||||
func SetupFlagOverrides(configMap ConfigMap) FlagMap {
|
||||
flagMap := make(FlagMap)
|
||||
for k, v := range configMap {
|
||||
f := flag.String(k, v, "")
|
||||
flagMap[k] = f
|
||||
}
|
||||
|
||||
return flagMap
|
||||
}
|
||||
|
||||
func ParseFlags(configMap ConfigMap, flagMap FlagMap) ConfigMap {
|
||||
flag.Parse()
|
||||
|
||||
for k, v := range flagMap {
|
||||
if v != nil && len(*v) > 0 {
|
||||
configMap[k] = trimToken(*v)
|
||||
}
|
||||
}
|
||||
|
||||
return configMap
|
||||
|
||||
}
|
||||
|
||||
func Bool(value string) bool {
|
||||
v, err := strconv.ParseBool(value)
|
||||
if err != nil {
|
||||
log.Printf("error parsing bool %v - %v\n", v, err)
|
||||
v = false
|
||||
}
|
||||
|
||||
return v
|
||||
}
|
||||
|
||||
func parseFile(config io.Reader) (ConfigMap, error) {
|
||||
func ConfigureWithDefaults(filename string, defaultConf ConfigMap) (ConfigMap, error) {
|
||||
var err error
|
||||
parsedMap := make(ConfigMap)
|
||||
|
||||
scanner := bufio.NewScanner(config)
|
||||
for scanner.Scan() {
|
||||
line := scanner.Text()
|
||||
trimmed := strings.TrimSpace(line)
|
||||
if len(trimmed) == 0 {
|
||||
// ignore empty lines
|
||||
continue
|
||||
}
|
||||
|
||||
if trimmed[0] == '#' {
|
||||
// ignore comments
|
||||
continue
|
||||
}
|
||||
|
||||
split := strings.Split(trimmed, "=")
|
||||
if len(split) != 2 {
|
||||
return nil, fmt.Errorf("failed to parse config line: %v", trimmed)
|
||||
}
|
||||
|
||||
key := trimToken(split[0])
|
||||
value := trimToken(split[1])
|
||||
|
||||
parsedMap[key] = value
|
||||
}
|
||||
|
||||
if err = scanner.Err(); err != nil {
|
||||
_, err = os.Stat(filename)
|
||||
if os.IsNotExist(err) {
|
||||
// Config file does not exist, return a default configMap
|
||||
return defaultConf, nil
|
||||
} else if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return parsedMap, nil
|
||||
}
|
||||
|
||||
func trimToken(value string) string {
|
||||
// Trim off whitespace
|
||||
v := strings.TrimSpace(value)
|
||||
|
||||
// Trim off any surrounding quotes, everything is a string anyway
|
||||
v = strings.TrimPrefix(v, "\"")
|
||||
v = strings.TrimSuffix(v, "\"")
|
||||
|
||||
return v
|
||||
return Configure(filename)
|
||||
}
|
||||
|
|
|
@ -1,150 +1,40 @@
|
|||
package gosimpleconf
|
||||
|
||||
import (
|
||||
"flag"
|
||||
"strings"
|
||||
"testing"
|
||||
)
|
||||
import "testing"
|
||||
|
||||
func TestParseWithValidConfig(t *testing.T) {
|
||||
var err error
|
||||
configFileStr := `
|
||||
# Some config file
|
||||
func TestConfigureWithDefaults(t *testing.T) {
|
||||
defaultMap := ConfigMap{
|
||||
"some": "thing",
|
||||
"cool": "1337",
|
||||
}
|
||||
|
||||
foo=bar
|
||||
asdf = 1234
|
||||
filename := "idontexist_123456789"
|
||||
|
||||
# Things
|
||||
wat.wat= thing
|
||||
foo.wat =stuff
|
||||
|
||||
immaempty=
|
||||
|
||||
technically valid = haha hmm...
|
||||
|
||||
#Done
|
||||
`
|
||||
configFile := strings.NewReader(configFileStr)
|
||||
|
||||
expectedMap := make(ConfigMap)
|
||||
expectedMap["foo"] = "bar"
|
||||
expectedMap["asdf"] = "1234"
|
||||
expectedMap["wat.wat"] = "thing"
|
||||
expectedMap["foo.wat"] = "stuff"
|
||||
expectedMap["immaempty"] = ""
|
||||
expectedMap["technically valid"] = "haha hmm..."
|
||||
|
||||
parsedMap, err := parseFile(configFile)
|
||||
conf, err := ConfigureWithDefaults(filename, defaultMap)
|
||||
if err != nil {
|
||||
t.Errorf("failed while parsing the file")
|
||||
t.Errorf("unexpected error: %v", err)
|
||||
}
|
||||
|
||||
validateMap(t, parsedMap, expectedMap)
|
||||
validateMap(t, conf, defaultMap)
|
||||
}
|
||||
|
||||
func TestParseWithExtraEquals(t *testing.T) {
|
||||
var err error
|
||||
configFileStr := `
|
||||
foo=bar=true
|
||||
`
|
||||
configFile := strings.NewReader(configFileStr)
|
||||
|
||||
_, err = parseFile(configFile)
|
||||
if err == nil {
|
||||
t.Errorf("parse did not thrown an error when it was supposed to")
|
||||
func TestConfigure(t *testing.T) {
|
||||
filename := "test.conf"
|
||||
expectedMap := ConfigMap{
|
||||
"url": "www.wisellama.rocks",
|
||||
"number_of_widgets": "1337",
|
||||
"pi": "3.141592653589793238462643383",
|
||||
"environment": "production",
|
||||
"name": "Dude guy",
|
||||
"description": "Just some dude it was",
|
||||
"base64_tacos": "dGFjb3M=",
|
||||
"a": "b=c",
|
||||
}
|
||||
}
|
||||
|
||||
func TestParseWithNoEquals(t *testing.T) {
|
||||
var err error
|
||||
configFileStr := `
|
||||
Something here with no equals to split on
|
||||
`
|
||||
configFile := strings.NewReader(configFileStr)
|
||||
|
||||
_, err = parseFile(configFile)
|
||||
if err == nil {
|
||||
t.Errorf("parse did not thrown an error when it was supposed to")
|
||||
}
|
||||
}
|
||||
|
||||
func TestFlagOverrides(t *testing.T) {
|
||||
var err error
|
||||
configFileStr := `
|
||||
foo=bar
|
||||
asdf = 1234
|
||||
foo.wat =stuff
|
||||
immaempty=
|
||||
`
|
||||
configFile := strings.NewReader(configFileStr)
|
||||
|
||||
expectedMap := make(ConfigMap)
|
||||
expectedMap["foo"] = "bar"
|
||||
expectedMap["asdf"] = "1234"
|
||||
// expect to override the 'foo.wat' value with a cli flag
|
||||
expectedMap["foo.wat"] = "iwasoverridden"
|
||||
expectedMap["immaempty"] = ""
|
||||
|
||||
configMap, err := parseFile(configFile)
|
||||
conf, err := Configure(filename)
|
||||
if err != nil {
|
||||
t.Errorf("failed while parsing the file")
|
||||
t.Errorf("unexpected error: %v", err)
|
||||
}
|
||||
|
||||
flagMap := SetupFlagOverrides(configMap)
|
||||
|
||||
err = flag.Set("foo.wat", "iwasoverridden")
|
||||
if err != nil {
|
||||
t.Errorf("failed to set cli flag override")
|
||||
}
|
||||
|
||||
configMap = ParseFlags(configMap, flagMap)
|
||||
|
||||
validateMap(t, configMap, expectedMap)
|
||||
}
|
||||
|
||||
func TestParseWithExtraQuotes(t *testing.T) {
|
||||
var err error
|
||||
configFileStr := `
|
||||
some.name = "This is in quotes"
|
||||
extra.quotes = ""This will keep the quotes""
|
||||
internal.quotes = "Some "thing" is here"
|
||||
"This should work too" = shrug I guess
|
||||
`
|
||||
|
||||
configFile := strings.NewReader(configFileStr)
|
||||
|
||||
expectedMap := make(ConfigMap)
|
||||
expectedMap["some.name"] = "This is in quotes"
|
||||
expectedMap["extra.quotes"] = "\"This will keep the quotes\""
|
||||
expectedMap["internal.quotes"] = "Some \"thing\" is here"
|
||||
expectedMap["This should work too"] = "shrug I guess"
|
||||
|
||||
configMap, err := parseFile(configFile)
|
||||
if err != nil {
|
||||
t.Errorf("failed while parsing the file")
|
||||
}
|
||||
|
||||
validateMap(t, configMap, expectedMap)
|
||||
}
|
||||
|
||||
func validateMap(t *testing.T, given map[string]string, expected map[string]string) {
|
||||
if given == nil {
|
||||
t.Errorf("given map was nil")
|
||||
}
|
||||
|
||||
if expected == nil {
|
||||
t.Errorf("expected map was nil")
|
||||
}
|
||||
|
||||
expectedLen := len(expected)
|
||||
givenLen := len(given)
|
||||
if expectedLen != givenLen {
|
||||
t.Errorf("size mismatch on maps - expected %v, given %v", expectedLen, givenLen)
|
||||
}
|
||||
|
||||
for k, v := range expected {
|
||||
if v != given[k] {
|
||||
t.Errorf("incorrect value for key %v - expected %v, given %v", k, expected[k], given[k])
|
||||
}
|
||||
}
|
||||
validateMap(t, conf, expectedMap)
|
||||
}
|
||||
|
|
|
@ -0,0 +1,13 @@
|
|||
url = www.wisellama.rocks
|
||||
number_of_widgets = 1337
|
||||
pi = 3.141592653589793238462643383
|
||||
environment = production
|
||||
|
||||
# Quotes are optional
|
||||
name = Dude guy
|
||||
description = "Just some dude it was"
|
||||
|
||||
# Additional equals are just part of the value
|
||||
base64_tacos = dGFjb3M=
|
||||
a=b=c
|
||||
# key: 'a', value: 'b=c'
|
|
@ -0,0 +1,25 @@
|
|||
package gosimpleconf
|
||||
|
||||
import "testing"
|
||||
|
||||
func validateMap(t *testing.T, given map[string]string, expected map[string]string) {
|
||||
if given == nil {
|
||||
t.Errorf("given map was nil")
|
||||
}
|
||||
|
||||
if expected == nil {
|
||||
t.Errorf("expected map was nil")
|
||||
}
|
||||
|
||||
expectedLen := len(expected)
|
||||
givenLen := len(given)
|
||||
if expectedLen != givenLen {
|
||||
t.Errorf("size mismatch on maps - expected %v, given %v", expectedLen, givenLen)
|
||||
}
|
||||
|
||||
for k, v := range expected {
|
||||
if v != given[k] {
|
||||
t.Errorf("incorrect value for key %v - expected %v, given %v", k, expected[k], given[k])
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue