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
16
17import (
18	"testing"
19
20	"github.com/stretchr/testify/assert"
21	"github.com/stretchr/testify/require"
22)
23
24func TestSection_SetBody(t *testing.T) {
25	t.Run("set body of raw section", func(t *testing.T) {
26		f := Empty()
27		require.NotNil(t, f)
28
29		sec, err := f.NewRawSection("comments", `1111111111111111111000000000000000001110000
30111111111111111111100000000000111000000000`)
31		require.NoError(t, err)
32		require.NotNil(t, sec)
33		assert.Equal(t, `1111111111111111111000000000000000001110000
34111111111111111111100000000000111000000000`, sec.Body())
35
36		sec.SetBody("1111111111111111111000000000000000001110000")
37		assert.Equal(t, `1111111111111111111000000000000000001110000`, sec.Body())
38
39		t.Run("set for non-raw section", func(t *testing.T) {
40			sec, err := f.NewSection("author")
41			require.NoError(t, err)
42			require.NotNil(t, sec)
43			assert.Empty(t, sec.Body())
44
45			sec.SetBody("1111111111111111111000000000000000001110000")
46			assert.Empty(t, sec.Body())
47		})
48	})
49}
50
51func TestSection_NewKey(t *testing.T) {
52	t.Run("create a new key", func(t *testing.T) {
53		f := Empty()
54		require.NotNil(t, f)
55
56		k, err := f.Section("").NewKey("NAME", "ini")
57		require.NoError(t, err)
58		require.NotNil(t, k)
59		assert.Equal(t, "NAME", k.Name())
60		assert.Equal(t, "ini", k.Value())
61
62		t.Run("with duplicated name", func(t *testing.T) {
63			k, err := f.Section("").NewKey("NAME", "ini.v1")
64			require.NoError(t, err)
65			require.NotNil(t, k)
66
67			// Overwrite previous existed key
68			assert.Equal(t, "ini.v1", k.Value())
69		})
70
71		t.Run("with empty string", func(t *testing.T) {
72			_, err := f.Section("").NewKey("", "")
73			require.Error(t, err)
74		})
75	})
76
77	t.Run("create keys with same name and allow shadow", func(t *testing.T) {
78		f, err := ShadowLoad([]byte(""))
79		require.NoError(t, err)
80		require.NotNil(t, f)
81
82		k, err := f.Section("").NewKey("NAME", "ini")
83		require.NoError(t, err)
84		require.NotNil(t, k)
85		k, err = f.Section("").NewKey("NAME", "ini.v1")
86		require.NoError(t, err)
87		require.NotNil(t, k)
88
89		assert.Equal(t, []string{"ini", "ini.v1"}, k.ValueWithShadows())
90	})
91}
92
93func TestSection_NewBooleanKey(t *testing.T) {
94	t.Run("create a new boolean key", func(t *testing.T) {
95		f := Empty()
96		require.NotNil(t, f)
97
98		k, err := f.Section("").NewBooleanKey("start-ssh-server")
99		require.NoError(t, err)
100		require.NotNil(t, k)
101		assert.Equal(t, "start-ssh-server", k.Name())
102		assert.Equal(t, "true", k.Value())
103
104		t.Run("with empty string", func(t *testing.T) {
105			_, err := f.Section("").NewBooleanKey("")
106			require.Error(t, err)
107		})
108	})
109}
110
111func TestSection_GetKey(t *testing.T) {
112	t.Run("get a key", func(t *testing.T) {
113		f := Empty()
114		require.NotNil(t, f)
115
116		k, err := f.Section("").NewKey("NAME", "ini")
117		require.NoError(t, err)
118		require.NotNil(t, k)
119
120		k, err = f.Section("").GetKey("NAME")
121		require.NoError(t, err)
122		require.NotNil(t, k)
123		assert.Equal(t, "NAME", k.Name())
124		assert.Equal(t, "ini", k.Value())
125
126		t.Run("key not exists", func(t *testing.T) {
127			_, err := f.Section("").GetKey("404")
128			require.Error(t, err)
129		})
130
131		t.Run("key exists in parent section", func(t *testing.T) {
132			k, err := f.Section("parent").NewKey("AGE", "18")
133			require.NoError(t, err)
134			require.NotNil(t, k)
135
136			k, err = f.Section("parent.child.son").GetKey("AGE")
137			require.NoError(t, err)
138			require.NotNil(t, k)
139			assert.Equal(t, "18", k.Value())
140		})
141	})
142}
143
144func TestSection_HasKey(t *testing.T) {
145	t.Run("check if a key exists", func(t *testing.T) {
146		f := Empty()
147		require.NotNil(t, f)
148
149		k, err := f.Section("").NewKey("NAME", "ini")
150		require.NoError(t, err)
151		require.NotNil(t, k)
152
153		assert.True(t, f.Section("").HasKey("NAME"))
154		assert.True(t, f.Section("").HasKey("NAME"))
155		assert.False(t, f.Section("").HasKey("404"))
156		assert.False(t, f.Section("").HasKey("404"))
157	})
158}
159
160func TestSection_HasValue(t *testing.T) {
161	t.Run("check if contains a value in any key", func(t *testing.T) {
162		f := Empty()
163		require.NotNil(t, f)
164
165		k, err := f.Section("").NewKey("NAME", "ini")
166		require.NoError(t, err)
167		require.NotNil(t, k)
168
169		assert.True(t, f.Section("").HasValue("ini"))
170		assert.False(t, f.Section("").HasValue("404"))
171	})
172}
173
174func TestSection_Key(t *testing.T) {
175	t.Run("get a key", func(t *testing.T) {
176		f := Empty()
177		require.NotNil(t, f)
178
179		k, err := f.Section("").NewKey("NAME", "ini")
180		require.NoError(t, err)
181		require.NotNil(t, k)
182
183		k = f.Section("").Key("NAME")
184		require.NotNil(t, k)
185		assert.Equal(t, "NAME", k.Name())
186		assert.Equal(t, "ini", k.Value())
187
188		t.Run("key not exists", func(t *testing.T) {
189			k := f.Section("").Key("404")
190			require.NotNil(t, k)
191			assert.Equal(t, "404", k.Name())
192		})
193
194		t.Run("key exists in parent section", func(t *testing.T) {
195			k, err := f.Section("parent").NewKey("AGE", "18")
196			require.NoError(t, err)
197			require.NotNil(t, k)
198
199			k = f.Section("parent.child.son").Key("AGE")
200			require.NotNil(t, k)
201			assert.Equal(t, "18", k.Value())
202		})
203	})
204}
205
206func TestSection_Keys(t *testing.T) {
207	t.Run("get all keys in a section", func(t *testing.T) {
208		f := Empty()
209		require.NotNil(t, f)
210
211		k, err := f.Section("").NewKey("NAME", "ini")
212		require.NoError(t, err)
213		require.NotNil(t, k)
214		k, err = f.Section("").NewKey("VERSION", "v1")
215		require.NoError(t, err)
216		require.NotNil(t, k)
217		k, err = f.Section("").NewKey("IMPORT_PATH", "gopkg.in/ini.v1")
218		require.NoError(t, err)
219		require.NotNil(t, k)
220
221		keys := f.Section("").Keys()
222		names := []string{"NAME", "VERSION", "IMPORT_PATH"}
223		assert.Equal(t, len(names), len(keys))
224		for i, name := range names {
225			assert.Equal(t, name, keys[i].Name())
226		}
227	})
228}
229
230func TestSection_ParentKeys(t *testing.T) {
231	t.Run("get all keys of parent sections", func(t *testing.T) {
232		f := Empty()
233		require.NotNil(t, f)
234
235		k, err := f.Section("package").NewKey("NAME", "ini")
236		require.NoError(t, err)
237		require.NotNil(t, k)
238		k, err = f.Section("package").NewKey("VERSION", "v1")
239		require.NoError(t, err)
240		require.NotNil(t, k)
241		k, err = f.Section("package").NewKey("IMPORT_PATH", "gopkg.in/ini.v1")
242		require.NoError(t, err)
243		require.NotNil(t, k)
244
245		keys := f.Section("package.sub.sub2").ParentKeys()
246		names := []string{"NAME", "VERSION", "IMPORT_PATH"}
247		assert.Equal(t, len(names), len(keys))
248		for i, name := range names {
249			assert.Equal(t, name, keys[i].Name())
250		}
251	})
252}
253
254func TestSection_KeyStrings(t *testing.T) {
255	t.Run("get all key names in a section", func(t *testing.T) {
256		f := Empty()
257		require.NotNil(t, f)
258
259		k, err := f.Section("").NewKey("NAME", "ini")
260		require.NoError(t, err)
261		require.NotNil(t, k)
262		k, err = f.Section("").NewKey("VERSION", "v1")
263		require.NoError(t, err)
264		require.NotNil(t, k)
265		k, err = f.Section("").NewKey("IMPORT_PATH", "gopkg.in/ini.v1")
266		require.NoError(t, err)
267		require.NotNil(t, k)
268
269		assert.Equal(t, []string{"NAME", "VERSION", "IMPORT_PATH"}, f.Section("").KeyStrings())
270	})
271}
272
273func TestSection_KeyHash(t *testing.T) {
274	t.Run("get clone of key hash", func(t *testing.T) {
275		f, err := Load([]byte(`
276key = one
277[log]
278name = app
279file = a.log
280`), []byte(`
281key = two
282[log]
283name = app2
284file = b.log
285`))
286		require.NoError(t, err)
287		require.NotNil(t, f)
288
289		assert.Equal(t, "two", f.Section("").Key("key").String())
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			assert.Equal(t, relation[k], v)
298		}
299	})
300}
301
302func TestSection_DeleteKey(t *testing.T) {
303	t.Run("delete a key", func(t *testing.T) {
304		f := Empty()
305		require.NotNil(t, f)
306
307		k, err := f.Section("").NewKey("NAME", "ini")
308		require.NoError(t, err)
309		require.NotNil(t, k)
310
311		assert.True(t, f.Section("").HasKey("NAME"))
312		f.Section("").DeleteKey("NAME")
313		assert.False(t, f.Section("").HasKey("NAME"))
314	})
315}
316