1/*
2 *  Licensed to the Apache Software Foundation (ASF) under one or more
3 *  contributor license agreements.  See the NOTICE file distributed with
4 *  this work for additional information regarding copyright ownership.
5 *  The ASF licenses this file to You under the Apache License, Version 2.0
6 *  (the "License"); you may not use this file except in compliance with
7 *  the License.  You may obtain a copy of the License at
8 *
9 *     http://www.apache.org/licenses/LICENSE-2.0
10 *
11 *  Unless required by applicable law or agreed to in writing, software
12 *  distributed under the License is distributed on an "AS IS" BASIS,
13 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 *  See the License for the specific language governing permissions and
15 *  limitations under the License.
16 */
17
18package org.apache.harmony.luni.tests.java.util;
19
20import java.io.BufferedReader;
21import java.io.ByteArrayInputStream;
22import java.io.ByteArrayOutputStream;
23import java.io.IOException;
24import java.io.InputStream;
25import java.io.InputStreamReader;
26import java.io.OutputStreamWriter;
27import java.io.PrintStream;
28import java.io.PrintWriter;
29import java.io.Reader;
30import java.io.Writer;
31import java.util.ArrayList;
32import java.util.Arrays;
33import java.util.Enumeration;
34import java.util.InvalidPropertiesFormatException;
35import java.util.Iterator;
36import java.util.List;
37import java.util.NoSuchElementException;
38import java.util.Properties;
39import java.util.Scanner;
40import java.util.Set;
41
42import tests.support.resource.Support_Resources;
43
44public class PropertiesTest extends junit.framework.TestCase {
45
46    Properties tProps;
47
48    byte[] propsFile;
49
50    /**
51     * @tests java.util.Properties#Properties()
52     */
53    public void test_Constructor() {
54        // Test for method java.util.Properties()
55        Properties p = new Properties();
56        // do something to avoid getting a variable unused warning
57        p.clear();
58        assertTrue("Created incorrect Properties", true);
59    }
60
61    public void test_loadLjava_io_InputStream_NPE() throws Exception {
62        Properties p = new Properties();
63        try {
64            p.load((InputStream) null);
65            fail("should throw NullPointerException");
66        } catch (NullPointerException e) {
67            // Expected
68        }
69    }
70
71    public void test_loadsave() throws Exception{
72        Properties p = new Properties();
73        try {
74            p.load((InputStream) null);
75            fail("should throw NPE");
76        } catch (NullPointerException npe) {
77        	// expected
78        }
79    }
80
81    /**
82     * @tests java.util.Properties#Properties(java.util.Properties)
83     */
84    public void test_ConstructorLjava_util_Properties() {
85        Properties systemProperties = System.getProperties();
86        Properties properties = new Properties(systemProperties);
87        Enumeration<?> propertyNames = systemProperties.propertyNames();
88        String propertyName = null;
89        while (propertyNames.hasMoreElements()) {
90            propertyName = (String) propertyNames.nextElement();
91            assertEquals("failed to construct correct properties",
92                    systemProperties.get(propertyName), properties
93                            .getProperty(propertyName));
94        }
95    }
96
97    /**
98     * @tests java.util.Properties#getProperty(java.lang.String)
99     */
100    public void test_getPropertyLjava_lang_String() {
101        // Test for method java.lang.String
102        // java.util.Properties.getProperty(java.lang.String)
103        assertEquals("Did not retrieve property", "this is a test property",
104                ((String) tProps.getProperty("test.prop")));
105    }
106
107    /**
108     * @tests java.util.Properties#getProperty(java.lang.String,
109     *        java.lang.String)
110     */
111    public void test_getPropertyLjava_lang_StringLjava_lang_String() {
112        // Test for method java.lang.String
113        // java.util.Properties.getProperty(java.lang.String, java.lang.String)
114        assertEquals("Did not retrieve property", "this is a test property",
115                ((String) tProps.getProperty("test.prop", "Blarg")));
116        assertEquals("Did not return default value", "Gabba", ((String) tProps
117                .getProperty("notInThere.prop", "Gabba")));
118    }
119
120    /**
121     * @tests java.util.Properties#getProperty(java.lang.String)
122     */
123    public void test_getPropertyLjava_lang_String2() {
124        // regression test for HARMONY-3518
125        MyProperties props = new MyProperties();
126        assertNull(props.getProperty("key"));
127    }
128
129    /**
130     * @tests java.util.Properties#getProperty(java.lang.String,
131     *        java.lang.String)
132     */
133    public void test_getPropertyLjava_lang_StringLjava_lang_String2() {
134        // regression test for HARMONY-3518
135        MyProperties props = new MyProperties();
136        assertEquals("defaultValue", props.getProperty("key", "defaultValue"));
137    }
138
139    // regression testing for HARMONY-3518
140    static class MyProperties extends Properties {
141        public synchronized Object get(Object key) {
142            return getProperty((String) key); // assume String
143        }
144    }
145
146    /**
147     * @tests java.util.Properties#list(java.io.PrintStream)
148     */
149    public void test_listLjava_io_PrintStream() {
150        ByteArrayOutputStream baos = new ByteArrayOutputStream();
151        PrintStream ps = new PrintStream(baos);
152        Properties myProps = new Properties();
153        myProps.setProperty("Abba", "Cadabra");
154        myProps.setProperty("Open", "Sesame");
155        myProps.setProperty("LongProperty",
156                "a long long long long long long long property");
157        myProps.list(ps);
158        ps.flush();
159        String propList = baos.toString();
160        assertTrue("Property list innacurate",
161                propList.indexOf("Abba=Cadabra") >= 0);
162        assertTrue("Property list innacurate",
163                propList.indexOf("Open=Sesame") >= 0);
164        assertTrue("property list do not conatins \"...\"", propList
165                .indexOf("...") != -1);
166
167        ps = null;
168        try {
169            myProps.list(ps);
170            fail("should throw NullPointerException");
171        } catch (NullPointerException e) {
172            // expected
173        }
174    }
175
176    /**
177     * @tests java.util.Properties#list(java.io.PrintWriter)
178     */
179    public void test_listLjava_io_PrintWriter() {
180        ByteArrayOutputStream baos = new ByteArrayOutputStream();
181        PrintWriter pw = new PrintWriter(baos);
182        Properties myProps = new Properties();
183        myProps.setProperty("Abba", "Cadabra");
184        myProps.setProperty("Open", "Sesame");
185        myProps.setProperty("LongProperty",
186                "a long long long long long long long property");
187        myProps.list(pw);
188        pw.flush();
189        String propList = baos.toString();
190        assertTrue("Property list innacurate",
191                propList.indexOf("Abba=Cadabra") >= 0);
192        assertTrue("Property list innacurate",
193                propList.indexOf("Open=Sesame") >= 0);
194        pw = null;
195        try {
196            myProps.list(pw);
197            fail("should throw NullPointerException");
198        } catch (NullPointerException e) {
199            // expected
200        }
201    }
202
203    /**
204     * @tests java.util.Properties#load(java.io.InputStream)
205     */
206    public void test_loadLjava_io_InputStream() {
207        // Test for method void java.util.Properties.load(java.io.InputStream)
208        Properties prop = null;
209        try {
210            InputStream is;
211            prop = new Properties();
212            prop.load(is = new ByteArrayInputStream(writeProperties()));
213            is.close();
214        } catch (Exception e) {
215            fail("Exception during load test : " + e.getMessage());
216        }
217        assertEquals("Failed to load correct properties", "harmony.tests", prop
218                .getProperty("test.pkg"));
219        assertNull("Load failed to parse incorrectly", prop
220                .getProperty("commented.entry"));
221
222        prop = new Properties();
223		try {
224			prop.load(new ByteArrayInputStream("=".getBytes()));
225		} catch (IOException e) {
226			// expected
227		}
228        assertTrue("Failed to add empty key", prop.get("").equals(""));
229
230        prop = new Properties();
231        try {
232			prop.load(new ByteArrayInputStream(" = ".getBytes()));
233		} catch (IOException e) {
234			// expected
235		}
236        assertTrue("Failed to add empty key2", prop.get("").equals(""));
237
238		prop = new Properties();
239		try {
240			prop.load(new ByteArrayInputStream(" a= b".getBytes()));
241		} catch (IOException e) {
242			// expected
243		}
244		assertEquals("Failed to ignore whitespace", "b", prop.get("a"));
245
246		prop = new Properties();
247		try {
248			prop.load(new ByteArrayInputStream(" a b".getBytes()));
249		} catch (IOException e) {
250			// expected
251		}
252		assertEquals("Failed to interpret whitespace as =", "b", prop.get("a"));
253
254		prop = new Properties();
255		try {
256			prop.load(new ByteArrayInputStream("#\u008d\u00d2\na=\u008d\u00d3"
257					.getBytes("ISO8859_1")));
258		} catch (IOException e) {
259			// expected
260		}
261		assertEquals("Failed to parse chars >= 0x80", "\u008d\u00d3", prop
262				.get("a"));
263
264		prop = new Properties();
265		try {
266			prop.load(new ByteArrayInputStream(
267					"#properties file\r\nfred=1\r\n#last comment"
268							.getBytes("ISO8859_1")));
269		} catch (IOException e) {
270			// expected
271		} catch (IndexOutOfBoundsException e) {
272			fail("IndexOutOfBoundsException when last line is a comment with no line terminator");
273		}
274        assertEquals("Failed to load when last line contains a comment", "1",
275                prop.get("fred"));
276    }
277
278    /**
279	 * @tests java.util.Properties#load(java.io.InputStream)
280	 */
281    public void test_loadLjava_io_InputStream_subtest0() {
282        try {
283            InputStream is = Support_Resources
284                    .getStream("hyts_PropertiesTest.properties");
285            Properties props = new Properties();
286            props.load(is);
287            is.close();
288            assertEquals("1", "\n \t \f", props.getProperty(" \r"));
289            assertEquals("2", "a", props.getProperty("a"));
290            assertEquals("3", "bb as,dn   ", props.getProperty("b"));
291            assertEquals("4", ":: cu", props.getProperty("c\r \t\nu"));
292            assertEquals("5", "bu", props.getProperty("bu"));
293            assertEquals("6", "d\r\ne=e", props.getProperty("d"));
294            assertEquals("7", "fff", props.getProperty("f"));
295            assertEquals("8", "g", props.getProperty("g"));
296            assertEquals("9", "", props.getProperty("h h"));
297            assertEquals("10", "i=i", props.getProperty(" "));
298            assertEquals("11", "   j", props.getProperty("j"));
299            assertEquals("12", "   c", props.getProperty("space"));
300            assertEquals("13", "\\", props.getProperty("dblbackslash"));
301        } catch (IOException e) {
302            fail("Unexpected: " + e);
303        }
304    }
305
306    /**
307     * @throws IOException
308     * @tests java.util.Properties#load(java.io.Reader)
309     * @since 1.6
310     */
311    public void test_loadLjava_io_Reader() throws IOException {
312        Properties prop = null;
313        try {
314            InputStream is;
315            prop = new Properties();
316            is = new ByteArrayInputStream(writeProperties());
317            prop.load(new InputStreamReader(is));
318            is.close();
319        } catch (Exception e) {
320            fail("Exception during load test : " + e.getMessage());
321        }
322        assertEquals("Failed to load correct properties", "harmony.tests", prop
323                .getProperty("test.pkg"));
324        assertNull("Load failed to parse incorrectly", prop
325                .getProperty("commented.entry"));
326
327        prop = new Properties();
328        prop.load(new ByteArrayInputStream("=".getBytes()));
329        assertEquals("Failed to add empty key", "", prop.get(""));
330
331        prop = new Properties();
332        prop.load(new ByteArrayInputStream(" = ".getBytes()));
333        assertEquals("Failed to add empty key2", "", prop.get(""));
334
335        prop = new Properties();
336        prop.load(new ByteArrayInputStream(" a= b".getBytes()));
337        assertEquals("Failed to ignore whitespace", "b", prop.get("a"));
338
339        prop = new Properties();
340        prop.load(new ByteArrayInputStream(" a b".getBytes()));
341        assertEquals("Failed to interpret whitespace as =", "b", prop.get("a"));
342
343        prop = new Properties();
344        prop.load(new ByteArrayInputStream("#comment\na=value"
345                .getBytes("UTF-8")));
346        assertEquals("value", prop.getProperty("a"));
347
348        prop = new Properties();
349        prop.load(new InputStreamReader(new ByteArrayInputStream(
350                "#\u008d\u00d2\na=\u008d\u00d3".getBytes("UTF-8"))));
351        try {
352            prop
353                    .load(new InputStreamReader(new ByteArrayInputStream(
354                            "#\u008d\u00d2\na=\\\\u008d\\\\\\uu00d3"
355                                    .getBytes("UTF-8"))));
356            fail("Should throw IllegalArgumentException");
357        } catch (IllegalArgumentException e) {
358            // expected
359        }
360
361        prop = new Properties();
362        try {
363            prop.load(new InputStreamReader(new ByteArrayInputStream(
364                    "#properties file\r\nfred=1\r\n#last comment"
365                            .getBytes("ISO8859_1"))));
366        } catch (IndexOutOfBoundsException e) {
367            fail("IndexOutOfBoundsException when last line is a comment with no line terminator");
368        }
369        assertEquals("Failed to load when last line contains a comment", "1",
370                prop.get("fred"));
371
372        // Regression tests for HARMONY-5414
373        prop = new Properties();
374        prop.load(new ByteArrayInputStream("a=\\u1234z".getBytes()));
375
376        prop = new Properties();
377        try {
378            prop.load(new ByteArrayInputStream("a=\\u123".getBytes()));
379            fail("should throw IllegalArgumentException");
380        } catch (IllegalArgumentException e) {
381            // Expected
382        }
383
384        prop = new Properties();
385        try {
386            prop.load(new ByteArrayInputStream("a=\\u123z".getBytes()));
387            fail("should throw IllegalArgumentException");
388        } catch (IllegalArgumentException expected) {
389            // Expected
390        }
391
392        prop = new Properties();
393        Properties expected = new Properties();
394        expected.put("a", "\u0000");
395        prop.load(new ByteArrayInputStream("a=\\".getBytes()));
396        assertEquals("Failed to read trailing slash value", expected, prop);
397
398        prop = new Properties();
399        expected = new Properties();
400        expected.put("a", "\u1234\u0000");
401        prop.load(new ByteArrayInputStream("a=\\u1234\\".getBytes()));
402        assertEquals("Failed to read trailing slash value #2", expected, prop);
403
404        prop = new Properties();
405        expected = new Properties();
406        expected.put("a", "q");
407        prop.load(new ByteArrayInputStream("a=\\q".getBytes()));
408        assertEquals("Failed to read slash value #3", expected, prop);
409    }
410
411    /**
412     * @tests java.util.Properties#load(java.io.InputStream)
413     */
414    public void test_loadLjava_io_InputStream_Special() throws IOException {
415        // Test for method void java.util.Properties.load(java.io.InputStream)
416        Properties prop = null;
417        prop = new Properties();
418        prop.load(new ByteArrayInputStream("=".getBytes()));
419        assertTrue("Failed to add empty key", prop.get("").equals(""));
420
421        prop = new Properties();
422        prop.load(new ByteArrayInputStream("=\r\n".getBytes()));
423        assertTrue("Failed to add empty key", prop.get("").equals(""));
424
425        prop = new Properties();
426        prop.load(new ByteArrayInputStream("=\n\r".getBytes()));
427        assertTrue("Failed to add empty key", prop.get("").equals(""));
428    }
429
430    /**
431     * @throws IOException
432     * @tests java.util.Properties#load(java.io.Reader)
433     * @since 1.6
434     */
435    public void test_loadLjava_io_Reader_subtest0() throws IOException {
436        InputStream is = Support_Resources
437                .getStream("hyts_PropertiesTest.properties");
438        Properties props = new Properties();
439        props.load(new InputStreamReader(is));
440        is.close();
441        assertEquals("1", "\n \t \f", props.getProperty(" \r"));
442        assertEquals("2", "a", props.getProperty("a"));
443        assertEquals("3", "bb as,dn   ", props.getProperty("b"));
444        assertEquals("4", ":: cu", props.getProperty("c\r \t\nu"));
445        assertEquals("5", "bu", props.getProperty("bu"));
446        assertEquals("6", "d\r\ne=e", props.getProperty("d"));
447        assertEquals("7", "fff", props.getProperty("f"));
448        assertEquals("8", "g", props.getProperty("g"));
449        assertEquals("9", "", props.getProperty("h h"));
450        assertEquals("10", "i=i", props.getProperty(" "));
451        assertEquals("11", "   j", props.getProperty("j"));
452        assertEquals("12", "   c", props.getProperty("space"));
453        assertEquals("13", "\\", props.getProperty("dblbackslash"));
454    }
455
456    /**
457     * @tests java.util.Properties#propertyNames()
458     */
459    public void test_propertyNames() {
460        Properties myPro = new Properties(tProps);
461        Enumeration names = myPro.propertyNames();
462        int i = 0;
463        while (names.hasMoreElements()) {
464            ++i;
465            String p = (String) names.nextElement();
466            assertTrue("Incorrect names returned", p.equals("test.prop")
467                    || p.equals("bogus.prop"));
468        }
469
470        // cast Enumeration to Iterator
471        Iterator iterator = (Iterator) names;
472        assertFalse(iterator.hasNext());
473        try {
474            iterator.next();
475            fail("should throw NoSuchElementException");
476        } catch (NoSuchElementException e) {
477            // Expected
478        }
479    }
480
481    public void test_propertyNames_sequence() {
482        Properties parent = new Properties();
483        parent.setProperty("parent.a.key", "parent.a.value");
484        parent.setProperty("parent.b.key", "parent.b.value");
485
486        Enumeration<?> names = parent.propertyNames();
487        assertEquals("parent.a.key", names.nextElement());
488        assertEquals("parent.b.key", names.nextElement());
489        assertFalse(names.hasMoreElements());
490
491        Properties current = new Properties(parent);
492        current.setProperty("current.a.key", "current.a.value");
493        current.setProperty("current.b.key", "current.b.value");
494
495        names = current.propertyNames();
496        assertEquals("parent.a.key", names.nextElement());
497        assertEquals("current.b.key", names.nextElement());
498        assertEquals("parent.b.key", names.nextElement());
499        assertEquals("current.a.key", names.nextElement());
500        assertFalse(names.hasMoreElements());
501
502        Properties child = new Properties(current);
503        child.setProperty("child.a.key", "child.a.value");
504        child.setProperty("child.b.key", "child.b.value");
505
506        names = child.propertyNames();
507        assertEquals("parent.a.key", names.nextElement());
508        assertEquals("child.b.key", names.nextElement());
509        assertEquals("current.b.key", names.nextElement());
510        assertEquals("parent.b.key", names.nextElement());
511        assertEquals("child.a.key", names.nextElement());
512        assertEquals("current.a.key", names.nextElement());
513        assertFalse(names.hasMoreElements());
514    }
515
516    /**
517     * @tests {@link java.util.Properties#stringPropertyNames()}
518     * @since 1.6
519     */
520    public void test_stringPropertyNames() {
521        Set<String> set = tProps.stringPropertyNames();
522        assertEquals(2, set.size());
523        assertTrue(set.contains("test.prop"));
524        assertTrue(set.contains("bogus.prop"));
525        assertNotSame(set, tProps.stringPropertyNames());
526
527        set = new Properties().stringPropertyNames();
528        assertEquals(0, set.size());
529
530        set = new Properties(System.getProperties()).stringPropertyNames();
531        assertTrue(set.size() > 0);
532
533        tProps = new Properties(tProps);
534        tProps.put("test.prop", "anotherValue");
535        tProps.put("3rdKey", "3rdValue");
536        set = tProps.stringPropertyNames();
537        assertEquals(3, set.size());
538        assertTrue(set.contains("test.prop"));
539        assertTrue(set.contains("bogus.prop"));
540        assertTrue(set.contains("3rdKey"));
541
542        tProps.put(String.class, "valueOfNonStringKey");
543        set = tProps.stringPropertyNames();
544        assertEquals(3, set.size());
545        assertTrue(set.contains("test.prop"));
546        assertTrue(set.contains("bogus.prop"));
547        assertTrue(set.contains("3rdKey"));
548
549        tProps.put("4thKey", "4thValue");
550        assertEquals(4, tProps.size());
551        assertEquals(3, set.size());
552
553        try {
554            set.add("another");
555            fail("Should throw UnsupportedOperationException");
556        } catch (UnsupportedOperationException e) {
557            // expected
558        }
559    }
560
561    /**
562     * @tests {@link java.util.Properties#stringPropertyNames()}
563     * @since 1.6
564     */
565    public void test_stringPropertyNames_scenario1() {
566        String[] keys = new String[] { "key1", "key2", "key3" };
567        String[] values = new String[] { "value1", "value2", "value3" };
568        List<String> keyList = Arrays.asList(keys);
569
570        Properties properties = new Properties();
571        for (int index = 0; index < keys.length; index++) {
572            properties.setProperty(keys[index], values[index]);
573        }
574
575        properties = new Properties(properties);
576        Set<String> nameSet = properties.stringPropertyNames();
577        assertEquals(keys.length, nameSet.size());
578        Iterator<String> iterator = nameSet.iterator();
579        while (iterator.hasNext()) {
580            assertTrue(keyList.contains(iterator.next()));
581        }
582
583        Enumeration<?> nameEnum = properties.propertyNames();
584        int count = 0;
585        while (nameEnum.hasMoreElements()) {
586            count++;
587            assertTrue(keyList.contains(nameEnum.nextElement()));
588        }
589        assertEquals(keys.length, count);
590
591        properties = new Properties(properties);
592        nameSet = properties.stringPropertyNames();
593        assertEquals(keys.length, nameSet.size());
594        iterator = nameSet.iterator();
595        while (iterator.hasNext()) {
596            assertTrue(keyList.contains(iterator.next()));
597        }
598
599        nameEnum = properties.propertyNames();
600        count = 0;
601        while (nameEnum.hasMoreElements()) {
602            count++;
603            assertTrue(keyList.contains(nameEnum.nextElement()));
604        }
605        assertEquals(keys.length, count);
606    }
607
608    /**
609     * @tests {@link java.util.Properties#stringPropertyNames()}
610     * @since 1.6
611     */
612    public void test_stringPropertyNames_scenario2() {
613        String[] defaultKeys = new String[] { "defaultKey1", "defaultKey2",
614                "defaultKey3", "defaultKey4", "defaultKey5", "defaultKey6" };
615        String[] defaultValues = new String[] { "defaultValue1",
616                "defaultValue2", "defaultValue3", "defaultValue4",
617                "defaultValue5", "defaultValue6" };
618        List<String> keyList = new ArrayList<String>();
619        Properties defaults = new Properties();
620        for (int index = 0; index < 3; index++) {
621            defaults.setProperty(defaultKeys[index], defaultValues[index]);
622            keyList.add(defaultKeys[index]);
623        }
624
625        String[] keys = new String[] { "key1", "key2", "key3" };
626        String[] values = new String[] { "value1", "value2", "value3" };
627        Properties properties = new Properties(defaults);
628        for (int index = 0; index < keys.length; index++) {
629            properties.setProperty(keys[index], values[index]);
630            keyList.add(keys[index]);
631        }
632
633        Set<String> nameSet = properties.stringPropertyNames();
634        assertEquals(keyList.size(), nameSet.size());
635        Iterator<String> iterator = nameSet.iterator();
636        while (iterator.hasNext()) {
637            assertTrue(keyList.contains(iterator.next()));
638        }
639
640        Enumeration<?> nameEnum = properties.propertyNames();
641        int count = 0;
642        while (nameEnum.hasMoreElements()) {
643            count++;
644            assertTrue(keyList.contains(nameEnum.nextElement()));
645        }
646        assertEquals(keyList.size(), count);
647
648        for (int index = 3; index < defaultKeys.length; index++) {
649            defaults.setProperty(defaultKeys[index], defaultValues[index]);
650            keyList.add(defaultKeys[index]);
651        }
652
653        nameSet = properties.stringPropertyNames();
654        assertEquals(keyList.size(), nameSet.size());
655        iterator = nameSet.iterator();
656        while (iterator.hasNext()) {
657            assertTrue(keyList.contains(iterator.next()));
658        }
659
660        nameEnum = properties.propertyNames();
661        count = 0;
662        while (nameEnum.hasMoreElements()) {
663            count++;
664            assertTrue(keyList.contains(nameEnum.nextElement()));
665        }
666        assertEquals(keyList.size(), count);
667    }
668
669    /**
670     * @tests java.util.Properties#save(java.io.OutputStream, java.lang.String)
671     */
672    public void test_saveLjava_io_OutputStreamLjava_lang_String() {
673        // Test for method void java.util.Properties.save(java.io.OutputStream,
674        // java.lang.String)
675        Properties myProps = new Properties();
676        Properties myProps2 = new Properties();
677
678        myProps.setProperty("Property A", "aye");
679        myProps.setProperty("Property B", "bee");
680        myProps.setProperty("Property C", "see");
681
682        try {
683            ByteArrayOutputStream out = new ByteArrayOutputStream();
684            myProps.save(out, "A Header");
685            out.close();
686            ByteArrayInputStream in = new ByteArrayInputStream(out
687                    .toByteArray());
688            myProps2.load(in);
689            in.close();
690        } catch (IOException ioe) {
691            fail("IOException occurred reading/writing file : "
692                    + ioe.getMessage());
693        }
694
695        Enumeration e = myProps.propertyNames();
696        String nextKey;
697        while (e.hasMoreElements()) {
698            nextKey = (String) e.nextElement();
699            assertEquals("Stored property list not equal to original", myProps
700                    .getProperty(nextKey), myProps2.getProperty(nextKey));
701        }
702    }
703
704    /**
705     * @tests java.util.Properties#setProperty(java.lang.String,
706     *        java.lang.String)
707     */
708    public void test_setPropertyLjava_lang_StringLjava_lang_String() {
709        // Test for method java.lang.Object
710        // java.util.Properties.setProperty(java.lang.String, java.lang.String)
711        Properties myProps = new Properties();
712        myProps.setProperty("Yoink", "Yabba");
713        assertEquals("Failed to set property", "Yabba", myProps
714                .getProperty("Yoink"));
715        myProps.setProperty("Yoink", "Gab");
716        assertEquals("Failed to reset property", "Gab", myProps
717                .getProperty("Yoink"));
718    }
719
720    /**
721     * @tests java.util.Properties#store(java.io.OutputStream, java.lang.String)
722     */
723    public void test_storeLjava_io_OutputStreamLjava_lang_String() {
724        // Test for method void java.util.Properties.store(java.io.OutputStream,
725        // java.lang.String)
726        Properties myProps = new Properties();
727        Properties myProps2 = new Properties();
728        Enumeration e;
729        String nextKey;
730
731        myProps.put("Property A", " aye\\\f\t\n\r\b");
732        myProps.put("Property B", "b ee#!=:");
733        myProps.put("Property C", "see");
734
735        try {
736            ByteArrayOutputStream out = new ByteArrayOutputStream();
737            myProps.store(out, "A Header");
738            out.close();
739            ByteArrayInputStream in = new ByteArrayInputStream(out
740                    .toByteArray());
741            myProps2.load(in);
742            in.close();
743        } catch (IOException ioe) {
744            fail("IOException occurred reading/writing file : "
745                    + ioe.getMessage());
746        }
747
748        e = myProps.propertyNames();
749        while (e.hasMoreElements()) {
750            nextKey = (String) e.nextElement();
751            assertTrue("Stored property list not equal to original", myProps2
752                    .getProperty(nextKey).equals(myProps.getProperty(nextKey)));
753        }
754
755    }
756
757    /**
758     * @throws IOException
759     * @tests java.util.Properties#store(java.io.Writer, java.lang.String)
760     * @since 1.6
761     */
762    public void test_storeLjava_io_WriterLjava_lang_String() throws IOException {
763        Properties myProps = new Properties();
764        Properties myProps2 = new Properties();
765
766        myProps.put("Property A", " aye\\\f\t\n\r\b");
767        myProps.put("Property B", "b ee#!=:");
768        myProps.put("Property C", "see");
769
770        ByteArrayOutputStream out = new ByteArrayOutputStream();
771        myProps.store(new OutputStreamWriter(out), "A Header");
772        Scanner scanner = new Scanner(out.toString());
773        assertTrue(scanner.nextLine().startsWith("#A Header"));
774        assertTrue(scanner.nextLine().startsWith("#"));
775        out.close();
776        ByteArrayInputStream in = new ByteArrayInputStream(out.toByteArray());
777        myProps2.load(in);
778        in.close();
779
780        Enumeration e = myProps.propertyNames();
781        String nextKey;
782        while (e.hasMoreElements()) {
783            nextKey = (String) e.nextElement();
784            assertTrue("Stored property list not equal to original", myProps2
785                    .getProperty(nextKey).equals(myProps.getProperty(nextKey)));
786        }
787
788        try {
789            myProps.store((Writer) null, "some comments");
790            fail("Should throw NullPointerException");
791        } catch (NullPointerException e1) {
792            // expected
793        }
794
795        myProps.put(String.class, "wrong type");
796        try {
797            myProps.store(new OutputStreamWriter(new ByteArrayOutputStream()),
798                    "some comments");
799            fail("Should throw ClassCastException");
800        } catch (ClassCastException e1) {
801            // expected
802        }
803        myProps.remove(String.class);
804        myProps.store(new OutputStreamWriter(new ByteArrayOutputStream()),
805                "some comments");
806        // it is OK
807        myProps.put("wrong type", String.class);
808        try {
809            myProps.store(new OutputStreamWriter(new ByteArrayOutputStream()),
810                    "some comments");
811            fail("Should throw ClassCastException");
812        } catch (ClassCastException e1) {
813            // expected
814        }
815    }
816
817    /**
818     * @tests java.util.Properties#loadFromXML(java.io.InputStream)
819     */
820    public void test_loadFromXMLLjava_io_InputStream() throws Exception {
821        // Test for method void
822        // java.util.Properties.loadFromXML(java.io.InputStream)
823        Properties prop = null;
824        try {
825            InputStream is;
826            prop = new Properties();
827            prop.loadFromXML(is = new ByteArrayInputStream(
828                    writePropertiesXMLUTF_8()));
829            is.close();
830        } catch (Exception e) {
831            fail("Exception during load test : " + e.getMessage());
832        }
833        assertEquals("Failed to load correct properties", "value3", prop
834                .getProperty("key3"));
835        assertEquals("Failed to load correct properties", "value1", prop
836                .getProperty("key1"));
837
838        try {
839            InputStream is;
840            prop = new Properties();
841            prop.loadFromXML(is = new ByteArrayInputStream(
842                    writePropertiesXMLISO_8859_1()));
843            is.close();
844        } catch (Exception e) {
845            fail("Exception during load test : " + e.getMessage());
846        }
847        assertEquals("Failed to load correct properties", "value2", prop
848                .getProperty("key2"));
849        assertEquals("Failed to load correct properties", "value1", prop
850                .getProperty("key1"));
851
852        try {
853            prop.loadFromXML(null);
854            fail("should throw NullPointerException");
855        } catch (NullPointerException e) {
856            // expected
857        }
858    }
859
860    /**
861     * @tests java.util.Properties#storeToXML(java.io.OutputStream,
862     *        java.lang.String, java.lang.String)
863     */
864    public void test_storeToXMLLjava_io_OutputStreamLjava_lang_StringLjava_lang_String()
865            throws Exception {
866        // Test for method void
867        // java.util.Properties.storeToXML(java.io.OutputStream,
868        // java.lang.String, java.lang.String)
869        Properties myProps = new Properties();
870        Properties myProps2 = new Properties();
871        Enumeration e;
872        String nextKey;
873
874        myProps.setProperty("key1", "value1");
875        myProps.setProperty("key2", "value2");
876        myProps.setProperty("key3", "value3");
877        myProps.setProperty("<a>key4</a>", "\"value4");
878        myProps.setProperty("key5   ", "<h>value5</h>");
879        myProps.setProperty("<a>key6</a>", "   <h>value6</h>   ");
880        myProps.setProperty("<comment>key7</comment>", "value7");
881        myProps.setProperty("  key8   ", "<comment>value8</comment>");
882        myProps.setProperty("&lt;key9&gt;", "\u0027value9");
883        myProps.setProperty("key10\"", "&lt;value10&gt;");
884        myProps.setProperty("&amp;key11&amp;", "value11");
885        myProps.setProperty("key12", "&amp;value12&amp;");
886        myProps.setProperty("<a>&amp;key13&lt;</a>",
887                "&amp;&value13<b>&amp;</b>");
888
889        try {
890            ByteArrayOutputStream out = new ByteArrayOutputStream();
891
892            // store in UTF-8 encoding
893            myProps.storeToXML(out, "comment");
894            out.close();
895            ByteArrayInputStream in = new ByteArrayInputStream(out
896                    .toByteArray());
897            myProps2.loadFromXML(in);
898            in.close();
899        } catch (InvalidPropertiesFormatException ipfe) {
900            fail("InvalidPropertiesFormatException occurred reading file: "
901                    + ipfe.getMessage());
902        } catch (IOException ioe) {
903            fail("IOException occurred reading/writing file : "
904                    + ioe.getMessage());
905        }
906
907        e = myProps.propertyNames();
908        while (e.hasMoreElements()) {
909            nextKey = (String) e.nextElement();
910            assertTrue("Stored property list not equal to original", myProps2
911                    .getProperty(nextKey).equals(myProps.getProperty(nextKey)));
912        }
913
914        try {
915            ByteArrayOutputStream out = new ByteArrayOutputStream();
916
917            // store in ISO-8859-1 encoding
918            myProps.storeToXML(out, "comment", "ISO-8859-1");
919            out.close();
920            ByteArrayInputStream in = new ByteArrayInputStream(out
921                    .toByteArray());
922            myProps2 = new Properties();
923            myProps2.loadFromXML(in);
924            in.close();
925        } catch (InvalidPropertiesFormatException ipfe) {
926            fail("InvalidPropertiesFormatException occurred reading file: "
927                    + ipfe.getMessage());
928        } catch (IOException ioe) {
929            fail("IOException occurred reading/writing file : "
930                    + ioe.getMessage());
931        }
932
933        e = myProps.propertyNames();
934        while (e.hasMoreElements()) {
935            nextKey = (String) e.nextElement();
936            assertTrue("Stored property list not equal to original", myProps2
937                    .getProperty(nextKey).equals(myProps.getProperty(nextKey)));
938        }
939
940        try {
941            ByteArrayOutputStream out = new ByteArrayOutputStream();
942            myProps.storeToXML(out, null, null);
943            fail("should throw nullPointerException");
944        } catch (NullPointerException ne) {
945            // expected
946        }
947    }
948
949    /**
950     * if loading from single line like "hello" without "\n\r" neither "=", it
951     * should be same as loading from "hello="
952     */
953    public void testLoadSingleLine() throws Exception{
954        Properties props = new Properties();
955        InputStream sr = new ByteArrayInputStream("hello".getBytes());
956        props.load(sr);
957        assertEquals(1, props.size());
958    }
959
960    public void test_SequentialpropertyNames() {
961        Properties parent = new Properties();
962        parent.setProperty("parent.a.key", "parent.a.value");
963        parent.setProperty("parent.b.key", "parent.b.value");
964
965        Enumeration<?> names = parent.propertyNames();
966        assertEquals("parent.a.key", names.nextElement());
967        assertEquals("parent.b.key", names.nextElement());
968        assertFalse(names.hasMoreElements());
969
970        Properties current = new Properties(parent);
971        current.setProperty("current.a.key", "current.a.value");
972        current.setProperty("current.b.key", "current.b.value");
973
974        names = current.propertyNames();
975        assertEquals("parent.a.key", names.nextElement());
976        assertEquals("current.b.key", names.nextElement());
977        assertEquals("parent.b.key", names.nextElement());
978        assertEquals("current.a.key", names.nextElement());
979        assertFalse(names.hasMoreElements());
980
981        Properties child = new Properties(current);
982        child.setProperty("child.a.key", "child.a.value");
983        child.setProperty("child.b.key", "child.b.value");
984
985        names = child.propertyNames();
986        assertEquals("parent.a.key", names.nextElement());
987        assertEquals("child.b.key", names.nextElement());
988        assertEquals("current.b.key", names.nextElement());
989        assertEquals("parent.b.key", names.nextElement());
990        assertEquals("child.a.key", names.nextElement());
991        assertEquals("current.a.key", names.nextElement());
992        assertFalse(names.hasMoreElements());
993    }
994
995    public void test_SequentialstringPropertyNames() {
996        Properties parent = new Properties();
997        parent.setProperty("parent.a.key", "parent.a.value");
998        parent.setProperty("parent.b.key", "parent.b.value");
999
1000        Iterator<String> nameIterator = parent.stringPropertyNames().iterator();
1001        assertEquals("parent.a.key", nameIterator.next());
1002        assertEquals("parent.b.key", nameIterator.next());
1003        assertFalse(nameIterator.hasNext());
1004
1005        Properties current = new Properties(parent);
1006        current.setProperty("current.a.key", "current.a.value");
1007        current.setProperty("current.b.key", "current.b.value");
1008
1009        nameIterator = current.stringPropertyNames().iterator();
1010        assertEquals("parent.a.key", nameIterator.next());
1011        assertEquals("current.b.key", nameIterator.next());
1012        assertEquals("parent.b.key", nameIterator.next());
1013        assertEquals("current.a.key", nameIterator.next());
1014        assertFalse(nameIterator.hasNext());
1015
1016        Properties child = new Properties(current);
1017        child.setProperty("child.a.key", "child.a.value");
1018        child.setProperty("child.b.key", "child.b.value");
1019
1020        nameIterator = child.stringPropertyNames().iterator();
1021        assertEquals("parent.a.key", nameIterator.next());
1022        assertEquals("child.b.key", nameIterator.next());
1023        assertEquals("current.b.key", nameIterator.next());
1024        assertEquals("parent.b.key", nameIterator.next());
1025        assertEquals("child.a.key", nameIterator.next());
1026        assertEquals("current.a.key", nameIterator.next());
1027        assertFalse(nameIterator.hasNext());
1028    }
1029
1030    public static class MockProperties extends Properties {
1031
1032        private static final long serialVersionUID = 1L;
1033
1034        public MockProperties() throws IOException {
1035            mockLoad();
1036        }
1037
1038        private void mockLoad() throws IOException {
1039            super.load(new ByteArrayInputStream("key=value".getBytes()));
1040        }
1041
1042        public void load(Reader reader) {
1043            fail("should invoke Properties.load(Reader)");
1044        }
1045    }
1046
1047    public void test_loadLjava_io_InputStream_onLjava_io_Reader()
1048            throws IOException {
1049        MockProperties mockProperties = new MockProperties();
1050        assertEquals(1, mockProperties.size());
1051        assertEquals("value", mockProperties.get("key"));
1052    }
1053
1054    private String comment1 = "comment1";
1055
1056    private String comment2 = "comment2";
1057
1058    private void validateOutput(String[] expectStrings, byte[] output)
1059            throws IOException {
1060        ByteArrayInputStream bais = new ByteArrayInputStream(output);
1061        BufferedReader br = new BufferedReader(new InputStreamReader(bais,
1062                "ISO8859_1"));
1063        for (String expectString : expectStrings) {
1064            assertEquals(expectString, br.readLine());
1065        }
1066        br.readLine();
1067        assertNull(br.readLine());
1068        br.close();
1069    }
1070
1071    public void testStore_scenario0() throws IOException {
1072        ByteArrayOutputStream baos = new ByteArrayOutputStream();
1073        Properties props = new Properties();
1074        props.store(baos, comment1 + '\r' + comment2);
1075        validateOutput(new String[] { "#comment1", "#comment2" },
1076                baos.toByteArray());
1077        baos.close();
1078    }
1079
1080    public void testStore_scenario1() throws IOException {
1081        ByteArrayOutputStream baos = new ByteArrayOutputStream();
1082        Properties props = new Properties();
1083        props.store(baos, comment1 + '\n' + comment2);
1084        validateOutput(new String[] { "#comment1", "#comment2" },
1085                baos.toByteArray());
1086        baos.close();
1087    }
1088
1089    public void testStore_scenario2() throws IOException {
1090        ByteArrayOutputStream baos = new ByteArrayOutputStream();
1091        Properties props = new Properties();
1092        props.store(baos, comment1 + '\r' + '\n' + comment2);
1093        validateOutput(new String[] { "#comment1", "#comment2" },
1094                baos.toByteArray());
1095        baos.close();
1096    }
1097
1098    public void testStore_scenario3() throws IOException {
1099        ByteArrayOutputStream baos = new ByteArrayOutputStream();
1100        Properties props = new Properties();
1101        props.store(baos, comment1 + '\n' + '\r' + comment2);
1102        validateOutput(new String[] { "#comment1", "#", "#comment2" },
1103                baos.toByteArray());
1104        baos.close();
1105    }
1106
1107    public void testStore_scenario4() throws IOException {
1108        ByteArrayOutputStream baos = new ByteArrayOutputStream();
1109        Properties props = new Properties();
1110        props.store(baos, comment1 + '\r' + '#' + comment2);
1111        validateOutput(new String[] { "#comment1", "#comment2" },
1112                baos.toByteArray());
1113        baos.close();
1114    }
1115
1116    public void testStore_scenario5() throws IOException {
1117        ByteArrayOutputStream baos = new ByteArrayOutputStream();
1118        Properties props = new Properties();
1119        props.store(baos, comment1 + '\r' + '!' + comment2);
1120        validateOutput(new String[] { "#comment1", "!comment2" },
1121                baos.toByteArray());
1122        baos.close();
1123    }
1124
1125    public void testStore_scenario6() throws IOException {
1126        ByteArrayOutputStream baos = new ByteArrayOutputStream();
1127        Properties props = new Properties();
1128        props.store(baos, comment1 + '\n' + '#' + comment2);
1129        validateOutput(new String[] { "#comment1", "#comment2" },
1130                baos.toByteArray());
1131        baos.close();
1132    }
1133
1134    public void testStore_scenario7() throws IOException {
1135        ByteArrayOutputStream baos = new ByteArrayOutputStream();
1136        Properties props = new Properties();
1137        props.store(baos, comment1 + '\n' + '!' + comment2);
1138        validateOutput(new String[] { "#comment1", "!comment2" },
1139                baos.toByteArray());
1140        baos.close();
1141    }
1142
1143    public void testStore_scenario8() throws IOException {
1144        ByteArrayOutputStream baos = new ByteArrayOutputStream();
1145        Properties props = new Properties();
1146        props.store(baos, comment1 + '\r' + '\n' + '#' + comment2);
1147        validateOutput(new String[] { "#comment1", "#comment2" },
1148                baos.toByteArray());
1149        baos.close();
1150    }
1151
1152    public void testStore_scenario9() throws IOException {
1153        ByteArrayOutputStream baos = new ByteArrayOutputStream();
1154        Properties props = new Properties();
1155        props.store(baos, comment1 + '\n' + '\r' + '#' + comment2);
1156        validateOutput(new String[] { "#comment1", "#", "#comment2" },
1157                baos.toByteArray());
1158        baos.close();
1159    }
1160
1161    public void testStore_scenario10() throws IOException {
1162        ByteArrayOutputStream baos = new ByteArrayOutputStream();
1163        Properties props = new Properties();
1164        props.store(baos, comment1 + '\r' + '\n' + '!' + comment2);
1165        validateOutput(new String[] { "#comment1", "!comment2" },
1166                baos.toByteArray());
1167        baos.close();
1168    }
1169
1170    public void testStore_scenario11() throws IOException {
1171        ByteArrayOutputStream baos = new ByteArrayOutputStream();
1172        Properties props = new Properties();
1173        props.store(baos, comment1 + '\n' + '\r' + '!' + comment2);
1174        validateOutput(new String[] { "#comment1", "#", "!comment2" },
1175                baos.toByteArray());
1176        baos.close();
1177    }
1178
1179    public void testLoadReader() throws IOException {
1180        InputStream inputStream = new ByteArrayInputStream(
1181                "\u3000key=value".getBytes("UTF-8"));
1182        Properties props = new Properties();
1183        props.load(inputStream);
1184        Enumeration<Object> keyEnum = props.keys();
1185        assertFalse("\u3000key".equals(keyEnum.nextElement()));
1186        assertFalse(keyEnum.hasMoreElements());
1187        inputStream.close();
1188
1189        inputStream = new ByteArrayInputStream(
1190                "\u3000key=value".getBytes("UTF-8"));
1191        props = new Properties();
1192        props.load(new InputStreamReader(inputStream, "UTF-8"));
1193        keyEnum = props.keys();
1194        assertEquals("\u3000key", keyEnum.nextElement());
1195        assertFalse(keyEnum.hasMoreElements());
1196        inputStream.close();
1197    }
1198
1199    /**
1200     * Sets up the fixture, for example, open a network connection. This method
1201     * is called before a test is executed.
1202     */
1203    protected void setUp() {
1204
1205        tProps = new Properties();
1206        tProps.put("test.prop", "this is a test property");
1207        tProps.put("bogus.prop", "bogus");
1208    }
1209
1210    /**
1211     * Tears down the fixture, for example, close a network connection. This
1212     * method is called after a test is executed.
1213     */
1214    protected void tearDown() {
1215    }
1216
1217    /**
1218     * Tears down the fixture, for example, close a network connection. This
1219     * method is called after a test is executed.
1220     */
1221    protected byte[] writeProperties() throws IOException {
1222        PrintStream ps = null;
1223        ByteArrayOutputStream bout = new ByteArrayOutputStream();
1224        ps = new PrintStream(bout);
1225        ps.println("#commented.entry=Bogus");
1226        ps.println("test.pkg=harmony.tests");
1227        ps.println("test.proj=Automated Tests");
1228        ps.close();
1229        return bout.toByteArray();
1230    }
1231
1232    protected byte[] writePropertiesXMLUTF_8() throws IOException {
1233        PrintStream ps = null;
1234        ByteArrayOutputStream bout = new ByteArrayOutputStream();
1235        ps = new PrintStream(bout, true, "UTF-8");
1236        ps.println("<?xml version=\"1.0\" encoding=\"UTF-8\"?>");
1237        ps
1238                .println("<!DOCTYPE properties SYSTEM \"http://java.sun.com/dtd/properties.dtd\">");
1239        ps.println("<properties>");
1240        ps.println("<comment>comment</comment>");
1241        ps.println("<entry key=\"key4\">value4</entry>");
1242        ps.println("<entry key=\"key3\">value3</entry>");
1243        ps.println("<entry key=\"key2\">value2</entry>");
1244        ps.println("<entry key=\"key1\"><!-- xml comment -->value1</entry>");
1245        ps.println("</properties>");
1246        ps.close();
1247        return bout.toByteArray();
1248    }
1249
1250    protected byte[] writePropertiesXMLISO_8859_1() throws IOException {
1251        PrintStream ps = null;
1252        ByteArrayOutputStream bout = new ByteArrayOutputStream();
1253        ps = new PrintStream(bout, true, "ISO-8859-1");
1254        ps.println("<?xml version=\"1.0\" encoding=\"ISO-8859-1\"?>");
1255        ps
1256                .println("<!DOCTYPE properties SYSTEM \"http://java.sun.com/dtd/properties.dtd\">");
1257        ps.println("<properties>");
1258        ps.println("<comment>comment</comment>");
1259        ps.println("<entry key=\"key4\">value4</entry>");
1260        ps.println("<entry key=\"key3\">value3</entry>");
1261        ps.println("<entry key=\"key2\">value2</entry>");
1262        ps.println("<entry key=\"key1\"><!-- xml comment -->value1</entry>");
1263        ps.println("</properties>");
1264        ps.close();
1265        return bout.toByteArray();
1266    }
1267}
1268