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.logging.tests.java.util.logging;
19
20import java.io.Serializable;
21import java.util.ResourceBundle;
22import java.util.logging.Level;
23
24import junit.framework.TestCase;
25
26import org.apache.harmony.testframework.serialization.SerializationTest;
27import org.apache.harmony.testframework.serialization.SerializationTest.SerializableAssert;
28
29/*
30 * This class implements Serializable, so that the non-static inner class
31 * MockLevel can be Serializable.
32 */
33public class LevelTest extends TestCase implements Serializable {
34
35    private static final long serialVersionUID = 1L;
36
37    /**
38     * Test the constructor without resource bundle parameter using normal
39     * values. As byproducts, getName & intValue are also tested.
40     */
41    public void testConstructorNoResBundle_Normal() {
42        MockLevel l = new MockLevel("level1", 1);
43        assertEquals("level1", l.getName());
44        assertEquals(1, l.intValue());
45        assertNull(l.getResourceBundleName());
46    }
47
48    /**
49     * Test the constructor without resource bundle parameter using null name.
50     * As byproducts, getName & intValue are also tested.
51     */
52    public void testConstructorNoResBundle_NullName() {
53        try {
54            new MockLevel(null, -2);
55            fail("No expected NullPointerException");
56        } catch (NullPointerException ignore) {
57            // expected
58        }
59    }
60
61    /*
62      * Test the constructor without resource bundle parameter using empty name.
63      * As byproducts, getName & intValue are also tested.
64      */
65    public void testConstructorNoResBundle_EmptyName() {
66        MockLevel l = new MockLevel("", -3);
67        assertEquals("", l.getName());
68        assertEquals(-3, l.intValue());
69        assertNull(l.getResourceBundleName());
70    }
71
72    /*
73      * Test the constructor having resource bundle parameter using normal
74      * values. As byproducts, getName & intValue are also tested.
75      */
76    public void testConstructorHavingResBundle_Normal() {
77        MockLevel l = new MockLevel("level1", 1, "resourceBundle");
78        assertEquals("level1", l.getName());
79        assertEquals(1, l.intValue());
80        assertEquals("resourceBundle", l.getResourceBundleName());
81    }
82
83    /*
84      * Test the constructor having resource bundle parameter using null names.
85      * As byproducts, getName & intValue are also tested.
86      */
87    public void testConstructorHavingResBundle_NullName() {
88        try {
89            new MockLevel(null, -123, "qwe");
90            fail("No expected NullPointerException");
91        } catch (NullPointerException ignore) {
92            // expected
93        }
94    }
95
96    /*
97      * Test the constructor having resource bundle parameter using empty
98      names.
99      * As byproducts, getName & intValue are also tested.
100      */
101    public void testConstructorHavingResBundle_EmptyName() {
102        MockLevel l = new MockLevel("", -1000, "");
103        assertEquals("", l.getName());
104        assertEquals(-1000, l.intValue());
105        assertEquals("", l.getResourceBundleName());
106    }
107
108    /*
109      * Test method parse, with the pre-defined string consts.
110      */
111    public void testParse_PredefinedConstStrings() {
112        assertSame(Level.SEVERE, Level.parse("SEVERE"));
113        assertSame(Level.WARNING, Level.parse("WARNING"));
114        assertSame(Level.INFO, Level.parse("INFO"));
115        assertSame(Level.CONFIG, Level.parse("CONFIG"));
116        assertSame(Level.FINE, Level.parse("FINE"));
117        assertSame(Level.FINER, Level.parse("FINER"));
118        assertSame(Level.FINEST, Level.parse("FINEST"));
119        assertSame(Level.OFF, Level.parse("OFF"));
120        assertSame(Level.ALL, Level.parse("ALL"));
121    }
122
123    /*
124      * Test method parse, with an undefined string.
125      */
126    public void testParse_IllegalConstString() {
127        try {
128            Level.parse("SEVERe");
129            fail("Should throw IllegalArgumentException if undefined string.");
130        } catch (IllegalArgumentException e) {
131            // expected
132        }
133    }
134
135    /*
136      * Test method parse, with a null string.
137      */
138    public void testParse_NullString() {
139        try {
140            Level.parse(null);
141            fail("Should throw NullPointerException.");
142        } catch (NullPointerException e) {
143            // expected
144        }
145    }
146
147    /*
148      * Test method parse, with pre-defined valid number strings.
149      */
150    public void testParse_PredefinedNumber() {
151        assertSame(Level.SEVERE, Level.parse("SEVERE"));
152        assertSame(Level.WARNING, Level.parse("WARNING"));
153        assertSame(Level.INFO, Level.parse("INFO"));
154        assertSame(Level.CONFIG, Level.parse("CONFIG"));
155        assertSame(Level.FINE, Level.parse("FINE"));
156        assertSame(Level.FINER, Level.parse("FINER"));
157        assertSame(Level.FINEST, Level.parse("FINEST"));
158        assertSame(Level.OFF, Level.parse("OFF"));
159        assertSame(Level.ALL, Level.parse("ALL"));
160        assertSame(Level.SEVERE, Level.parse("1000"));
161        assertSame(Level.WARNING, Level.parse("900"));
162        assertSame(Level.INFO, Level.parse("800"));
163        assertSame(Level.CONFIG, Level.parse("700"));
164        assertSame(Level.FINE, Level.parse("500"));
165        assertSame(Level.FINER, Level.parse("400"));
166        assertSame(Level.FINEST, Level.parse("300"));
167        assertSame(Level.OFF, Level.parse(String.valueOf(Integer.MAX_VALUE)));
168        assertSame(Level.ALL, Level.parse(String.valueOf(Integer.MIN_VALUE)));
169    }
170
171    /*
172      * Test method parse, with an undefined valid number strings.
173      */
174    public void testParse_UndefinedNumber() {
175        Level l = Level.parse("0");
176        assertEquals(0, l.intValue());
177        assertEquals("0", l.getName());
178        assertNull(l.getResourceBundleName());
179    }
180
181    /*
182      * Test method parse, with an undefined valid number strings with spaces.
183      */
184    public void testParse_UndefinedNumberWithSpaces() {
185        try {
186            Level.parse(" 0");
187        } catch (IllegalArgumentException e) {
188            // expected
189        }
190    }
191
192    public void testParse_NegativeNumber() {
193        Level l = Level.parse("-4");
194        assertEquals(-4, l.intValue());
195        assertEquals("-4", l.getName());
196        assertNull(l.getResourceBundleName());
197    }
198
199    /*
200      * Test method parse, expecting the same objects will be returned given the
201      * same name, even for non-predefined levels.
202      */
203    public void testParse_SameObject() {
204        Level l = Level.parse("-100");
205        assertSame(l, Level.parse("-100"));
206    }
207
208    /*
209      * Test method hashCode, with normal fields.
210      */
211    public void testHashCode_Normal() {
212        assertEquals(100, Level.parse("100").hashCode());
213        assertEquals(-1, Level.parse("-1").hashCode());
214        assertEquals(0, Level.parse("0").hashCode());
215        assertEquals(Integer.MIN_VALUE, Level.parse("ALL").hashCode());
216    }
217
218    /*
219      * Test equals when two objects are equal.
220      */
221    public void testEquals_Equal() {
222        MockLevel l1 = new MockLevel("level1", 1);
223        MockLevel l2 = new MockLevel("level2", 1);
224        assertEquals(l1, l2);
225        assertEquals(l2, l1);
226    }
227
228    /*
229      * Test equals when two objects are not equal.
230      */
231    public void testEquals_NotEqual() {
232        MockLevel l1 = new MockLevel("level1", 1);
233        MockLevel l2 = new MockLevel("level1", 2);
234        assertFalse(l1.equals(l2));
235        assertFalse(l2.equals(l1));
236    }
237
238    /*
239      * Test equals when the other object is null.
240      */
241    public void testEquals_Null() {
242        assertFalse(Level.ALL.equals(null));
243    }
244
245    /*
246      * Test equals when the other object is not an instance of Level.
247      */
248    public void testEquals_NotLevel() {
249        assertFalse(Level.ALL.equals(new Object()));
250    }
251
252    /*
253      * Test equals when the other object is itself.
254      */
255    public void testEquals_Itself() {
256        assertTrue(Level.ALL.equals(Level.ALL));
257    }
258
259    /*
260      * Test toString of a normal Level.
261      */
262    public void testToString_Normal() {
263        assertEquals("ALL", Level.ALL.toString());
264
265        MockLevel l = new MockLevel("name", 2);
266        assertEquals("name", l.toString());
267
268        MockLevel emptyLevel = new MockLevel("", 3);
269        assertEquals("", emptyLevel.toString());
270    }
271
272    // comparator for Level objects:
273    // is used because Level.equals() method only takes into account
274    // 'level' value but ignores 'name' and 'resourceBundleName' values
275    private static final SerializableAssert LEVEL_COMPARATOR = new SerializableAssert() {
276        public void assertDeserialized(Serializable initial,
277                Serializable deserialized) {
278
279            Level init = (Level) initial;
280            Level dser = (Level) deserialized;
281
282            assertEquals("Class", init.getClass(), dser.getClass());
283            assertEquals("Name", init.getName(), dser.getName());
284            assertEquals("Value", init.intValue(), dser.intValue());
285            assertEquals("ResourceBundleName", init.getResourceBundleName(),
286                    dser.getResourceBundleName());
287        }
288    };
289
290    /**
291     * @tests serialization/deserialization compatibility.
292     * <p/>
293     * Test serialization of pre-defined const levels. It is expected that the
294     * deserialized cost level should be the same instance as the existing one.
295     */
296    public void testSerialization_ConstLevel() throws Exception {
297
298        SerializationTest.verifySelf(Level.ALL,
299                SerializationTest.SAME_COMPARATOR);
300    }
301
302    /**
303     * @tests serialization/deserialization compatibility.
304     * <p/>
305     * Test serialization of normal instance of Level. It is expected that the
306     * deserialized level object should be equal to the original one.
307     */
308    public void testSerialization_InstanceLevel() throws Exception {
309
310        // tests that objects are the same
311        Level[] objectsToTest = new Level[] { Level.parse("550") };
312
313        SerializationTest.verifySelf(objectsToTest,
314                SerializationTest.SAME_COMPARATOR);
315
316        // tests that objects are the equals
317        objectsToTest = new Level[] {
318                new MockLevel("123", 123, "bundle"),
319                new MockLevel("123", 123, null) };
320
321        SerializationTest.verifySelf(objectsToTest, LEVEL_COMPARATOR);
322    }
323
324    /**
325     * @tests serialization/deserialization compatibility with RI.
326     */
327    public void testSerializationCompatibility() throws Exception {
328
329        SerializationTest.verifyGolden(this,
330                new MockLevel("123", 123, "bundle"), LEVEL_COMPARATOR);
331    }
332
333    public void testGetLocalName() {
334        ResourceBundle rb = ResourceBundle.getBundle("bundles/com/android/java/util/logging/res");
335        Level l = new MockLevel("level1", 120,
336                "bundles/com/android/java/util/logging/res");
337        assertEquals(rb.getString("level1"), l.getLocalizedName());
338
339        // regression test for HARMONY-2415
340        rb = ResourceBundle.getBundle(
341                "com.android.org.apache.harmony.logging.tests.java.util.logging.LevelTestResource");
342        l = new MockLevel("Level_error", 120,
343                "com.android.org.apache.harmony.logging.tests.java.util.logging.LevelTestResource");
344        assertEquals(rb.getString("Level_error"), l.getLocalizedName());
345
346        l = new MockLevel("bad name", 120, "res");
347        assertEquals("bad name", l.getLocalizedName());
348
349        l = new MockLevel("level1", 11120, "bad name");
350        assertEquals("level1", l.getLocalizedName());
351
352        l = new MockLevel("level1", 1120);
353        assertEquals("level1", l.getLocalizedName());
354    }
355
356    /*
357      * Test defining new levels in subclasses of Level
358      */
359    public void testSubclassNewLevel() {
360        MyLevel.DUPLICATENAME.getName();// just to load MyLevel class
361
362        // test duplicated name and num
363        assertEquals("INFO", MyLevel.parse("800").getName());
364        assertEquals(800, MyLevel.parse("INFO").intValue());
365        // test duplicated name
366        assertEquals("FINE", MyLevel.parse("499").getName());
367        assertEquals("FINE", MyLevel.parse("500").getName());
368        assertEquals(500, MyLevel.parse("FINE").intValue());
369        // test duplicated number
370        assertEquals("FINEST", MyLevel.parse("300").getName());
371        assertEquals(300, MyLevel.parse("FINEST").intValue());
372        assertEquals(300, MyLevel.parse("MYLEVEL1").intValue());
373        // test a normal new level, without duplicated elements
374        assertEquals("MYLEVEL2", MyLevel.parse("299").getName());
375        assertEquals(299, MyLevel.parse("MYLEVEL2").intValue());
376    }
377
378    /*
379      * This subclass is to test whether subclasses of Level can add new defined
380      * levels.
381      */
382    static class MyLevel extends Level implements Serializable {
383        private static final long serialVersionUID = 1L;
384
385        public MyLevel(String name, int value) {
386            super(name, value);
387        }
388
389        public static final Level DUPLICATENAMENUM = new MyLevel("INFO", 800);
390
391        public static final Level DUPLICATENAME = new MyLevel("FINE", 499);
392
393        public static final Level DUPLICATENUM = new MyLevel("MYLEVEL1", 300);
394
395        public static final Level NORMAL = new MyLevel("MYLEVEL2", 299);
396    }
397
398    /*
399      * This Mock is used to expose the protected constructors.
400      */
401    public class MockLevel extends Level implements Serializable {
402
403        private static final long serialVersionUID = 1L;
404
405        public MockLevel(String name, int value) {
406            super(name, value);
407        }
408
409        public MockLevel(String name, int value, String resourceBundleName) {
410            super(name, value, resourceBundleName);
411        }
412    }
413}
414