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