001/*
002 * Copyright 2005,2009 Ivan SZKIBA
003 *
004 * Licensed under the Apache License, Version 2.0 (the "License");
005 * you may not use this file except in compliance with the License.
006 * You may obtain a copy of the License at
007 *
008 *      http://www.apache.org/licenses/LICENSE-2.0
009 *
010 * Unless required by applicable law or agreed to in writing, software
011 * distributed under the License is distributed on an "AS IS" BASIS,
012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013 * See the License for the specific language governing permissions and
014 * limitations under the License.
015 */
016package org.ini4j;
017
018import org.ini4j.sample.Dwarf;
019import org.ini4j.sample.DwarfBean;
020import org.ini4j.sample.Dwarfs;
021
022import org.ini4j.test.DwarfsData;
023import org.ini4j.test.DwarfsData.DwarfData;
024import org.ini4j.test.Helper;
025
026import static org.junit.Assert.assertEquals;
027import static org.junit.Assert.assertNotNull;
028import static org.junit.Assert.assertNull;
029import static org.junit.Assert.assertTrue;
030
031import org.junit.Test;
032
033import java.net.URI;
034
035public class BasicProfileTest extends Ini4jCase
036{
037    private static final String SECTION = "section";
038    private static final String NUMBER = "number";
039    private static final String SINGLE = "single";
040    private static final String SOLO = "solo";
041    private static final String LOCATION = "location";
042    private static final String LOCATION_1 = "http://www.ini4j.org";
043    private static final String LOCATION_2 = "http://ini4j.org";
044
045    /*
046     * thanx to Gary Pampara for bug report
047     */
048    @Test public void bug_2817403() throws Exception
049    {
050        BasicProfile prof = new BasicProfile();
051        Profile.Section sec = prof.add("section");
052
053        sec.add("player.name", "Joe");
054        sec.add("player.greeting", "Hi ${player.name}!");
055        sec.add("player.domain", "foo.bar");
056        sec.add("player.email", "${player.name}@${player.domain}");
057
058        //
059        assertEquals("Joe", sec.fetch("player.name"));
060        assertEquals("Hi Joe!", sec.fetch("player.greeting"));
061        assertEquals("foo.bar", sec.fetch("player.domain"));
062        assertEquals("Joe@foo.bar", sec.fetch("player.email"));
063
064        //
065        sec = prof.add("other");
066        sec.add("option", "${section/player.name}");
067        assertEquals("Joe", sec.fetch("option"));
068        sec.put("option", "${section/player.email}");
069        assertEquals("Joe@foo.bar", sec.fetch("option"));
070        sec.put("option2", "${option} ${section/player.name} ${section/player.domain}");
071        assertEquals("Joe@foo.bar Joe foo.bar", sec.fetch("option2"));
072    }
073
074    @Test public void testAddPut()
075    {
076        Profile prof = new BasicProfile();
077
078        prof.add(SECTION, Dwarf.PROP_AGE, DwarfsData.sneezy.age);
079        prof.put(SECTION, Dwarf.PROP_HEIGHT, DwarfsData.sneezy.height);
080        prof.add(SECTION, Dwarf.PROP_HOME_DIR, DwarfsData.sneezy.homeDir);
081        prof.add(SECTION, Dwarf.PROP_WEIGHT, DwarfsData.sneezy.weight);
082        prof.put(SECTION, Dwarf.PROP_HOME_PAGE, null);
083        prof.put(SECTION, Dwarf.PROP_HOME_PAGE, DwarfsData.sneezy.homePage);
084        prof.add(SECTION, Dwarf.PROP_FORTUNE_NUMBER, DwarfsData.sneezy.fortuneNumber[0]);
085        prof.add(SECTION, Dwarf.PROP_FORTUNE_NUMBER, DwarfsData.sneezy.fortuneNumber[1]);
086        prof.add(SECTION, Dwarf.PROP_FORTUNE_NUMBER, DwarfsData.sneezy.fortuneNumber[2]);
087        prof.add(SECTION, Dwarf.PROP_FORTUNE_NUMBER, DwarfsData.sneezy.fortuneNumber[3]);
088        Helper.assertEquals(DwarfsData.sneezy, prof.get(SECTION).as(Dwarf.class));
089        assertNotNull(prof.remove(SECTION, Dwarf.PROP_FORTUNE_NUMBER));
090        assertEquals(0, prof.get(SECTION).length(Dwarf.PROP_FORTUNE_NUMBER));
091        assertNotNull(prof.remove(SECTION));
092        assertNull(prof.remove(SECTION, Dwarf.PROP_FORTUNE_NUMBER));
093    }
094
095    @Test public void testFirstUpper()
096    {
097        BasicProfile prof = new BasicProfile(true, true);
098        DwarfsRW dwarfs = prof.as(DwarfsRW.class);
099
100        dwarfs.setBashful(DwarfsData.bashful);
101        assertTrue(prof.containsKey("Bashful"));
102        assertNotNull(dwarfs.getBashful());
103    }
104
105    @Test public void testFromToAs() throws Exception
106    {
107        BasicProfile prof = new BasicProfile();
108
109        Helper.addDwarfs(prof);
110        fromToAs(prof, DwarfsData.bashful);
111        fromToAs(prof, DwarfsData.doc);
112        fromToAs(prof, DwarfsData.dopey);
113        fromToAs(prof, DwarfsData.grumpy);
114        fromToAs(prof, DwarfsData.happy);
115        fromToAs(prof, DwarfsData.sleepy);
116        fromToAs(prof, DwarfsData.sneezy);
117
118        //
119        DwarfsRW dwarfs = prof.as(DwarfsRW.class);
120
121        Helper.assertEquals(DwarfsData.bashful, dwarfs.getBashful());
122        Helper.assertEquals(DwarfsData.doc, dwarfs.getDoc());
123        Helper.assertEquals(DwarfsData.dopey, dwarfs.getDopey());
124        Helper.assertEquals(DwarfsData.grumpy, dwarfs.getGrumpy());
125        Helper.assertEquals(DwarfsData.happy, dwarfs.getHappy());
126        Helper.assertEquals(DwarfsData.sleepy, dwarfs.getSleepy());
127        Helper.assertEquals(DwarfsData.sneezy, dwarfs.getSneezy());
128
129        //
130        prof.remove(Dwarfs.PROP_BASHFUL);
131        assertNull(prof.get(Dwarfs.PROP_BASHFUL));
132        assertEquals(0, prof.length(Dwarfs.PROP_BASHFUL));
133        assertNull(dwarfs.getBashful());
134        dwarfs.setBashful(DwarfsData.dopey);
135        Helper.assertEquals(DwarfsData.dopey, dwarfs.getBashful());
136    }
137
138    @Test public void testIniGetFetch()
139    {
140        Profile prof = new BasicProfile();
141        Profile.Section sec = Helper.addDwarf(prof, DwarfsData.dopey);
142
143        Helper.addDwarf(prof, DwarfsData.bashful);
144        Helper.addDwarf(prof, DwarfsData.doc);
145        assertEquals(sec.get(Dwarf.PROP_AGE), prof.get(Dwarfs.PROP_DOPEY, Dwarf.PROP_AGE));
146        assertEquals(DwarfsData.dopey.age, (int) prof.get(Dwarfs.PROP_DOPEY, Dwarf.PROP_AGE, int.class));
147        assertEquals(sec.get(Dwarf.PROP_WEIGHT), prof.get(Dwarfs.PROP_DOPEY, Dwarf.PROP_WEIGHT));
148        assertEquals(DwarfsData.dopey.weight, prof.fetch(Dwarfs.PROP_DOPEY, Dwarf.PROP_WEIGHT, double.class), Helper.DELTA);
149        assertEquals(sec.fetch(Dwarf.PROP_HEIGHT), prof.fetch(Dwarfs.PROP_DOPEY, Dwarf.PROP_HEIGHT));
150        assertEquals(DwarfsData.dopey.weight, prof.fetch(Dwarfs.PROP_DOPEY, Dwarf.PROP_WEIGHT, double.class), Helper.DELTA);
151        assertEquals(sec.fetch(Dwarf.PROP_HOME_PAGE), prof.fetch(Dwarfs.PROP_DOPEY, Dwarf.PROP_HOME_PAGE));
152        assertEquals(DwarfsData.dopey.homePage, prof.fetch(Dwarfs.PROP_DOPEY, Dwarf.PROP_HOME_PAGE, URI.class));
153
154        // nulls
155        assertNull(prof.get(SECTION, Dwarf.PROP_AGE));
156        assertEquals(0, (int) prof.get(SECTION, Dwarf.PROP_AGE, int.class));
157        assertNull(prof.get(SECTION, Dwarf.PROP_WEIGHT));
158        assertEquals(0.0, prof.fetch(SECTION, Dwarf.PROP_WEIGHT, double.class), Helper.DELTA);
159        assertNull(prof.fetch(SECTION, Dwarf.PROP_HEIGHT));
160        assertEquals(0.0, prof.fetch(SECTION, Dwarf.PROP_WEIGHT, double.class), Helper.DELTA);
161        assertNull(prof.fetch(SECTION, Dwarf.PROP_HOME_PAGE));
162        assertNull(prof.fetch(SECTION, Dwarf.PROP_HOME_PAGE, URI.class));
163    }
164
165    @Test public void testOptionArray() throws Exception
166    {
167        BasicProfile prof = new BasicProfile();
168        Profile.Section sec = prof.add(SECTION);
169
170        sec.add(NUMBER, 1);
171        sec.add(LOCATION, LOCATION_1);
172        sec.add(NUMBER, 2);
173        sec.add(LOCATION, LOCATION_2);
174        Section s = prof.get(SECTION).as(Section.class);
175
176        assertNotNull(s);
177        assertEquals(2, s.getNumber().length);
178        assertEquals(1, s.getNumber()[0]);
179        assertEquals(2, s.getNumber()[1]);
180        assertEquals(2, s.getLocation().length);
181        assertEquals(new URI(LOCATION_1), s.getLocation()[0]);
182        assertNull(s.getMissing());
183        int[] numbers = new int[] { 1, 2, 3, 4, 5 };
184
185        s.setNumber(numbers);
186        assertEquals(5, sec.length(NUMBER));
187    }
188
189    @Test public void testResolve() throws Exception
190    {
191        BasicProfile prof = new BasicProfile();
192
193        Helper.addDwarf(prof, DwarfsData.happy);
194        Profile.Section doc = Helper.addDwarf(prof, DwarfsData.doc);
195        StringBuilder buffer;
196        String input;
197
198        // other sections's value
199        input = "${happy/weight}";
200        buffer = new StringBuilder(input);
201
202        prof.resolve(buffer, doc);
203        assertEquals(String.valueOf(DwarfsData.happy.weight), buffer.toString());
204
205        // same sections's value
206        input = "${height}";
207        buffer = new StringBuilder(input);
208
209        prof.resolve(buffer, doc);
210        assertEquals(String.valueOf(DwarfsData.doc.height), buffer.toString());
211
212        // system property
213        input = "${@prop/user.home}";
214        buffer = new StringBuilder(input);
215
216        prof.resolve(buffer, doc);
217        assertEquals(System.getProperty("user.home"), buffer.toString());
218
219        // system environment
220        input = "${@env/PATH}";
221        buffer = new StringBuilder(input);
222        try
223        {
224            prof.resolve(buffer, doc);
225            assertEquals(System.getenv("PATH"), buffer.toString());
226        }
227        catch (Error e)
228        {
229            // retroweaver + JDK 1.4 throws Error on getenv
230        }
231
232        // unknown variable
233        input = "${no such name}";
234        buffer = new StringBuilder(input);
235
236        prof.resolve(buffer, doc);
237        assertEquals(input, buffer.toString());
238
239        // unknown section's unknown variable
240        input = "${no such section/no such name}";
241        buffer = new StringBuilder(input);
242
243        prof.resolve(buffer, doc);
244        assertEquals(input, buffer.toString());
245
246        // other section's unknown variable
247        input = "${happy/no such name}";
248        buffer = new StringBuilder(input);
249
250        prof.resolve(buffer, doc);
251        assertEquals(input, buffer.toString());
252
253        // small input
254        input = "${";
255        buffer = new StringBuilder(input);
256
257        prof.resolve(buffer, doc);
258        assertEquals(input, buffer.toString());
259
260        // incorrect references
261        input = "${doc/weight";
262        buffer = new StringBuilder(input);
263
264        prof.resolve(buffer, doc);
265        assertEquals(input, buffer.toString());
266
267        // empty references
268        input = "jim${}";
269        buffer = new StringBuilder(input);
270
271        prof.resolve(buffer, doc);
272        assertEquals(input, buffer.toString());
273
274        // escaped references
275        input = "${happy/weight}";
276        buffer = new StringBuilder(input);
277
278        prof.resolve(buffer, doc);
279        assertEquals("" + DwarfsData.happy.weight, buffer.toString());
280        input = "\\" + input;
281        buffer = new StringBuilder(input);
282
283        prof.resolve(buffer, doc);
284        assertEquals(input, buffer.toString());
285    }
286
287    @Test public void testResolveArray() throws Exception
288    {
289        StringBuilder buffer;
290        BasicProfile prof = new BasicProfile();
291
292        prof.add(SECTION).add(NUMBER, 1);
293        prof.add(SECTION).add(NUMBER, 2);
294        Profile.Section sec = prof.get(SECTION);
295
296        //
297        buffer = new StringBuilder("${section[0]/number}");
298        prof.resolve(buffer, sec);
299        assertEquals("1", buffer.toString());
300        buffer = new StringBuilder("${section[1]/number}");
301        prof.resolve(buffer, sec);
302        assertEquals("2", buffer.toString());
303        buffer = new StringBuilder("${section[0]/number}-${section[1]/number}");
304        prof.resolve(buffer, sec);
305        assertEquals("1-2", buffer.toString());
306
307        //
308        prof.clear();
309        sec = prof.add(SECTION);
310        sec.add(NUMBER, 1);
311        sec.add(NUMBER, 2);
312        sec = prof.get(SECTION);
313        assertEquals(2, sec.length(NUMBER));
314        buffer = new StringBuilder("${number}");
315        prof.resolve(buffer, sec);
316        assertEquals("2", buffer.toString());
317        buffer = new StringBuilder("${number[0]}-${section/number[1]}-${section[0]/number}");
318        prof.resolve(buffer, sec);
319        assertEquals("1-2-2", buffer.toString());
320    }
321
322    @Test public void testSectionArray() throws Exception
323    {
324        BasicProfile prof = new BasicProfile();
325
326        prof.add(SECTION).add(NUMBER, 1);
327        prof.add(SECTION).add(NUMBER, 2);
328        prof.add(SINGLE).add(NUMBER, 3);
329        Global g = prof.as(Global.class);
330
331        assertNotNull(g);
332        assertEquals(2, g.getSection().length);
333        assertEquals(1, g.getSingle().length);
334        assertNull(g.getMissing());
335        assertTrue(g.hasSection());
336    }
337
338    @Test public void testSetter()
339    {
340        BasicProfile prof = new BasicProfile();
341        Global g = prof.as(Global.class);
342        Section s1 = new SectionBean();
343        Section s2 = new SectionBean();
344        Section[] all = new Section[] { s1, s2 };
345
346        g.setSection(all);
347        assertEquals(2, prof.length("section"));
348        assertNull(g.getSolo());
349        g.setSolo(s1);
350        assertNotNull(g.getSolo());
351        g.setSolo(null);
352        assertEquals(0, prof.length("solo"));
353    }
354
355    private void fromToAs(BasicProfile prof, DwarfData dwarf)
356    {
357        Profile.Section sec = prof.get(dwarf.name);
358        Profile.Section dup = new BasicProfileSection(prof, SECTION);
359        DwarfBean bean = new DwarfBean();
360
361        sec.to(bean);
362        Helper.assertEquals(dwarf, bean);
363        dup.from(bean);
364        bean = new DwarfBean();
365        dup.to(bean);
366        Helper.assertEquals(dwarf, bean);
367        Dwarf proxy = dup.as(Dwarf.class);
368
369        Helper.assertEquals(dwarf, proxy);
370        dup.clear();
371        sec.to(proxy);
372        Helper.assertEquals(dwarf, proxy);
373        prof.remove(dup);
374    }
375
376    public static interface DwarfsRW extends Dwarfs
377    {
378        void setBashful(Dwarf value);
379    }
380
381    public static interface Global
382    {
383        Section[] getMissing();
384
385        Section[] getSection();
386
387        void setSection(Section[] value);
388
389        Section[] getSingle();
390
391        Section getSolo();
392
393        void setSolo(Section value);
394
395        boolean hasSection();
396    }
397
398    public static interface Section
399    {
400        URI[] getLocation();
401
402        void setLocation(URI[] value);
403
404        String[] getMissing();
405
406        void setMissing(String[] value);
407
408        int[] getNumber();
409
410        void setNumber(int[] value);
411    }
412
413    public static class SectionBean implements Section
414    {
415        private URI[] _location;
416        private String[] _missing;
417        private int[] _number;
418
419        @Override public URI[] getLocation()
420        {
421            return _location;
422        }
423
424        @Override public void setLocation(URI[] value)
425        {
426            _location = value;
427        }
428
429        @Override public String[] getMissing()
430        {
431            return _missing;
432        }
433
434        @Override public void setMissing(String[] value)
435        {
436            _missing = value;
437        }
438
439        @Override public int[] getNumber()
440        {
441            return _number;
442        }
443
444        @Override public void setNumber(int[] value)
445        {
446            _number = value;
447        }
448    }
449}