Revision: 7071 Author: rice+leg...@google.com Date: Fri Nov 20 11:47:11 2009 Log: Merge a bunch of changes to the release branch.
tr...@6929 was merged into this branch Fix formatting of milliseconds in pre-1970 (i.e., negative) dates svn merge --ignore-ancestry -c6929 https://google-web-toolkit.googlecode.com/svn/trunk . tr...@6983 was merged into this branch Ensure server info from superclasses doesn't stomp on subclass info. svn merge --ignore-ancestry -c6983 https://google-web-toolkit.googlecode.com/svn/trunk . tr...@6996 was merged into this branch Pin modules in DevMode/DevModeBase until they are actually invoked. svn merge --ignore-ancestry -c6996 https://google-web-toolkit.googlecode.com/svn/trunk . tr...@7002 was merged into this branch Improve NumberFormat.format to avoid weird rounding issues svn merge --ignore-ancestry -c7002 https://google-web-toolkit.googlecode.com/svn/trunk . tr...@7043 was merged into this branch Work around Firefox issue where hasOwnProperty(new String(key)) fails svn merge --ignore-ancestry -c7043 https://google-web-toolkit.googlecode.com/svn/trunk . tr...@7044 was merged into this branch Fix mentions of 'hosted mode' in comments svn merge --ignore-ancestry -c7044 https://google-web-toolkit.googlecode.com/svn/trunk . tr...@7058 was merged into this branch Reinstate the help string and comment changes from r7040. svn merge --ignore-ancestry -c7058 https://google-web-toolkit.googlecode.com/svn/trunk . tr...@7059 was merged into this branch Fix javadoc typo (external issue 4252). svn merge --ignore-ancestry -c7059 https://google-web-toolkit.googlecode.com/svn/trunk . tr...@7060 was merged into this branch Simplify FF workaround for 'hasOwnProperty' String keys svn merge --ignore-ancestry -c7060 https://google-web-toolkit.googlecode.com/svn/trunk . tr...@7062 was merged into this branch Unify DevMode's startupModules and alreadySeen modules to simplify code svn merge --ignore-ancestry -c7062 https://google-web-toolkit.googlecode.com/svn/trunk . tr...@7063 was merged into this branch Simplify FF workaround for 'hasOwnProperty' String keys svn merge --ignore-ancestry -c7063 https://google-web-toolkit.googlecode.com/svn/trunk . http://code.google.com/p/google-web-toolkit/source/detail?r=7071 Modified: /releases/2.0/branch-info.txt /releases/2.0/dev/core/src/com/google/gwt/core/ext/ServletContainerLauncher.java /releases/2.0/dev/core/src/com/google/gwt/dev/DevMode.java /releases/2.0/dev/core/src/com/google/gwt/dev/DevModeBase.java /releases/2.0/dev/core/src/com/google/gwt/dev/cfg/ModuleDefLoader.java /releases/2.0/dev/core/src/com/google/gwt/dev/util/log/CompositeTreeLogger.java /releases/2.0/user/src/com/google/gwt/dom/client/Element.java /releases/2.0/user/src/com/google/gwt/i18n/client/DateTimeFormat.java /releases/2.0/user/src/com/google/gwt/i18n/client/Dictionary.java /releases/2.0/user/src/com/google/gwt/i18n/client/NumberFormat.java /releases/2.0/user/src/com/google/gwt/json/client/JSONObject.java /releases/2.0/user/src/com/google/gwt/junit/JUnitShell.java /releases/2.0/user/src/com/google/gwt/user/rebind/rpc/FieldSerializerCreator.java /releases/2.0/user/test/com/google/gwt/i18n/client/DateTimeFormat_en_Test.java /releases/2.0/user/test/com/google/gwt/i18n/client/NumberFormat_en_Test.java ======================================= --- /releases/2.0/branch-info.txt Fri Nov 20 10:37:09 2009 +++ /releases/2.0/branch-info.txt Fri Nov 20 11:47:11 2009 @@ -874,3 +874,46 @@ Ensures correct handling of (unknown) RuntimeExceptions thrown from deRPC service methods. svn merge --ignore-ancestry -c7049,7065 https://google-web-toolkit.googlecode.com/svn/trunk . +tr...@6929 was merged into this branch + Fix formatting of milliseconds in pre-1970 (i.e., negative) dates + svn merge --ignore-ancestry -c6929 https://google-web-toolkit.googlecode.com/svn/trunk . + +tr...@6983 was merged into this branch + Ensure server info from superclasses doesn't stomp on subclass info. + svn merge --ignore-ancestry -c6983 https://google-web-toolkit.googlecode.com/svn/trunk . + +tr...@6996 was merged into this branch + Pin modules in DevMode/DevModeBase until they are actually invoked. + svn merge --ignore-ancestry -c6996 https://google-web-toolkit.googlecode.com/svn/trunk . + +tr...@7002 was merged into this branch + Improve NumberFormat.format to avoid weird rounding issues + svn merge --ignore-ancestry -c7002 https://google-web-toolkit.googlecode.com/svn/trunk . + +tr...@7043 was merged into this branch + Work around Firefox issue where hasOwnProperty(new String(key)) fails + svn merge --ignore-ancestry -c7043 https://google-web-toolkit.googlecode.com/svn/trunk . + +tr...@7044 was merged into this branch + Fix mentions of 'hosted mode' in comments + svn merge --ignore-ancestry -c7044 https://google-web-toolkit.googlecode.com/svn/trunk . + +tr...@7058 was merged into this branch + Reinstate the help string and comment changes from r7040. + svn merge --ignore-ancestry -c7058 https://google-web-toolkit.googlecode.com/svn/trunk . + +tr...@7059 was merged into this branch + Fix javadoc typo (external issue 4252). + svn merge --ignore-ancestry -c7059 https://google-web-toolkit.googlecode.com/svn/trunk . + +tr...@7060 was merged into this branch + Simplify FF workaround for 'hasOwnProperty' String keys + svn merge --ignore-ancestry -c7060 https://google-web-toolkit.googlecode.com/svn/trunk . + +tr...@7062 was merged into this branch + Unify DevMode's startupModules and alreadySeen modules to simplify code + svn merge --ignore-ancestry -c7062 https://google-web-toolkit.googlecode.com/svn/trunk . + +tr...@7063 was merged into this branch + Simplify FF workaround for 'hasOwnProperty' String keys + svn merge --ignore-ancestry -c7063 https://google-web-toolkit.googlecode.com/svn/trunk . ======================================= --- /releases/2.0/dev/core/src/com/google/gwt/core/ext/ServletContainerLauncher.java Tue Oct 13 16:57:19 2009 +++ /releases/2.0/dev/core/src/com/google/gwt/core/ext/ServletContainerLauncher.java Fri Nov 20 11:47:11 2009 @@ -20,7 +20,7 @@ /** * Defines the service provider interface for launching servlet containers that - * can be used by the GWT hosted mode. + * can be used by the GWT development mode. */ public abstract class ServletContainerLauncher { ======================================= --- /releases/2.0/dev/core/src/com/google/gwt/dev/DevMode.java Thu Nov 19 14:41:30 2009 +++ /releases/2.0/dev/core/src/com/google/gwt/dev/DevMode.java Fri Nov 20 11:47:11 2009 @@ -37,6 +37,8 @@ import java.io.File; import java.io.IOException; import java.net.BindException; +import java.util.HashMap; +import java.util.Map; /** * The main executable class for the hosted mode shell. NOTE: the public API for @@ -253,6 +255,8 @@ */ private ServletContainer server; + private final Map<String, ModuleDef> startupModules = new HashMap<String, ModuleDef>(); + /** * Tracks whether we created a temp workdir that we need to destroy. */ @@ -324,6 +328,9 @@ TreeLogger moduleBranch = branch.branch(TreeLogger.TRACE, moduleName); try { ModuleDef module = loadModule(moduleBranch, moduleName, false); + // Create a hard reference to the module to avoid gc-ing it until we + // actually load the module from the browser. + startupModules.put(module.getName(), module); Util.recursiveDelete(options.getShellBaseWorkDir(module), false); validateServletTags(moduleBranch, servletValidator, module, webXml); TreeLogger loadLogger = moduleBranch.branch(TreeLogger.DEBUG, @@ -382,6 +389,16 @@ protected String getWebServerName() { return options.getServletContainerLauncher().getName(); } + + @Override + protected ModuleDef loadModule(TreeLogger logger, String moduleName, + boolean refresh) throws UnableToCompleteException { + if (startupModules.containsKey(moduleName)) { + // First load of a startup module; remove from list, no need to refresh. + return startupModules.remove(moduleName); + } + return super.loadModule(logger, moduleName, refresh); + } @Override protected synchronized void produceOutput(TreeLogger logger, ======================================= --- /releases/2.0/dev/core/src/com/google/gwt/dev/DevModeBase.java Thu Nov 19 20:36:53 2009 +++ /releases/2.0/dev/core/src/com/google/gwt/dev/DevModeBase.java Fri Nov 20 11:47:11 2009 @@ -54,11 +54,9 @@ import java.util.ArrayList; import java.util.Collections; import java.util.HashMap; -import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Random; -import java.util.Set; import java.util.concurrent.Semaphore; import java.util.concurrent.atomic.AtomicLong; @@ -572,8 +570,6 @@ registerHandler(new ArgHandlerRemoteUI(options)); } } - - protected static final Map<String, ModuleDef> startupModules = new HashMap<String, ModuleDef>(); private static final Random RNG = new Random(); @@ -654,14 +650,6 @@ protected DevModeUI ui = null; protected TreeLogger.Type baseLogLevelForUI = null; - /** - * Cheat on the first load's refresh by assuming the module loaded by - * {...@link com.google.gwt.dev.shell.GWTShellServlet} is still fresh. This - * prevents a double-refresh on startup. Subsequent refreshes will trigger a - * real refresh. - */ - private Set<String> alreadySeenModules = new HashSet<String>(); - private final Semaphore blockUntilDone = new Semaphore(0); private BrowserWidgetHost browserHost = new UiBrowserWidgetHostImpl(); @@ -901,10 +889,8 @@ */ protected ModuleDef loadModule(TreeLogger logger, String moduleName, boolean refresh) throws UnableToCompleteException { - refresh &= alreadySeenModules.contains(moduleName); ModuleDef moduleDef = ModuleDefLoader.loadFromClassPath(logger, moduleName, refresh); - alreadySeenModules.add(moduleName); assert (moduleDef != null) : "Required module state is absent"; return moduleDef; } ======================================= --- /releases/2.0/dev/core/src/com/google/gwt/dev/cfg/ModuleDefLoader.java Mon Nov 16 19:22:20 2009 +++ /releases/2.0/dev/core/src/com/google/gwt/dev/cfg/ModuleDefLoader.java Fri Nov 20 11:47:11 2009 @@ -28,6 +28,7 @@ import java.io.Reader; import java.net.URISyntaxException; import java.net.URL; +import java.util.HashMap; import java.util.HashSet; import java.util.Map; import java.util.Set; @@ -60,11 +61,17 @@ /** * Keep soft references to loaded modules so the VM can gc them when memory is - * tight. + * tight. The module's physical name is used as a key. */ @SuppressWarnings("unchecked") private static final Map<String, ModuleDef> loadedModules = new ReferenceMap( AbstractReferenceMap.HARD, AbstractReferenceMap.SOFT); + + /** + * A mapping from effective to physical module names. + */ + private static final Map<String, String> moduleEffectiveNameToPhysicalName = + new HashMap<String, String>(); /** * Creates a module in memory that is not associated with a @@ -96,7 +103,8 @@ } /** - * Loads a new module from the class path. + * Loads a new module from the class path. Equivalent to + * {...@link #loadFromClassPath(logger, moduleName, false)}. * * @param logger logs the process * @param moduleName the module to load @@ -107,7 +115,7 @@ throws UnableToCompleteException { return loadFromClassPath(logger, moduleName, false); } - + /** * Loads a new module from the class path. * @@ -119,6 +127,12 @@ */ public static ModuleDef loadFromClassPath(TreeLogger logger, String moduleName, boolean refresh) throws UnableToCompleteException { + // Look up the module's physical name; if null, we are either encountering + // the module for the first time, or else the name is already physical + String physicalName = moduleEffectiveNameToPhysicalName.get(moduleName); + if (physicalName != null) { + moduleName = physicalName; + } ModuleDef moduleDef = tryGetLoadedModule(logger, moduleName, refresh); if (moduleDef != null) { return moduleDef; @@ -275,8 +289,8 @@ // Add the "physical" module name: com.google.Module loadedModules.put(moduleName, moduleDef); - // Add the module's effective name: some.other.Module - loadedModules.put(moduleDef.getName(), moduleDef); + // Add a mapping from the module's effective name to its physical name + moduleEffectiveNameToPhysicalName.put(moduleDef.getName(), moduleName); return moduleDef; } } ======================================= --- /releases/2.0/dev/core/src/com/google/gwt/dev/util/log/CompositeTreeLogger.java Thu Nov 5 11:28:20 2009 +++ /releases/2.0/dev/core/src/com/google/gwt/dev/util/log/CompositeTreeLogger.java Fri Nov 20 11:47:11 2009 @@ -19,7 +19,7 @@ /** * Forks logging over two child loggers. This provides the graphics + file - * logging of HostedModeBase's -logfile option. + * logging of DevModeBase's -logfile option. */ public class CompositeTreeLogger extends TreeLogger { ======================================= --- /releases/2.0/user/src/com/google/gwt/dom/client/Element.java Tue May 19 08:35:33 2009 +++ /releases/2.0/user/src/com/google/gwt/dom/client/Element.java Fri Nov 20 11:47:11 2009 @@ -392,7 +392,7 @@ }-*/; /** - * The height of the scroll view of an element. + * The width of the scroll view of an element. */ public final native int getScrollWidth() /*-{ return this.scrollWidth || 0; ======================================= --- /releases/2.0/user/src/com/google/gwt/i18n/client/DateTimeFormat.java Tue Jul 14 10:17:53 2009 +++ /releases/2.0/user/src/com/google/gwt/i18n/client/DateTimeFormat.java Fri Nov 20 11:47:11 2009 @@ -989,7 +989,13 @@ // Fractional seconds should be left-justified, ie. zero must be padded // from left. For example, if value in milliseconds is 5, and count is 3, // the output need to be "005". - int value = (int) (date.getTime() % 1000); + long time = date.getTime(); + int value; + if (time < 0) { + value = 1000 - (int) (-time % 1000); + } else { + value = (int) (time % 1000); + } if (count == 1) { value = (value + 50) / 100; // Round to 100ms. buf.append(Integer.toString(value)); ======================================= --- /releases/2.0/user/src/com/google/gwt/i18n/client/Dictionary.java Mon Nov 16 08:35:40 2009 +++ /releases/2.0/user/src/com/google/gwt/i18n/client/Dictionary.java Fri Nov 20 11:47:11 2009 @@ -143,6 +143,8 @@ * @throws MissingResourceException if the value is not found */ public native String get(String key) /*-{ + // In Firefox, jsObject.hasOwnProperty(key) requires a primitive string + key = String(key); var map = th...@com.google.gwt.i18n.client.dictionary::dict; var value = map[key]; var keys = th...@com.google.gwt.i18n.client.dictionary::accessedKeys; ======================================= --- /releases/2.0/user/src/com/google/gwt/i18n/client/NumberFormat.java Sun Oct 18 11:53:33 2009 +++ /releases/2.0/user/src/com/google/gwt/i18n/client/NumberFormat.java Fri Nov 20 11:47:11 2009 @@ -117,7 +117,7 @@ * </tr> * * <tr> - * <td><code>E</code></td> + * <td><code>;</code></td> * <td>Number</td> * <td>Yes</td> * <td>Separates mantissa and exponent in scientific notation; need not be @@ -580,6 +580,10 @@ return "\u00A0"; } + private static native String toFixed(double d, int digits) /*-{ + return d.toFixed(digits); + }-*/; + // The currency code. private final String currencyCode; @@ -1308,15 +1312,38 @@ */ private void subformatFixed(double number, StringBuffer result, int minIntDigits) { - // Round the number. double power = Math.pow(10, maximumFractionDigits); - double intValue = Math.floor(number); - // we don't want to use Math.round, 'cause that returns a long which JS - // then has to emulate... Math.floor(x + 0.5d) is defined to be equivalent - double fracValue = Math.floor((number - intValue) * power + 0.5d); - if (fracValue >= power) { - intValue += 1.0; - fracValue -= power; + // Use 3 extra digits to allow us to do our own rounding since + // Java rounds up on .5 whereas some browsers might use 'round to even' + // or other rules. + + // There are cases where more digits would be required to get + // guaranteed results, but this at least makes such cases rarer. + String fixedString = toFixed(number, maximumFractionDigits + 3); + + double intValue = 0, fracValue = 0; + int exponentIndex = fixedString.indexOf('e'); + if (exponentIndex != -1) { + // Large numbers may be returned in exponential notation: such numbers + // are integers anyway + intValue = Math.floor(number); + } else { + int decimalIndex = fixedString.indexOf('.'); + int len = fixedString.length(); + if (decimalIndex == -1) { + decimalIndex = len; + } + if (decimalIndex > 0) { + intValue = Double.parseDouble(fixedString.substring(0, decimalIndex)); + } + if (decimalIndex < len - 1) { + fracValue = Double.parseDouble(fixedString.substring(decimalIndex + 1)); + fracValue = (((int) fracValue) + 500) / 1000; + if (fracValue >= power) { + fracValue -= power; + intValue++; + } + } } boolean fractionPresent = (minimumFractionDigits > 0) || (fracValue > 0); ======================================= --- /releases/2.0/user/src/com/google/gwt/json/client/JSONObject.java Mon Nov 16 18:58:42 2009 +++ /releases/2.0/user/src/com/google/gwt/json/client/JSONObject.java Fri Nov 20 11:47:11 2009 @@ -195,7 +195,9 @@ private native void addAllKeys(Collection<String> s) /*-{ var jsObject = th...@com.google.gwt.json.client.jsonobject::jsObject; for (var key in jsObject) { - s...@java.util.collection::add(Ljava/lang/Object;)(key); + if (jsObject.hasOwnProperty(key)) { + s...@java.util.collection::add(Ljava/lang/Object;)(key); + } } }-*/; @@ -213,7 +215,9 @@ var jsObject = th...@com.google.gwt.json.client.jsonobject::jsObject; var i = 0; for (var key in jsObject) { - result[i++] = key; + if (jsObject.hasOwnProperty(key)) { + result[i++] = key; + } } return result; }-*/; @@ -222,15 +226,24 @@ var jsObject = th...@com.google.gwt.json.client.jsonobject::jsObject; var size = 0; for (var key in jsObject) { - ++size; + if (jsObject.hasOwnProperty(key)) { + ++size; + } } return size; }-*/; private native JSONValue get0(String key) /*-{ - var v = th...@com.google.gwt.json.client.jsonobject::jsObject[key]; + var jsObject = th...@com.google.gwt.json.client.jsonobject::jsObject; + var v; + // In Firefox, jsObject.hasOwnProperty(key) requires a primitive string + key = String(key); + if (jsObject.hasOwnProperty(key)) { + v = jsObject[key]; + } var func = @com.google.gwt.json.client.JSONParser::typeMap[typeof v]; - return func ? func(v) : @com.google.gwt.json.client.JSONParser::throwUnknownTypeException(Ljava/lang/String;)(typeof v); + var ret = func ? func(v) : @com.google.gwt.json.client.JSONParser::throwUnknownTypeException(Ljava/lang/String;)(typeof v); + return ret; }-*/; private native void put0(String key, JSONValue value) /*-{ ======================================= --- /releases/2.0/user/src/com/google/gwt/junit/JUnitShell.java Thu Nov 19 14:34:20 2009 +++ /releases/2.0/user/src/com/google/gwt/junit/JUnitShell.java Fri Nov 20 11:47:11 2009 @@ -148,7 +148,7 @@ registerHandler(new ArgHandlerFlag() { @Override public String getPurpose() { - return "Causes your test to run in -noserver hosted mode (defaults to hosted mode)"; + return "Causes your test to run in -noserver development mode (defaults to development mode)"; } @Override @@ -166,7 +166,7 @@ registerHandler(new ArgHandlerFlag() { @Override public String getPurpose() { - return "Causes your test to run in web (compiled) mode (defaults to hosted mode)"; + return "Causes your test to run in web (compiled) mode (defaults to development mode)"; } @Override @@ -648,7 +648,7 @@ private TestInfo currentTestInfo; /** - * True if we are running the test in hosted mode. + * True if we are running the test in development mode. */ private boolean developmentMode = true; @@ -689,7 +689,7 @@ private String[] remoteUserAgents; /** - * What type of test we're running; Local hosted, local web, or remote web. + * What type of test we're running; Local development, local web, or remote web. */ private RunStyle runStyle = null; @@ -933,7 +933,7 @@ } /** - * Accessor method to HostedModeBase.setHeadless -- without this, we get + * Accessor method to DevModeBase.setHeadless -- without this, we get * IllegalAccessError from the -notHeadless arg handler. Compiler bug? * * @param headlessMode ======================================= --- /releases/2.0/user/src/com/google/gwt/user/rebind/rpc/FieldSerializerCreator.java Thu Nov 19 14:34:20 2009 +++ /releases/2.0/user/src/com/google/gwt/user/rebind/rpc/FieldSerializerCreator.java Fri Nov 20 11:47:11 2009 @@ -121,6 +121,18 @@ return sb.toString(); } + + /** + * Returns the depth of the given class in the class hierarchy + * (where the depth of java.lang.Object == 0). + */ + private int getDepth(JClassType clazz) { + int depth = 0; + while ((clazz = clazz.getSuperclass()) != null) { + depth++; + } + return depth; + } private SourceWriter getSourceWriter(TreeLogger logger, GeneratorContext ctx) { String qualifiedSerializerName = SerializationUtils.getFieldSerializerName( @@ -272,7 +284,9 @@ */ if (serializableClass.isEnhanced()) { sourceWriter.println(WEAK_MAPPING_CLASS_NAME + ".set(instance, " - + "\"server-enhanced-data\", streamReader.readString());"); + + "\"server-enhanced-data-" + + getDepth(serializableClass) + + "\", streamReader.readString());"); } for (JField serializableField : serializableFields) { @@ -320,7 +334,9 @@ if (serializableClass.isEnhanced()) { sourceWriter.println("streamWriter.writeString((String) " - + WEAK_MAPPING_CLASS_NAME + ".get(instance, \"server-enhanced-data\"));"); + + WEAK_MAPPING_CLASS_NAME + + ".get(instance, \"server-enhanced-data-" + + getDepth(serializableClass) + "\"));"); } for (JField serializableField : serializableFields) { ======================================= --- /releases/2.0/user/test/com/google/gwt/i18n/client/DateTimeFormat_en_Test.java Mon Nov 24 14:39:21 2008 +++ /releases/2.0/user/test/com/google/gwt/i18n/client/DateTimeFormat_en_Test.java Fri Nov 20 11:47:11 2009 @@ -22,7 +22,7 @@ import java.util.Date; /** - * Tests formatting functionality in {...@link DateTimeFormat} for the German + * Tests formatting functionality in {...@link DateTimeFormat} for the English * language. */ public class DateTimeFormat_en_Test extends GWTTestCase { @@ -415,4 +415,16 @@ assertEquals("10/29/2006 01:00:00 PST", DateTimeFormat.getFormat( "MM/dd/yyyy HH:mm:ss z").format(date, usPacific)); } -} + + public void testPre1970Milliseconds() { + Date date = new Date(-631151998945L); // Jan 1, 1950 00:00:01.055 UTC + + long midnight = Date.UTC(1950 - 1900, 0, 1, 0, 0, 1); + assertEquals(-631151998945L, midnight + 55); + + TimeZone utc = TimeZone.createTimeZone(0); + assertEquals("055", DateTimeFormat.getFormat("SSS").format(date, utc)); + assertEquals("06", DateTimeFormat.getFormat("SS").format(date, utc)); + assertEquals("1", DateTimeFormat.getFormat("S").format(date, utc)); + } +} ======================================= --- /releases/2.0/user/test/com/google/gwt/i18n/client/NumberFormat_en_Test.java Sun Oct 18 11:53:33 2009 +++ /releases/2.0/user/test/com/google/gwt/i18n/client/NumberFormat_en_Test.java Fri Nov 20 11:47:11 2009 @@ -357,4 +357,62 @@ str = NumberFormat.getFormat("#").format(0); assertEquals("0", str); } -} + + public void testRounding() { + String str; + + str = NumberFormat.getFormat("#0.##").format(0.555); + assertEquals("0.56", str); + + str = NumberFormat.getFormat("#.##").format(30.555); + assertEquals("30.56", str); + + str = NumberFormat.getFormat("#.00").format(0.997); + assertEquals("1.00", str); + + str = NumberFormat.getFormat("#.00").format(-0.997); + assertEquals("-1.00", str); + + str = NumberFormat.getFormat("#.00").format(27.997); + assertEquals("28.00", str); + + str = NumberFormat.getFormat("#.00").format(-27.997); + assertEquals("-28.00", str); + + str = NumberFormat.getFormat("#0.00000").format(1.23456789E-03); + assertEquals("0.00123", str); + + str = NumberFormat.getFormat("#0.0000000").format(1.23456789E-03); + assertEquals("0.0012346", str); + + str = NumberFormat.getFormat("#0.0000").format(1.2E-03); + assertEquals("0.0012", str); + + str = NumberFormat.getFormat("#0.000").format(1.2E-03); + assertEquals("0.001", str); + + str = NumberFormat.getFormat("#0.00").format(1.2E-03); + assertEquals("0.00", str); + + str = NumberFormat.getFormat("#0.0").format(1.2E-03); + assertEquals("0.0", str); + + str = NumberFormat.getFormat("#0.00").format(11.2E-03); + assertEquals("0.01", str); + + str = NumberFormat.getFormat("#0.00").format(111.2E-03); + assertEquals("0.11", str); + + str = NumberFormat.getFormat("#0.00").format(1111.2E-03); + assertEquals("1.11", str); + + str = NumberFormat.getFormat("#0.00000").format(1.23456789E-05); + assertEquals("0.00001", str); + + str = NumberFormat.getFormat("#0.0000000").format(1.23456789E-05); + assertEquals("0.0000123", str); + + str = NumberFormat.getFormat("#0.0000000").format(1.23756789E-05); + assertEquals("0.0000124", str); + } +} -- http://groups.google.com/group/Google-Web-Toolkit-Contributors