1   /*
2    * Copyright 2005,2009 Ivan SZKIBA
3    *
4    * Licensed under the Apache License, Version 2.0 (the "License");
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of the License at
7    *
8    *      http://www.apache.org/licenses/LICENSE-2.0
9    *
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS,
12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   * See the License for the specific language governing permissions and
14   * limitations under the License.
15   */
16  package org.ini4j.addon;
17  
18  import org.ini4j.DwarfsData;
19  import org.ini4j.Helper;
20  import org.ini4j.Ini;
21  
22  import org.ini4j.sample.Dwarf;
23  import org.ini4j.sample.Dwarfs;
24  
25  import org.junit.After;
26  
27  import static org.junit.Assert.*;
28  
29  import org.junit.Before;
30  import org.junit.Test;
31  
32  import java.io.File;
33  import java.io.FileInputStream;
34  import java.io.FileOutputStream;
35  import java.io.FileReader;
36  import java.io.FileWriter;
37  
38  import java.util.HashMap;
39  import java.util.List;
40  import java.util.Map;
41  
42  public class ConfigParserTest
43  {
44      private static final String SECTION = "section";
45      private static final String OPTION = "option";
46      private static final String DWARFS_PATH = "org/ini4j/addon/dwarfs-py.ini";
47      private static final String BAD_INI_PATH = "org/ini4j/addon/dwarfs-py-bad.ini";
48      private static final String TEST_DATA_PATH = "src/test/resources";
49      private static final String TEST_WORK_PATH = "target";
50      private static final String MISSING = "missing";
51      private static final String MISSING_REF = "%(missing)";
52      private static final String DUMMY = "dummy";
53      protected ConfigParser instance;
54  
55      @Before public void setUp()
56      {
57          instance = new ConfigParser();
58      }
59  
60      @After public void tearDown()
61      {
62      }
63  
64      @Test public void testAddHasRemove() throws Exception
65      {
66          assertFalse(instance.hasSection(SECTION));
67          assertFalse(instance.hasOption(SECTION, OPTION));
68          assertFalse(instance.getIni().containsKey(SECTION));
69          instance.addSection(SECTION);
70          assertTrue(instance.hasSection(SECTION));
71          instance.set(SECTION, OPTION, "dummy");
72          assertTrue(instance.hasOption(SECTION, OPTION));
73          assertTrue(instance.getIni().get(SECTION).containsKey(OPTION));
74          instance.removeOption(SECTION, OPTION);
75          assertFalse(instance.hasOption(SECTION, OPTION));
76          instance.removeSection(SECTION);
77          assertFalse(instance.hasSection(SECTION));
78      }
79  
80      @Test(expected = ConfigParser.DuplicateSectionException.class)
81      public void testAddSectionDuplicate() throws Exception
82      {
83          instance.addSection(SECTION);
84          instance.addSection(SECTION);
85      }
86  
87      @Test(expected = IllegalArgumentException.class)
88      public void testAddSectionIllegal() throws Exception
89      {
90          instance.addSection(ConfigParser.PyIni.DEFAULT_SECTION_NAME);
91      }
92  
93      @Test public void testDefaults() throws Exception
94      {
95          Map<String, String> defs = new HashMap<String, String>();
96  
97          instance = new ConfigParser(defs);
98  
99          assertSame(defs, instance.defaults());
100     }
101 
102     @Test public void testDwarfs() throws Exception
103     {
104         readDwarfs();
105         checkEquals(DwarfsData.bashful, Dwarfs.PROP_BASHFUL);
106         checkEquals(DwarfsData.doc, Dwarfs.PROP_DOC);
107         checkEquals(DwarfsData.dopey, Dwarfs.PROP_DOPEY);
108         checkEquals(DwarfsData.happy, Dwarfs.PROP_HAPPY);
109         checkEquals(DwarfsData.grumpy, Dwarfs.PROP_GRUMPY);
110         checkEquals(DwarfsData.sleepy, Dwarfs.PROP_SLEEPY);
111         checkEquals(DwarfsData.sneezy, Dwarfs.PROP_SNEEZY);
112     }
113 
114     @Test public void testGet() throws Exception
115     {
116         Ini.Section section = instance.getIni().add(SECTION);
117 
118         section.put(OPTION, "on");
119         assertTrue(instance.getBoolean(SECTION, OPTION));
120         section.put(OPTION, "1");
121         assertTrue(instance.getBoolean(SECTION, OPTION));
122         section.put(OPTION, "true");
123         assertTrue(instance.getBoolean(SECTION, OPTION));
124         section.put(OPTION, "yes");
125         assertTrue(instance.getBoolean(SECTION, OPTION));
126         section.put(OPTION, "TruE");
127         assertTrue(instance.getBoolean(SECTION, OPTION));
128 
129         //
130         section.put(OPTION, "off");
131         assertFalse(instance.getBoolean(SECTION, OPTION));
132         section.put(OPTION, "0");
133         assertFalse(instance.getBoolean(SECTION, OPTION));
134         section.put(OPTION, "no");
135         assertFalse(instance.getBoolean(SECTION, OPTION));
136         section.put(OPTION, "false");
137         assertFalse(instance.getBoolean(SECTION, OPTION));
138         section.put(OPTION, "FalsE");
139         assertFalse(instance.getBoolean(SECTION, OPTION));
140 
141         // ints
142         section.put(OPTION, "12");
143         assertEquals(12, instance.getInt(SECTION, OPTION));
144         assertEquals(12L, instance.getLong(SECTION, OPTION));
145         section.put(OPTION, "1.2");
146         assertEquals(1.2f, instance.getFloat(SECTION, OPTION), Helper.DELTA);
147         assertEquals(1.2, instance.getDouble(SECTION, OPTION), Helper.DELTA);
148     }
149 
150     @Test(expected = IllegalArgumentException.class)
151     public void testGetBooleanException() throws Exception
152     {
153         Ini.Section section = instance.getIni().add(SECTION);
154 
155         section.put(OPTION, "joe");
156         instance.getBoolean(SECTION, OPTION);
157     }
158 
159     @Test(expected = ConfigParser.InterpolationMissingOptionException.class)
160     public void testGetMissinOptionException() throws Exception
161     {
162         instance.addSection(SECTION);
163         instance.set(SECTION, OPTION, MISSING_REF);
164         instance.get(SECTION, OPTION);
165     }
166 
167     @Test(expected = ConfigParser.NoOptionException.class)
168     public void testGetNoOption() throws Exception
169     {
170         instance.getIni().add(SECTION);
171         instance.get(SECTION, OPTION);
172     }
173 
174     @Test(expected = ConfigParser.NoSectionException.class)
175     public void testGetNoSection() throws Exception
176     {
177         instance.get(SECTION, OPTION);
178     }
179 
180     @Test
181     @SuppressWarnings("empty-statement")
182     public void testGetVars() throws Exception
183     {
184         Map<String, String> vars = new HashMap<String, String>();
185 
186         instance = new ConfigParser(vars);
187 
188         instance.addSection(SECTION);
189         instance.set(SECTION, OPTION, MISSING_REF);
190         assertEquals(MISSING_REF, instance.get(SECTION, OPTION, true));
191         requireMissingOptionException(SECTION, OPTION);
192         vars.put(MISSING, DUMMY);
193         assertEquals(DUMMY, instance.get(SECTION, OPTION));
194         vars.remove(MISSING);
195         requireMissingOptionException(SECTION, OPTION);
196         instance.getIni().add(ConfigParser.PyIni.DEFAULT_SECTION_NAME);
197         instance.getIni().getDefaultSection().put(MISSING, DUMMY);
198         assertEquals(DUMMY, instance.get(SECTION, OPTION));
199         instance.getIni().getDefaultSection().remove(MISSING);
200         requireMissingOptionException(SECTION, OPTION);
201         instance = new ConfigParser();
202         instance.addSection(SECTION);
203         instance.set(SECTION, OPTION, MISSING_REF);
204         vars.put(MISSING, DUMMY);
205         assertEquals(DUMMY, instance.get(SECTION, OPTION, false, vars));
206     }
207 
208     @Test public void testItems() throws Exception
209     {
210         Ini ini = new Ini();
211 
212         ini.add(SECTION).from(DwarfsData.dopey);
213         Ini.Section section = ini.get(SECTION);
214         Ini.Section dopey = ini.add(Dwarfs.PROP_DOPEY);
215 
216         for (String key : section.keySet())
217         {
218             dopey.put(key.toLowerCase(), section.get(key));
219         }
220 
221         readDwarfs();
222         List<Map.Entry<String, String>> items = instance.items(Dwarfs.PROP_DOPEY);
223 
224         assertEquals(5, items.size());
225         assertEquals(5, dopey.size());
226         for (Map.Entry<String, String> entry : items)
227         {
228             assertEquals(dopey.get(entry.getKey()), entry.getValue());
229         }
230 
231         // raw
232         dopey = instance.getIni().get(Dwarfs.PROP_DOPEY);
233         items = instance.items(Dwarfs.PROP_DOPEY, true);
234 
235         assertEquals(5, items.size());
236         assertEquals("%(_weight)", dopey.get(Dwarf.PROP_WEIGHT));
237         assertEquals("%(_height)", dopey.get(Dwarf.PROP_HEIGHT));
238     }
239 
240     @Test public void testOptions() throws Exception
241     {
242         instance.addSection(SECTION);
243         assertEquals(0, instance.options(SECTION).size());
244         for (int i = 0; i < 10; i++)
245         {
246             instance.set(SECTION, OPTION + i, DUMMY);
247         }
248 
249         assertEquals(10, instance.options(SECTION).size());
250     }
251 
252     @Test public void testRead() throws Exception
253     {
254         File file = newTestFile(DWARFS_PATH);
255 
256         assertTrue(file.exists());
257         instance.read(file.getCanonicalPath());
258         instance.read(file);
259         instance.read(new FileReader(file));
260         instance.read(new FileInputStream(file));
261         instance.read(file.toURI().toURL());
262     }
263 
264     @Test(expected = ConfigParser.ParsingException.class)
265     public void testReadFileException() throws Exception
266     {
267         instance.read(newTestFile(BAD_INI_PATH));
268     }
269 
270     @Test(expected = ConfigParser.ParsingException.class)
271     public void testReadReaderException() throws Exception
272     {
273         instance.read(new FileReader(newTestFile(BAD_INI_PATH)));
274     }
275 
276     @Test(expected = ConfigParser.ParsingException.class)
277     public void testReadStreamException() throws Exception
278     {
279         instance.read(new FileInputStream(newTestFile(BAD_INI_PATH)));
280     }
281 
282     @Test(expected = ConfigParser.ParsingException.class)
283     public void testReadURLException() throws Exception
284     {
285         instance.read(newTestFile(BAD_INI_PATH).toURI().toURL());
286     }
287 
288     @Test public void testSections() throws Exception
289     {
290         instance.addSection(SECTION);
291         assertEquals(1, instance.sections().size());
292         for (int i = 0; i < 10; i++)
293         {
294             instance.addSection(SECTION + i);
295         }
296 
297         assertEquals(11, instance.sections().size());
298     }
299 
300     @Test public void testSet() throws Exception
301     {
302         instance.addSection(SECTION);
303         instance.set(SECTION, OPTION, "dummy");
304         assertEquals("dummy", instance.getIni().get(SECTION).get(OPTION));
305         assertTrue(instance.hasOption(SECTION, OPTION));
306         instance.set(SECTION, OPTION, null);
307         assertFalse(instance.hasOption(SECTION, OPTION));
308     }
309 
310     @Test(expected = ConfigParser.NoSectionException.class)
311     public void testSetNoSection() throws Exception
312     {
313         instance.set(SECTION, OPTION, "dummy");
314     }
315 
316     @Test public void testWrite() throws Exception
317     {
318         File input = newTestFile(DWARFS_PATH);
319         File output = new File(TEST_WORK_PATH, input.getName());
320 
321         instance.read(input);
322         instance.write(output);
323         checkWrite(output);
324         instance.write(new FileWriter(output));
325         checkWrite(output);
326         instance.write(new FileOutputStream(output));
327         checkWrite(output);
328     }
329 
330     protected void checkEquals(Dwarf expected, String sectionName) throws Exception
331     {
332         assertEquals("" + expected.getAge(), instance.get(sectionName, Dwarf.PROP_AGE));
333         assertEquals("" + expected.getHeight(), instance.get(sectionName, Dwarf.PROP_HEIGHT));
334         assertEquals("" + expected.getWeight(), instance.get(sectionName, Dwarf.PROP_WEIGHT));
335         assertEquals("" + expected.getHomePage(), instance.get(sectionName, Dwarf.PROP_HOME_PAGE.toLowerCase()));
336         assertEquals("" + expected.getHomeDir(), instance.get(sectionName, Dwarf.PROP_HOME_DIR.toLowerCase()));
337     }
338 
339     protected File newTestFile(String path)
340     {
341         return new File(TEST_DATA_PATH, path);
342     }
343 
344     protected void readDwarfs() throws Exception
345     {
346         instance.read(newTestFile(DWARFS_PATH));
347     }
348 
349     private void checkEquals(Map<String, String> a, Map<String, String> b) throws Exception
350     {
351         if (a == null)
352         {
353             assertNull(b);
354         }
355         else
356         {
357             assertEquals(a.size(), b.size());
358             for (String key : a.keySet())
359             {
360                 assertEquals(a.get(key), b.get(key));
361             }
362         }
363     }
364 
365     private void checkWrite(File file) throws Exception
366     {
367         ConfigParser saved = new ConfigParser(instance.defaults());
368 
369         saved.read(file);
370         checkEquals(instance.getIni().getDefaultSection(), saved.getIni().getDefaultSection());
371         assertEquals(instance.sections().size(), saved.sections().size());
372         for (String sectionName : instance.sections())
373         {
374             checkEquals(instance.getIni().get(sectionName), saved.getIni().get(sectionName));
375         }
376     }
377 
378     @SuppressWarnings("empty-statement")
379     private void requireMissingOptionException(String sectionName, String optionName) throws Exception
380     {
381         try
382         {
383             instance.get(sectionName, optionName);
384             fail();
385         }
386         catch (ConfigParser.InterpolationMissingOptionException x)
387         {
388             ;
389         }
390     }
391 }