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 dalvik.annotation.AndroidOnly;
21import dalvik.annotation.TestTargetClass;
22import dalvik.annotation.TestTargets;
23import dalvik.annotation.TestTargetNew;
24import dalvik.annotation.TestLevel;
25
26import java.io.File;
27import java.text.MessageFormat;
28import java.util.Locale;
29import java.util.Properties;
30import java.util.ResourceBundle;
31import java.util.logging.FileHandler;
32import java.util.logging.Formatter;
33import java.util.logging.Handler;
34import java.util.logging.Level;
35import java.util.logging.Logger;
36import java.util.logging.LogManager;
37import java.util.logging.LogRecord;
38
39import junit.framework.TestCase;
40
41import org.apache.harmony.logging.tests.java.util.logging.util.EnvironmentHelper;
42
43@TestTargetClass(Formatter.class)
44public class FormatterTest extends TestCase {
45    Formatter f;
46
47    LogRecord r;
48
49    FileHandler h;
50
51    static String MSG = "msg, pls. ignore it";
52
53    static LogManager manager = LogManager.getLogManager();
54
55    final static Properties props = new Properties();
56
57    final static String className = FormatterTest.class.getName();
58
59    final static String TEMPPATH = System.getProperty("java.io.tmpdir");
60
61    final static String SEP = File.separator;
62
63    /*
64     * @see TestCase#setUp()
65     */
66    protected void setUp() throws Exception {
67        super.setUp();
68        manager.reset();
69
70        //initProp
71        props.clear();
72        props.put("java.util.logging.FileHandler.level", "FINE");
73        props.put("java.util.logging.FileHandler.filter", className
74                + "$MockFilter");
75        props.put("java.util.logging.FileHandler.formatter", className
76                + "$MockFormatter");
77        props.put("java.util.logging.FileHandler.encoding", "iso-8859-1");
78        // limit to only two message
79        props.put("java.util.logging.FileHandler.limit", "1000");
80        // rotation count is 2
81        props.put("java.util.logging.FileHandler.count", "2");
82        // using append mode
83        props.put("java.util.logging.FileHandler.append", "true");
84        props.put("java.util.logging.FileHandler.pattern",
85                        "%t/log/java%u.test");
86
87        File file = new File(TEMPPATH + SEP + "log");
88        file.mkdir();
89        manager.readConfiguration(EnvironmentHelper
90                .PropertiesToInputStream(props));
91
92        f = new MockFormatter();
93        r = new LogRecord(Level.FINE, MSG);
94        h = new FileHandler();
95    }
96
97    /*
98     * test for constructor protected Formatter()
99     */
100    @TestTargets({
101        @TestTargetNew(
102            level = TestLevel.COMPLETE,
103            notes = "",
104            method = "Formatter",
105            args = {}
106        ),
107        @TestTargetNew(
108            level = TestLevel.PARTIAL_COMPLETE,
109            notes = "",
110            method = "getHead",
111            args = {java.util.logging.Handler.class}
112        ),
113        @TestTargetNew(
114            level = TestLevel.PARTIAL_COMPLETE,
115            notes = "",
116            method = "getTail",
117            args = {java.util.logging.Handler.class}
118        )
119    })
120    public void testFormatter() {
121        assertEquals("head string is not empty", "", f.getHead(null));
122        assertEquals("tail string is not empty", "", f.getTail(null));
123
124    }
125
126    /*
127     * test for method public String getHead(Handler h)
128     */
129    @TestTargetNew(
130        level = TestLevel.PARTIAL_COMPLETE,
131        notes = "",
132        method = "getHead",
133        args = {Handler.class}
134    )
135    public void testGetHead() {
136        assertEquals("head string is not empty", "", f.getHead(null));
137        assertEquals("head string is not empty", "", f.getHead(h));
138        h.publish(r);
139        assertEquals("head string is not empty", "", f.getHead(h));
140    }
141
142    /*
143     * test for method public String getTail(Handler h)
144     */
145    @TestTargetNew(
146        level = TestLevel.PARTIAL_COMPLETE,
147        notes = "",
148        method = "getTail",
149        args = {Handler.class}
150    )
151    public void testGetTail() {
152        assertEquals("tail string is not empty", "", f.getTail(null));
153        assertEquals("tail string is not empty", "", f.getTail(h));
154        h.publish(r);
155        assertEquals("tail string is not empty", "", f.getTail(h));
156    }
157
158    @TestTargetNew(
159        level = TestLevel.PARTIAL_COMPLETE,
160        notes = "",
161        method = "formatMessage",
162        args = {LogRecord.class}
163    )
164    @AndroidOnly("The RI fails in this test because it uses a MessageFormat " +
165            "to format the message even though it doesn't contain \"{0\". " +
166            "The spec says that this would indicate that a MessageFormat " +
167            "should be used and else no formatting should be done.")
168    public void testFormatMessage() {
169        assertEquals(MSG, f.formatMessage(r));
170
171        String pattern = "test formatter {0, number}";
172        r.setMessage(pattern);
173        assertEquals(pattern, f.formatMessage(r));
174
175        Object[] oa = new Object[0];
176        r.setParameters(oa);
177        assertEquals(pattern, f.formatMessage(r));
178
179        oa = new Object[] { new Integer(100), new Float(1.2), new Float(2.2) };
180        r.setParameters(oa);
181        assertEquals(MessageFormat.format(pattern, oa), f.formatMessage(r));
182
183        r.setMessage(MSG);
184        assertEquals(MSG, f.formatMessage(r));
185
186        pattern = "wrong pattern {0, asdfasfd}";
187        r.setMessage(pattern);
188        assertEquals(pattern, f.formatMessage(r));
189
190        pattern = null;
191        r.setMessage(pattern);
192        assertNull(f.formatMessage(r));
193
194        // The RI fails in this test because it uses a MessageFormat to format
195        // the message even though it doesn't contain "{0". The spec says that
196        // this would indicate that a MessageFormat should be used and else no
197        // formatting should be done.
198        pattern = "pattern without 0 {1, number}";
199        r.setMessage(pattern);
200        assertEquals(pattern, f.formatMessage(r));
201    }
202
203    @TestTargetNew(
204        level = TestLevel.PARTIAL_COMPLETE,
205        notes = "",
206        method = "formatMessage",
207        args = {LogRecord.class}
208    )
209    public void testLocalizedFormatMessage() {
210        // normal case
211        r.setMessage("msg");
212        ResourceBundle rb = ResourceBundle
213                .getBundle("bundles/java/util/logging/res");
214        r.setResourceBundle(rb);
215        assertEquals(rb.getString("msg"), f.formatMessage(r));
216
217        // local message is a pattern
218        r.setMessage("pattern");
219        Object[] oa = new Object[] { new Integer(3) };
220        r.setParameters(oa);
221        assertEquals(MessageFormat.format(rb.getString("pattern"), oa), f
222                .formatMessage(r));
223
224        // key is a pattern, but local message is not
225        r.setMessage("pattern{0,number}");
226        oa = new Object[] { new Integer(3) };
227        r.setParameters(oa);
228        assertEquals(rb.getString("pattern{0,number}"), f.formatMessage(r));
229
230        // another bundle
231        rb = ResourceBundle.getBundle("bundles/java/util/logging/res",
232                Locale.US);
233        r.setMessage("msg");
234        r.setResourceBundle(rb);
235        assertEquals(rb.getString("msg"), f.formatMessage(r));
236
237        // cannot find local message in bundle
238        r.setMessage("msg without locale");
239        assertEquals("msg without locale", f.formatMessage(r));
240
241        // set bundle name but not bundle
242        r.setResourceBundle(null);
243        r.setResourceBundleName("bundles/java/util/logging/res");
244        r.setMessage("msg");
245        assertEquals("msg", f.formatMessage(r));
246    }
247
248    public static class MockFormatter extends Formatter {
249
250        public String format(LogRecord arg0) {
251            return "format";
252        }
253    }
254}
255