// 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") } }