1// Copyright 2014 Unknwon
2//
3// Licensed under the Apache License, Version 2.0 (the "License"): you may
4// not use this file except in compliance with the License. You may obtain
5// a copy of the License at
6//
7//     http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
11// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
12// License for the specific language governing permissions and limitations
13// under the License.
14
15package ini_test
16
17import (
18	"testing"
19
20	. "github.com/smartystreets/goconvey/convey"
21	"gopkg.in/ini.v1"
22)
23
24func TestSection_SetBody(t *testing.T) {
25	Convey("Set body of raw section", t, func() {
26		f := ini.Empty()
27		So(f, ShouldNotBeNil)
28
29		sec, err := f.NewRawSection("comments", `1111111111111111111000000000000000001110000
30111111111111111111100000000000111000000000`)
31		So(err, ShouldBeNil)
32		So(sec, ShouldNotBeNil)
33		So(sec.Body(), ShouldEqual, `1111111111111111111000000000000000001110000
34111111111111111111100000000000111000000000`)
35
36		sec.SetBody("1111111111111111111000000000000000001110000")
37		So(sec.Body(), ShouldEqual, `1111111111111111111000000000000000001110000`)
38
39		Convey("Set for non-raw section", func() {
40			sec, err := f.NewSection("author")
41			So(err, ShouldBeNil)
42			So(sec, ShouldNotBeNil)
43			So(sec.Body(), ShouldBeEmpty)
44
45			sec.SetBody("1111111111111111111000000000000000001110000")
46			So(sec.Body(), ShouldBeEmpty)
47		})
48	})
49}
50
51func TestSection_NewKey(t *testing.T) {
52	Convey("Create a new key", t, func() {
53		f := ini.Empty()
54		So(f, ShouldNotBeNil)
55
56		k, err := f.Section("").NewKey("NAME", "ini")
57		So(err, ShouldBeNil)
58		So(k, ShouldNotBeNil)
59		So(k.Name(), ShouldEqual, "NAME")
60		So(k.Value(), ShouldEqual, "ini")
61
62		Convey("With duplicated name", func() {
63			k, err := f.Section("").NewKey("NAME", "ini.v1")
64			So(err, ShouldBeNil)
65			So(k, ShouldNotBeNil)
66
67			// Overwrite previous existed key
68			So(k.Value(), ShouldEqual, "ini.v1")
69		})
70
71		Convey("With empty string", func() {
72			_, err := f.Section("").NewKey("", "")
73			So(err, ShouldNotBeNil)
74		})
75	})
76
77	Convey("Create keys with same name and allow shadow", t, func() {
78		f, err := ini.ShadowLoad([]byte(""))
79		So(err, ShouldBeNil)
80		So(f, ShouldNotBeNil)
81
82		k, err := f.Section("").NewKey("NAME", "ini")
83		So(err, ShouldBeNil)
84		So(k, ShouldNotBeNil)
85		k, err = f.Section("").NewKey("NAME", "ini.v1")
86		So(err, ShouldBeNil)
87		So(k, ShouldNotBeNil)
88
89		So(k.ValueWithShadows(), ShouldResemble, []string{"ini", "ini.v1"})
90	})
91}
92
93func TestSection_NewBooleanKey(t *testing.T) {
94	Convey("Create a new boolean key", t, func() {
95		f := ini.Empty()
96		So(f, ShouldNotBeNil)
97
98		k, err := f.Section("").NewBooleanKey("start-ssh-server")
99		So(err, ShouldBeNil)
100		So(k, ShouldNotBeNil)
101		So(k.Name(), ShouldEqual, "start-ssh-server")
102		So(k.Value(), ShouldEqual, "true")
103
104		Convey("With empty string", func() {
105			_, err := f.Section("").NewBooleanKey("")
106			So(err, ShouldNotBeNil)
107		})
108	})
109}
110
111func TestSection_GetKey(t *testing.T) {
112	Convey("Get a key", t, func() {
113		f := ini.Empty()
114		So(f, ShouldNotBeNil)
115
116		k, err := f.Section("").NewKey("NAME", "ini")
117		So(err, ShouldBeNil)
118		So(k, ShouldNotBeNil)
119
120		k, err = f.Section("").GetKey("NAME")
121		So(err, ShouldBeNil)
122		So(k, ShouldNotBeNil)
123		So(k.Name(), ShouldEqual, "NAME")
124		So(k.Value(), ShouldEqual, "ini")
125
126		Convey("Key not exists", func() {
127			_, err := f.Section("").GetKey("404")
128			So(err, ShouldNotBeNil)
129		})
130
131		Convey("Key exists in parent section", func() {
132			k, err := f.Section("parent").NewKey("AGE", "18")
133			So(err, ShouldBeNil)
134			So(k, ShouldNotBeNil)
135
136			k, err = f.Section("parent.child.son").GetKey("AGE")
137			So(err, ShouldBeNil)
138			So(k, ShouldNotBeNil)
139			So(k.Value(), ShouldEqual, "18")
140		})
141	})
142}
143
144func TestSection_HasKey(t *testing.T) {
145	Convey("Check if a key exists", t, func() {
146		f := ini.Empty()
147		So(f, ShouldNotBeNil)
148
149		k, err := f.Section("").NewKey("NAME", "ini")
150		So(err, ShouldBeNil)
151		So(k, ShouldNotBeNil)
152
153		So(f.Section("").HasKey("NAME"), ShouldBeTrue)
154		So(f.Section("").HasKey("NAME"), ShouldBeTrue)
155		So(f.Section("").HasKey("404"), ShouldBeFalse)
156		So(f.Section("").HasKey("404"), ShouldBeFalse)
157	})
158}
159
160func TestSection_HasValue(t *testing.T) {
161	Convey("Check if contains a value in any key", t, func() {
162		f := ini.Empty()
163		So(f, ShouldNotBeNil)
164
165		k, err := f.Section("").NewKey("NAME", "ini")
166		So(err, ShouldBeNil)
167		So(k, ShouldNotBeNil)
168
169		So(f.Section("").HasValue("ini"), ShouldBeTrue)
170		So(f.Section("").HasValue("404"), ShouldBeFalse)
171	})
172}
173
174func TestSection_Key(t *testing.T) {
175	Convey("Get a key", t, func() {
176		f := ini.Empty()
177		So(f, ShouldNotBeNil)
178
179		k, err := f.Section("").NewKey("NAME", "ini")
180		So(err, ShouldBeNil)
181		So(k, ShouldNotBeNil)
182
183		k = f.Section("").Key("NAME")
184		So(k, ShouldNotBeNil)
185		So(k.Name(), ShouldEqual, "NAME")
186		So(k.Value(), ShouldEqual, "ini")
187
188		Convey("Key not exists", func() {
189			k := f.Section("").Key("404")
190			So(k, ShouldNotBeNil)
191			So(k.Name(), ShouldEqual, "404")
192		})
193
194		Convey("Key exists in parent section", func() {
195			k, err := f.Section("parent").NewKey("AGE", "18")
196			So(err, ShouldBeNil)
197			So(k, ShouldNotBeNil)
198
199			k = f.Section("parent.child.son").Key("AGE")
200			So(k, ShouldNotBeNil)
201			So(k.Value(), ShouldEqual, "18")
202		})
203	})
204}
205
206func TestSection_Keys(t *testing.T) {
207	Convey("Get all keys in a section", t, func() {
208		f := ini.Empty()
209		So(f, ShouldNotBeNil)
210
211		k, err := f.Section("").NewKey("NAME", "ini")
212		So(err, ShouldBeNil)
213		So(k, ShouldNotBeNil)
214		k, err = f.Section("").NewKey("VERSION", "v1")
215		So(err, ShouldBeNil)
216		So(k, ShouldNotBeNil)
217		k, err = f.Section("").NewKey("IMPORT_PATH", "gopkg.in/ini.v1")
218		So(err, ShouldBeNil)
219		So(k, ShouldNotBeNil)
220
221		keys := f.Section("").Keys()
222		names := []string{"NAME", "VERSION", "IMPORT_PATH"}
223		So(len(keys), ShouldEqual, len(names))
224		for i, name := range names {
225			So(keys[i].Name(), ShouldEqual, name)
226		}
227	})
228}
229
230func TestSection_ParentKeys(t *testing.T) {
231	Convey("Get all keys of parent sections", t, func() {
232		f := ini.Empty()
233		So(f, ShouldNotBeNil)
234
235		k, err := f.Section("package").NewKey("NAME", "ini")
236		So(err, ShouldBeNil)
237		So(k, ShouldNotBeNil)
238		k, err = f.Section("package").NewKey("VERSION", "v1")
239		So(err, ShouldBeNil)
240		So(k, ShouldNotBeNil)
241		k, err = f.Section("package").NewKey("IMPORT_PATH", "gopkg.in/ini.v1")
242		So(err, ShouldBeNil)
243		So(k, ShouldNotBeNil)
244
245		keys := f.Section("package.sub.sub2").ParentKeys()
246		names := []string{"NAME", "VERSION", "IMPORT_PATH"}
247		So(len(keys), ShouldEqual, len(names))
248		for i, name := range names {
249			So(keys[i].Name(), ShouldEqual, name)
250		}
251	})
252}
253
254func TestSection_KeyStrings(t *testing.T) {
255	Convey("Get all key names in a section", t, func() {
256		f := ini.Empty()
257		So(f, ShouldNotBeNil)
258
259		k, err := f.Section("").NewKey("NAME", "ini")
260		So(err, ShouldBeNil)
261		So(k, ShouldNotBeNil)
262		k, err = f.Section("").NewKey("VERSION", "v1")
263		So(err, ShouldBeNil)
264		So(k, ShouldNotBeNil)
265		k, err = f.Section("").NewKey("IMPORT_PATH", "gopkg.in/ini.v1")
266		So(err, ShouldBeNil)
267		So(k, ShouldNotBeNil)
268
269		So(f.Section("").KeyStrings(), ShouldResemble, []string{"NAME", "VERSION", "IMPORT_PATH"})
270	})
271}
272
273func TestSection_KeyHash(t *testing.T) {
274	Convey("Get clone of key hash", t, func() {
275		f, err := ini.Load([]byte(`
276key = one
277[log]
278name = app
279file = a.log
280`), []byte(`
281key = two
282[log]
283name = app2
284file = b.log
285`))
286		So(err, ShouldBeNil)
287		So(f, ShouldNotBeNil)
288
289		So(f.Section("").Key("key").String(), ShouldEqual, "two")
290
291		hash := f.Section("log").KeysHash()
292		relation := map[string]string{
293			"name": "app2",
294			"file": "b.log",
295		}
296		for k, v := range hash {
297			So(v, ShouldEqual, relation[k])
298		}
299	})
300}
301
302func TestSection_DeleteKey(t *testing.T) {
303	Convey("Delete a key", t, func() {
304		f := ini.Empty()
305		So(f, ShouldNotBeNil)
306
307		k, err := f.Section("").NewKey("NAME", "ini")
308		So(err, ShouldBeNil)
309		So(k, ShouldNotBeNil)
310
311		So(f.Section("").HasKey("NAME"), ShouldBeTrue)
312		f.Section("").DeleteKey("NAME")
313		So(f.Section("").HasKey("NAME"), ShouldBeFalse)
314	})
315}
316