399 lines
11 KiB
Go
399 lines
11 KiB
Go
|
// Copyright 2013 Unknwon
|
||
|
//
|
||
|
// Licensed under the Apache License, Version 2.0 (the "License"): you may
|
||
|
// not use this file except in compliance with the License. You may obtain
|
||
|
// a copy of the License at
|
||
|
//
|
||
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||
|
//
|
||
|
// Unless required by applicable law or agreed to in writing, software
|
||
|
// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||
|
// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||
|
// License for the specific language governing permissions and limitations
|
||
|
// under the License.
|
||
|
|
||
|
package goconfig
|
||
|
|
||
|
import (
|
||
|
"bytes"
|
||
|
"fmt"
|
||
|
"io/ioutil"
|
||
|
"testing"
|
||
|
|
||
|
. "github.com/smartystreets/goconvey/convey"
|
||
|
)
|
||
|
|
||
|
func TestLoadConfigFile(t *testing.T) {
|
||
|
Convey("Load a single configuration file that does exist", t, func() {
|
||
|
c, err := LoadConfigFile("testdata/conf.ini")
|
||
|
So(err, ShouldBeNil)
|
||
|
So(c, ShouldNotBeNil)
|
||
|
|
||
|
Convey("Test GetSectionList", func() {
|
||
|
So(c.GetSectionList(), ShouldResemble,
|
||
|
[]string{"DEFAULT", "Demo", "What's this?", "url", "parent",
|
||
|
"parent.child", "parent.child.child", "auto increment"})
|
||
|
})
|
||
|
|
||
|
Convey("Get value that does exist", func() {
|
||
|
v, err := c.GetValue("Demo", "key2")
|
||
|
So(err, ShouldBeNil)
|
||
|
So(v, ShouldEqual, "test data")
|
||
|
})
|
||
|
|
||
|
Convey("Get value that does not exist", func() {
|
||
|
_, err := c.GetValue("Demo", "key4")
|
||
|
So(err, ShouldNotBeNil)
|
||
|
})
|
||
|
|
||
|
Convey("Get value that has empty value", func() {
|
||
|
_, err := c.GetValue("What's this?", "empty_value")
|
||
|
So(err, ShouldBeNil)
|
||
|
})
|
||
|
|
||
|
Convey("Get value that section does not exist", func() {
|
||
|
_, err := c.GetValue("Demo404", "key4")
|
||
|
So(err, ShouldNotBeNil)
|
||
|
})
|
||
|
|
||
|
Convey("Get value use parent-child feature", func() {
|
||
|
v, err := c.GetValue("parent.child", "sex")
|
||
|
So(err, ShouldBeNil)
|
||
|
So(v, ShouldEqual, "male")
|
||
|
})
|
||
|
|
||
|
Convey("Get value use recursive feature", func() {
|
||
|
v, err := c.GetValue("", "search")
|
||
|
So(err, ShouldBeNil)
|
||
|
So(v, ShouldEqual, "http://www.google.com")
|
||
|
|
||
|
v, err = c.GetValue("url", "google_url")
|
||
|
So(err, ShouldBeNil)
|
||
|
So(v, ShouldEqual, "http://www.google.fake")
|
||
|
})
|
||
|
|
||
|
Convey("Set value that does exist", func() {
|
||
|
So(c.SetValue("Demo", "key2", "hello man!"), ShouldBeFalse)
|
||
|
v, err := c.GetValue("Demo", "key2")
|
||
|
So(err, ShouldBeNil)
|
||
|
So(v, ShouldEqual, "hello man!")
|
||
|
})
|
||
|
|
||
|
Convey("Set value that does not exist", func() {
|
||
|
So(c.SetValue("Demo", "key4", "hello girl!"), ShouldBeTrue)
|
||
|
v, err := c.GetValue("Demo", "key4")
|
||
|
So(err, ShouldBeNil)
|
||
|
So(v, ShouldEqual, "hello girl!")
|
||
|
So(c.SetValue("", "gowalker", "https://gowalker.org"), ShouldBeTrue)
|
||
|
})
|
||
|
|
||
|
Convey("Test GetKeyList", func() {
|
||
|
So(c.GetKeyList("Demo"), ShouldResemble,
|
||
|
[]string{"key1", "key2", "key3", "quote", "key:1",
|
||
|
"key:2=key:1", "中国", "chinese-var", "array_key"})
|
||
|
})
|
||
|
|
||
|
Convey("Delete a key", func() {
|
||
|
So(c.DeleteKey("", "key404"), ShouldBeFalse)
|
||
|
So(c.DeleteKey("Demo", "key404"), ShouldBeFalse)
|
||
|
So(c.DeleteKey("Demo", "中国"), ShouldBeTrue)
|
||
|
_, err := c.GetValue("Demo", "中国")
|
||
|
So(err, ShouldNotBeNil)
|
||
|
So(c.DeleteKey("404", "key"), ShouldBeFalse)
|
||
|
})
|
||
|
|
||
|
Convey("Delete all the keys", func() {
|
||
|
for _, key := range c.GetKeyList("Demo") {
|
||
|
So(c.DeleteKey("Demo", key), ShouldBeTrue)
|
||
|
}
|
||
|
So(c.GetKeyList("Demo"), ShouldResemble, []string{})
|
||
|
So(len(c.GetKeyList("Demo")), ShouldEqual, 0)
|
||
|
})
|
||
|
|
||
|
Convey("Delete section that does not exist", func() {
|
||
|
So(c.DeleteSection(""), ShouldBeTrue)
|
||
|
So(c.DeleteSection("404"), ShouldBeFalse)
|
||
|
})
|
||
|
|
||
|
Convey("Get section that exists", func() {
|
||
|
_, err = c.GetSection("")
|
||
|
So(err, ShouldBeNil)
|
||
|
})
|
||
|
|
||
|
Convey("Get section that does not exist", func() {
|
||
|
_, err = c.GetSection("404")
|
||
|
So(err, ShouldNotBeNil)
|
||
|
})
|
||
|
|
||
|
Convey("Set section comments", func() {
|
||
|
So(c.SetSectionComments("", "default section comments"), ShouldBeTrue)
|
||
|
})
|
||
|
|
||
|
Convey("Get section comments", func() {
|
||
|
So(c.GetSectionComments(""), ShouldEqual, "")
|
||
|
})
|
||
|
|
||
|
Convey("Set key comments", func() {
|
||
|
So(c.SetKeyComments("", "search", "search comments"), ShouldBeTrue)
|
||
|
So(c.SetKeyComments("404", "search", ""), ShouldBeTrue)
|
||
|
})
|
||
|
|
||
|
Convey("Get key comments", func() {
|
||
|
So(c.GetKeyComments("", "google"), ShouldEqual, "; Google")
|
||
|
})
|
||
|
|
||
|
Convey("Delete all the sections", func() {
|
||
|
for _, sec := range c.GetSectionList() {
|
||
|
So(c.DeleteSection(sec), ShouldBeTrue)
|
||
|
}
|
||
|
So(c.GetSectionList(), ShouldResemble, []string{})
|
||
|
So(len(c.GetSectionList()), ShouldEqual, 0)
|
||
|
})
|
||
|
})
|
||
|
|
||
|
Convey("Load a single configuration file that does not exist", t, func() {
|
||
|
_, err := LoadConfigFile("testdata/conf404.ini")
|
||
|
So(err, ShouldNotBeNil)
|
||
|
})
|
||
|
|
||
|
Convey("Load multiple configuration files", t, func() {
|
||
|
c, err := LoadConfigFile("testdata/conf.ini", "testdata/conf2.ini")
|
||
|
So(err, ShouldBeNil)
|
||
|
So(c, ShouldNotBeNil)
|
||
|
|
||
|
Convey("Get value that does not exist in 1st file", func() {
|
||
|
v, err := c.GetValue("new section", "key1")
|
||
|
So(err, ShouldBeNil)
|
||
|
So(v, ShouldEqual, "conf.ini does not have this key")
|
||
|
})
|
||
|
|
||
|
Convey("Get value that overwrited in 2nd file", func() {
|
||
|
v, err := c.GetValue("Demo", "key2")
|
||
|
So(err, ShouldBeNil)
|
||
|
So(v, ShouldEqual, "rewrite this key of conf.ini")
|
||
|
})
|
||
|
})
|
||
|
}
|
||
|
|
||
|
func TestGetKeyList(t *testing.T) {
|
||
|
Convey("Get key list", t, func() {
|
||
|
c, err := LoadConfigFile("testdata/conf.ini")
|
||
|
So(err, ShouldBeNil)
|
||
|
So(c, ShouldNotBeNil)
|
||
|
|
||
|
Convey("Get ket list that does exist", func() {
|
||
|
So(c.GetKeyList("Demo"), ShouldResemble,
|
||
|
[]string{"key1", "key2", "key3", "quote", "key:1",
|
||
|
"key:2=key:1", "中国", "chinese-var", "array_key"})
|
||
|
So(c.GetKeyList(""), ShouldResemble, []string{"google", "search"})
|
||
|
})
|
||
|
|
||
|
Convey("Get key list that not exist", func() {
|
||
|
So(c.GetKeyList("404"), ShouldBeNil)
|
||
|
})
|
||
|
})
|
||
|
}
|
||
|
|
||
|
func TestSaveConfigFile(t *testing.T) {
|
||
|
Convey("Save a ConfigFile to file system", t, func() {
|
||
|
c, err := LoadConfigFile("testdata/conf.ini", "testdata/conf2.ini")
|
||
|
So(err, ShouldBeNil)
|
||
|
So(c, ShouldNotBeNil)
|
||
|
|
||
|
c.SetValue("", "", "empty")
|
||
|
|
||
|
So(SaveConfigFile(c, "testdata/conf_test.ini"), ShouldBeNil)
|
||
|
})
|
||
|
}
|
||
|
|
||
|
func TestSaveConfigData(t *testing.T) {
|
||
|
Convey("Save a ConfigFile to file system", t, func() {
|
||
|
c, err := LoadConfigFile("testdata/conf.ini", "testdata/conf2.ini")
|
||
|
So(err, ShouldBeNil)
|
||
|
So(c, ShouldNotBeNil)
|
||
|
|
||
|
c.SetValue("", "", "empty")
|
||
|
var dst bytes.Buffer
|
||
|
So(SaveConfigData(c, &dst), ShouldBeNil)
|
||
|
So(dst.Len(), ShouldNotEqual, 0)
|
||
|
})
|
||
|
}
|
||
|
|
||
|
func TestReload(t *testing.T) {
|
||
|
Convey("Reload a configuration file", t, func() {
|
||
|
c, err := LoadConfigFile("testdata/conf.ini", "testdata/conf2.ini")
|
||
|
So(err, ShouldBeNil)
|
||
|
So(c, ShouldNotBeNil)
|
||
|
|
||
|
So(c.Reload(), ShouldBeNil)
|
||
|
})
|
||
|
}
|
||
|
|
||
|
func TestReloadData(t *testing.T) {
|
||
|
Convey("Reload a configuration file", t, func() {
|
||
|
data, err := ioutil.ReadFile("testdata/conf.ini")
|
||
|
So(err, ShouldBeNil)
|
||
|
c, err := LoadFromReader(bytes.NewBuffer(data))
|
||
|
So(err, ShouldBeNil)
|
||
|
So(c, ShouldNotBeNil)
|
||
|
|
||
|
So(c.ReloadData(bytes.NewBuffer(data)), ShouldBeNil)
|
||
|
})
|
||
|
}
|
||
|
|
||
|
func TestAppendFiles(t *testing.T) {
|
||
|
Convey("Reload a configuration file", t, func() {
|
||
|
c, err := LoadConfigFile("testdata/conf.ini")
|
||
|
So(err, ShouldBeNil)
|
||
|
So(c, ShouldNotBeNil)
|
||
|
|
||
|
So(c.AppendFiles("testdata/conf2.ini"), ShouldBeNil)
|
||
|
})
|
||
|
}
|
||
|
|
||
|
func TestTypes(t *testing.T) {
|
||
|
Convey("Return with types", t, func() {
|
||
|
c, err := LoadConfigFile("testdata/conf.ini")
|
||
|
So(err, ShouldBeNil)
|
||
|
So(c, ShouldNotBeNil)
|
||
|
|
||
|
Convey("Return bool", func() {
|
||
|
v, err := c.Bool("parent.child", "married")
|
||
|
So(err, ShouldBeNil)
|
||
|
So(v, ShouldBeTrue)
|
||
|
|
||
|
_, err = c.Bool("parent.child", "died")
|
||
|
So(err, ShouldNotBeNil)
|
||
|
})
|
||
|
|
||
|
Convey("Return float64", func() {
|
||
|
v, err := c.Float64("parent", "money")
|
||
|
So(err, ShouldBeNil)
|
||
|
So(v, ShouldEqual, 1.25)
|
||
|
|
||
|
_, err = c.Float64("parent", "balance")
|
||
|
So(err, ShouldNotBeNil)
|
||
|
})
|
||
|
|
||
|
Convey("Return int", func() {
|
||
|
v, err := c.Int("parent", "age")
|
||
|
So(err, ShouldBeNil)
|
||
|
So(v, ShouldEqual, 32)
|
||
|
|
||
|
_, err = c.Int("parent", "children")
|
||
|
So(err, ShouldNotBeNil)
|
||
|
})
|
||
|
|
||
|
Convey("Return int64", func() {
|
||
|
v, err := c.Int64("parent", "age")
|
||
|
So(err, ShouldBeNil)
|
||
|
So(v, ShouldEqual, 32)
|
||
|
|
||
|
_, err = c.Int64("parent", "children")
|
||
|
So(err, ShouldNotBeNil)
|
||
|
})
|
||
|
})
|
||
|
}
|
||
|
|
||
|
func TestMust(t *testing.T) {
|
||
|
Convey("Must return with type", t, func() {
|
||
|
c, err := LoadConfigFile("testdata/conf.ini")
|
||
|
So(err, ShouldBeNil)
|
||
|
So(c, ShouldNotBeNil)
|
||
|
|
||
|
Convey("Return string", func() {
|
||
|
So(c.MustValue("parent.child", "name"), ShouldEqual, "john")
|
||
|
So(c.MustValue("parent.child", "died"), ShouldEqual, "")
|
||
|
So(c.MustValue("parent.child", "died", "no"), ShouldEqual, "no")
|
||
|
})
|
||
|
|
||
|
Convey("Return string and bool", func() {
|
||
|
val, ok := c.MustValueSet("parent.child", "died")
|
||
|
So(val, ShouldEqual, "")
|
||
|
So(ok, ShouldBeFalse)
|
||
|
val, ok = c.MustValueSet("parent.child", "died", "no")
|
||
|
So(val, ShouldEqual, "no")
|
||
|
So(ok, ShouldBeTrue)
|
||
|
})
|
||
|
|
||
|
Convey("Return bool", func() {
|
||
|
So(c.MustBool("parent.child", "married"), ShouldBeTrue)
|
||
|
So(c.MustBool("parent.child", "died"), ShouldBeFalse)
|
||
|
So(c.MustBool("parent.child", "died", true), ShouldBeTrue)
|
||
|
})
|
||
|
|
||
|
Convey("Return float64", func() {
|
||
|
So(c.MustFloat64("parent", "money"), ShouldEqual, 1.25)
|
||
|
So(c.MustFloat64("parent", "balance"), ShouldEqual, 0.0)
|
||
|
So(c.MustFloat64("parent", "balance", 1.25), ShouldEqual, 1.25)
|
||
|
})
|
||
|
|
||
|
Convey("Return int", func() {
|
||
|
So(c.MustInt("parent", "age"), ShouldEqual, 32)
|
||
|
So(c.MustInt("parent", "children"), ShouldEqual, 0)
|
||
|
So(c.MustInt("parent", "children", 3), ShouldEqual, 3)
|
||
|
})
|
||
|
|
||
|
Convey("Return int64", func() {
|
||
|
So(c.MustInt64("parent", "age"), ShouldEqual, 32)
|
||
|
So(c.MustInt64("parent", "children"), ShouldEqual, 0)
|
||
|
So(c.MustInt64("parent", "children", 3), ShouldEqual, 3)
|
||
|
})
|
||
|
})
|
||
|
}
|
||
|
|
||
|
func TestRange(t *testing.T) {
|
||
|
Convey("Must return with range", t, func() {
|
||
|
c, err := LoadConfigFile("testdata/conf.ini")
|
||
|
So(err, ShouldBeNil)
|
||
|
So(c, ShouldNotBeNil)
|
||
|
|
||
|
So(c.MustValueRange("What's this?", "name", "joe", []string{"hello"}), ShouldEqual, "joe")
|
||
|
So(c.MustValueRange("What's this?", "name404", "joe", []string{"hello"}), ShouldEqual, "joe")
|
||
|
So(c.MustValueRange("What's this?", "name", "joe", []string{"hello", "try one more value ^-^"}),
|
||
|
ShouldEqual, "try one more value ^-^")
|
||
|
})
|
||
|
}
|
||
|
|
||
|
func TestArray(t *testing.T) {
|
||
|
Convey("Must return with string array", t, func() {
|
||
|
c, err := LoadConfigFile("testdata/conf.ini")
|
||
|
So(err, ShouldBeNil)
|
||
|
So(c, ShouldNotBeNil)
|
||
|
|
||
|
So(fmt.Sprintf("%s", c.MustValueArray("Demo", "array_key", ",")), ShouldEqual, "[1 2 3 4 5]")
|
||
|
So(fmt.Sprintf("%s", c.MustValueArray("Demo", "array_key404", ",")), ShouldEqual, "[]")
|
||
|
})
|
||
|
}
|
||
|
|
||
|
func TestLoadFromData(t *testing.T) {
|
||
|
Convey("Load config file from data", t, func() {
|
||
|
c, err := LoadFromData([]byte(""))
|
||
|
So(err, ShouldBeNil)
|
||
|
So(c, ShouldNotBeNil)
|
||
|
})
|
||
|
}
|
||
|
|
||
|
func TestLoadFromReader(t *testing.T) {
|
||
|
Convey("Load config file from reader", t, func() {
|
||
|
c, err := LoadFromReader(bytes.NewBuffer([]byte("")))
|
||
|
So(err, ShouldBeNil)
|
||
|
So(c, ShouldNotBeNil)
|
||
|
})
|
||
|
}
|
||
|
|
||
|
func Benchmark_GetValue(b *testing.B) {
|
||
|
c, _ := LoadConfigFile("testdata/conf.ini")
|
||
|
c.BlockMode = false
|
||
|
for i := 0; i < b.N; i++ {
|
||
|
c.GetValue("parent", "money")
|
||
|
}
|
||
|
}
|
||
|
|
||
|
func Benchmark_SetValue(b *testing.B) {
|
||
|
c, _ := LoadConfigFile("testdata/conf.ini")
|
||
|
for i := 0; i < b.N; i++ {
|
||
|
c.SetValue("parent", "money", "10")
|
||
|
}
|
||
|
}
|