package test.utils;
import junit.framework.AssertionFailedError;
import junit.framework.Test;
import junit.framework.TestCase;
import junit.framework.TestSuite;
import java.io.File;
import java.io.FileInputStream;
import java.util.Enumeration;
import java.util.Vector;
/**
* This TestCase verifies:
* - the contents of resource.properties for well-formedness, and
* - tests calls to Messages.getMessage.
* - tests Messages extension mechanism
*/
public class TestMessages extends TestCase {
public TestMessages(String name) {
super(name);
} // ctor
public static Test suite() {
return new TestSuite(TestMessages.class);
}
/**
* Call getMessage for each key in resource.properties
* to make sure they are all well formed.
*/
private static final int expectedNumberKeysThreshold = 500;
public void testAllMessages() {
String arg0 = "arg0";
String arg1 = "arg1";
String[] args = {arg0, arg1, "arg2"};
int count = 0;
Enumeration keys = Messages.getResourceBundle().getKeys();
while (keys.hasMoreElements()) {
count++;
String key = (String) keys.nextElement();
try {
String message = Messages.getMessage(key);
message = Messages.getMessage(key, arg0);
message = Messages.getMessage(key, arg0, arg1);
message = Messages.getMessage(key, args);
}
catch (IllegalArgumentException iae) {
throw new AssertionFailedError("Test failure on key = " + key + ": " + iae.getMessage());
}
}
assertTrue("expected # keys greater than " + expectedNumberKeysThreshold + ", only got " + count + "! VERIFY HIERARCHICAL MESSAGES WORK/LINKED CORRECTLY",
count > expectedNumberKeysThreshold);
} // testAllMessages
/**
* Make sure the test messages come out as we expect them to.
*/
public void testTestMessages() {
try {
String message = Messages.getMessage("test00");
String expected = "...";
assertTrue("expected (" + expected + ") got (" + message + ")", expected.equals(message));
message = Messages.getMessage("test00", new String[0]);
assertTrue("expected (" + expected + ") got (" + message + ")", expected.equals(message));
message = Messages.getMessage("test00", new String[] {"one", "two"});
assertTrue("expected (" + expected + ") got (" + message + ")", expected.equals(message));
message = Messages.getMessage("test01");
expected = ".{0}.";
assertTrue("expected (" + expected + ") got (" + message + ")", expected.equals(message));
message = Messages.getMessage("test01", "one");
expected = ".one.";
assertTrue("expected (" + expected + ") got (" + message + ")", expected.equals(message));
message = Messages.getMessage("test01", new String[0]);
expected = ".{0}.";
assertTrue("expected (" + expected + ") got (" + message + ")", expected.equals(message));
message = Messages.getMessage("test01", new String[] {"one"});
expected = ".one.";
assertTrue("expected (" + expected + ") got (" + message + ")", expected.equals(message));
message = Messages.getMessage("test01", new String[] {"one", "two"});
expected = ".one.";
assertTrue("expected (" + expected + ") got (" + message + ")", expected.equals(message));
message = Messages.getMessage("test02");
expected = "{0}, {1}.";
assertTrue("expected (" + expected + ") got (" + message + ")", expected.equals(message));
message = Messages.getMessage("test02", new String[0]);
expected = "{0}, {1}.";
assertTrue("expected (" + expected + ") got (" + message + ")", expected.equals(message));
message = Messages.getMessage("test02", new String[] {"one"});
expected = "one, {1}.";
assertTrue("expected (" + expected + ") got (" + message + ")", expected.equals(message));
message = Messages.getMessage("test02", new String[] {"one", "two"});
expected = "one, two.";
assertTrue("expected (" + expected + ") got (" + message + ")", expected.equals(message));
message = Messages.getMessage("test03", new String[] {"one", "two", "three"});
expected = ".three, one, two.";
assertTrue("expected (" + expected + ") got (" + message + ")", expected.equals(message));
message = Messages.getMessage("test04", new String[] {"one", "two", "three", "four", "five", "six"});
expected = ".one two three ... four three five six.";
assertTrue("expected (" + expected + ") got (" + message + ")", expected.equals(message));
}
catch (Throwable t) {
throw new AssertionFailedError("Test failure: " + t.getMessage());
}
} // testTestMessages
/**
* Make sure the extended test messages come out as we expect them to.
*/
public void testTestExtendedMessages() {
try {
String message = Messages.getMessage("extended.test00");
String expected = "message in extension file";
assertTrue("expected (" + expected + ") got (" + message + ")", expected.equals(message));
}
catch (Throwable t) {
throw new AssertionFailedError("Test failure: " + t.getMessage());
}
} // testTestExtendedMessages
private static final String LS = System.getProperty("line.separator");
private String errors = "";
/**
* If this test is run from xml-axis/java, then walk through the source
* tree looking for all calls to Messages.getMessage. For each of these
* calls:
* 1. Make sure the message key exists in resource.properties
* 2. Make sure the actual number of parameters (in resource.properties)
* matches the excpected number of parameters (in the source code).
*/
public void testForMissingMessages() {
String baseDir = System.getProperty("user.dir");
char sep = File.separatorChar;
String srcDirStr = baseDir + sep + "src";
File srcDir = new File(srcDirStr);
if (srcDir.exists()) {
walkTree(srcDir);
}
if (!errors.equals("")) {
throw new AssertionFailedError(errors);
}
} // testForMissingMessages
/**
* Walk the source tree
*/
private void walkTree(File srcDir) {
File[] files = srcDir.listFiles();
for (int i = 0; i < files.length; ++i) {
if (files[i].isDirectory()) {
walkTree(files[i]);
}
else if (files[i].getName().endsWith(".java")) {
checkMessages(files[i]);
}
}
} // walkTree
/**
* Check all calls to Messages.getMessages:
* 1. Make sure the message key exists in resource.properties
* 2. Make sure the actual number of parameters (in resource.properties)
* matches the expected number of parameters (in the source code).
*/
private void checkMessages(File file) {
try {
FileInputStream fis = new FileInputStream(file);
byte[] bytes = new byte[fis.available()];
fis.read(bytes);
final String pattern = "Messages.getMessage(";
String string = new String(bytes);
while (true) {
int index = string.indexOf(pattern);
if (index < 0) break;
// Bump the string past the pattern-string
string = string.substring(index + pattern.length());
// Get the arguments for the getMessage call
String[] msgArgs = args(string);
// The first argument is the key.
// If the key is a literal string, check the usage.
// If the key is not a literal string, accept the usage.
if (msgArgs[0].startsWith("\"")) {
String key = msgArgs[0].substring(1, msgArgs[0].length() - 1);
// Get the raw message
String value = null;
try {
value = Messages.getMessage(key);
}
catch (Throwable t) {
errors = errors + "File: " + file.getPath() + " " + t.getMessage() + LS;
}
// The realParms count is the number of strings in the
// message of the form: {X} where X is 0..9
int realParms = count(value);
// The providedParms count is the number of arguments to
// getMessage, minus the first argument (key).
int providedParms = msgArgs.length - 1;
if (realParms != providedParms) {
errors = errors + "File: '" + file.getPath() + "', Key '" + key + "' specifies " + realParms + " {X} parameters, but " + providedParms + " parameter(s) provided." + LS;
}
}
}
}
catch (Throwable t) {
errors = errors + "File: " + file.getPath() + " " + t.getMessage() + LS;
}
} // checkMessages
/**
* For the given method call string, return the parameter strings.
* This means that everything between the first "(" and the last ")",
* and each "," encountered at the top level delimits a parameter.
*/
private String[] args (String string) {
int innerParens = 0;
Vector args = new Vector();
String arg = "";
while (true) {
if (string.startsWith("\"")) {
// Make sure we don't look for the following characters within quotes:
// , ' " ( )
String quote = readQuote(string);
arg = arg + quote;
string = string.substring(quote.length());
}
else if (string.startsWith("'")) {
// Make sure we ignore a quoted character
arg = arg + string.substring(0, 2);
string = string.substring(2);
}
else if (string.startsWith(",")) {
// If we're at the top level (ie., not inside inner parens like:
// (X, Y, new String(str, 0))), then we are seeing the end of an argument.
if (innerParens == 0) {
args.add(arg);
arg = "";
}
else {
arg = arg + ',';
}
string = string.substring(1);
}
else if (string.startsWith("(")) {
// We are stepping within a subexpression delimited by parens
++innerParens;
arg = arg + '(';
string = string.substring(1);
}
else if (string.startsWith(")")) {
// We are either stepping out of a subexpression delimited by parens, or we
// have reached the end of the parameter list.
if (innerParens == 0) {
args.add(arg);
String[] argsArray = new String[args.size()];
args.toArray(argsArray);
return argsArray;
}
else {
--innerParens;
arg = arg + ')';
string = string.substring(1);
}
}
else {
// We aren't looking at any special character, just add it to the arg string
// we're building.
if (!Character.isWhitespace(string.charAt(0))) {
arg = arg + string.charAt(0);
}
string = string.substring(1);
}
}
} // args
/**
* Collect a quoted string, making sure we really end when the string ends.
*/
private String readQuote(String string) {
String quote = "\"";
string = string.substring(1);
while (true) {
int index = string.indexOf('"');
if (index == 0 || string.charAt(index - 1) != '\\') {
quote = quote + string.substring(0, index + 1);
return quote;
}
else {
quote = quote + string.substring(0, index + 1);
string = string.substring(index);
}
}
} // readQuote
/**
* Count the number of strings of the form {X} where X = 0..9.
*/
private int count(String string) {
int parms = 0;
int index = string.indexOf("{");
while (index >= 0) {
try {
char parmNumber = string.charAt(index + 1);
if (parmNumber >= '0' && parmNumber <= '9' && string.charAt(index + 2) == '}') {
++parms;
}
string = string.substring(index + 1);
index = string.indexOf("{");
} catch (Throwable t) {
}
}
return parms;
} // count
}
|