001: /*
002: * Licensed to the Apache Software Foundation (ASF) under one or more
003: * contributor license agreements. See the NOTICE file distributed with
004: * this work for additional information regarding copyright ownership.
005: * The ASF licenses this file to You under the Apache License, Version 2.0
006: * (the "License"); you may not use this file except in compliance with
007: * the License. You may obtain a copy of the License at
008: *
009: * http://www.apache.org/licenses/LICENSE-2.0
010: *
011: * Unless required by applicable law or agreed to in writing, software
012: * distributed under the License is distributed on an "AS IS" BASIS,
013: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014: * See the License for the specific language governing permissions and
015: * limitations under the License.
016: *
017: */
018:
019: package org.apache.jmeter.resources;
020:
021: import java.io.BufferedReader;
022: import java.io.InputStream;
023: import java.io.InputStreamReader;
024: import java.util.ArrayList;
025: import java.util.Collections;
026: import java.util.Enumeration;
027: import java.util.List;
028: import java.util.MissingResourceException;
029: import java.util.PropertyResourceBundle;
030:
031: import junit.framework.Test;
032: import junit.framework.TestCase;
033: import junit.framework.TestSuite;
034:
035: /*
036: * Created on Nov 29, 2003
037: *
038: * Test the composition of the properties files - properties files exist
039: * (default, DE, NO, JA) - properties files don't have duplicate keys -
040: * non-default properties files don't have any extra keys.
041: *
042: * N.B. If there is a default resource, ResourceBundle does not detect missing
043: * resources, i.e. the presence of messages.properties means that the
044: * ResourceBundle for Locale "XYZ" would still be found, and have the same keys
045: * as the default. This makes it not very useful for checking properties files.
046: *
047: * This is why the tests use Class.getResourceAsStream() etc
048: *
049: * The tests don't quite follow the normal JUnit test strategy of one test per
050: * possible failure. This was done in order to make it easier to report exactly
051: * why the tests failed.
052: */
053:
054: /**
055: * @version $Revision: 493796 $ $Date: 2007-01-07 18:31:05 +0000 (Sun, 07 Jan 2007) $
056: */
057: public class PackageTest extends TestCase {
058:
059: // private static List defaultList = null;
060: private static PropertyResourceBundle defaultPRB;
061:
062: // Read resource into ResourceBundle and store in List
063: private PropertyResourceBundle getRAS(String res) throws Exception {
064: InputStream ras = this .getClass().getResourceAsStream(res);
065: return new PropertyResourceBundle(ras);
066: }
067:
068: private static Object[] DUMMY_PARAMS = new Object[] { "1", "2",
069: "3", "4", "5", "6", "7", "8", "9" };
070:
071: // Read resource file saving the keys
072: private int readRF(String res, List l) throws Exception {
073: int fails = 0;
074: InputStream ras = this .getClass().getResourceAsStream(res);
075: BufferedReader fileReader = new BufferedReader(
076: new InputStreamReader(ras));
077: String s;
078: while ((s = fileReader.readLine()) != null) {
079: if (s.length() > 0 && !s.startsWith("#")
080: && !s.startsWith("!")) {
081: int equ = s.indexOf('=');
082: String key = s.substring(0, equ);
083: /*
084: * JMeterUtils.getResString() converts space to _ and lowercases
085: * the key, so make sure all keys pass the test
086: */
087: if ((key.indexOf(' ') >= 0)
088: || !key.toLowerCase().equals(key)) {
089: System.out.println("Invalid key for JMeterUtils "
090: + key);
091: fails++;
092: }
093: String val = s.substring(equ + 1);
094: l.add(key); // Store the key
095: /*
096: * Now check for invalid message format: if string contains {0}
097: * and ' there may be a problem, so do a format with dummy
098: * parameters and check if there is a { in the output. A bit
099: * crude, but should be enough for now.
100: */
101: if (val.indexOf("{0}") > 0 && val.indexOf("'") > 0) {
102: String m = java.text.MessageFormat.format(val,
103: DUMMY_PARAMS);
104: if (m.indexOf("{") > 0) {
105: fails++;
106: System.out
107: .println("Incorrect message format ? (input/output): ");
108: System.out.println(val);
109: System.out.println(m);
110: }
111: }
112:
113: }
114: }
115: return fails;
116: }
117:
118: // Helper method to construct resource name
119: private static String getResName(String lang) {
120: if (lang.length() == 0) {
121: return "messages.properties";
122: } else {
123: return "messages_" + lang + ".properties";
124: }
125: }
126:
127: private void check(String resname) throws Exception {
128: check(resname, true);// check that there aren't any extra entries
129: }
130:
131: /*
132: * perform the checks on the resources
133: *
134: */
135: private void check(String resname, boolean checkUnexpected)
136: throws Exception {
137: ArrayList alf = new ArrayList(500);// holds keys from file
138: String res = getResName(resname);
139: subTestFailures += readRF(res, alf);
140: Collections.sort(alf);
141:
142: // Look for duplicate keys in the file
143: String last = "";
144: for (int i = 0; i < alf.size(); i++) {
145: String curr = (String) alf.get(i);
146: if (curr.equals(last)) {
147: subTestFailures++;
148: System.out.println("\nDuplicate key =" + curr + " in "
149: + res);
150: }
151: last = curr;
152: }
153:
154: if (resname.length() == 0) // Must be the default resource file
155: {
156: defaultPRB = getRAS(res);
157: } else if (checkUnexpected) {
158: // Check all the keys are in the default props file
159: PropertyResourceBundle prb = getRAS(res);
160: Enumeration enumr = prb.getKeys();
161: while (enumr.hasMoreElements()) {
162: String key = null;
163: try {
164: key = (String) enumr.nextElement();
165: String val = defaultPRB.getString(key);
166: if (val.equals(prb.getString(key))) {
167: System.out
168: .println("Possible duplicate value for "
169: + key + " in " + res);
170: subTestFailures++;
171: }
172: } catch (MissingResourceException e) {
173: subTestFailures++;
174: System.out.println("Locale: " + resname
175: + " has unexpected key: " + key);
176: }
177: }
178: }
179:
180: if (subTestFailures > 0) {
181: fail("One or more subtests failed");
182: }
183: }
184:
185: /*
186: * Use a suite to ensure that the default is done first
187: */
188: public static Test suite() {
189: TestSuite ts = new TestSuite("Resources PackageTest");
190: ts.addTest(new PackageTest("atestDefault"));
191: ts.addTest(new PackageTest("atestDE"));
192: ts.addTest(new PackageTest("atestNO"));
193: ts.addTest(new PackageTest("atestJA"));
194: ts.addTest(new PackageTest("atestzh_CN"));
195: ts.addTest(new PackageTest("atestzh_TW"));
196: ts.addTest(new PackageTest("atestFR"));
197: ts.addTest(new PackageTest("atestES"));
198: return ts;
199: }
200:
201: private int subTestFailures;
202:
203: public PackageTest(String string) {
204: super (string);
205: subTestFailures = 0;
206: }
207:
208: public void atestDE() throws Exception {
209: check("de");
210: }
211:
212: public void atestJA() throws Exception {
213: check("ja");
214: }
215:
216: public void atestzh_CN() throws Exception {
217: check("zh_CN");
218: }
219:
220: public void atestzh_TW() throws Exception {
221: check("zh_TW");
222: }
223:
224: public void atestNO() throws Exception {
225: check("no");
226: }
227:
228: public void atestFR() throws Exception {
229: check("fr");
230: }
231:
232: public void atestES() throws Exception {
233: check("es");
234: }
235:
236: public void atestDefault() throws Exception {
237: check("");
238: }
239: }
|