Author: etnu
Date: Sat Jun  7 15:17:35 2008
New Revision: 664406

URL: http://svn.apache.org/viewvc?rev=664406&view=rev
Log:
Applied Gonzalo Aune's patch for SHINDIG-340, with some small modifications and 
a lot of new tests.


Added:
    
incubator/shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/BasicMessageBundleFactoryTest.java
Modified:
    
incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/BasicMessageBundleFactory.java
    
incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/spec/LocaleSpec.java
    
incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/spec/MessageBundle.java
    
incubator/shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/spec/LocaleSpecTest.java
    
incubator/shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/spec/MessageBundleTest.java

Modified: 
incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/BasicMessageBundleFactory.java
URL: 
http://svn.apache.org/viewvc/incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/BasicMessageBundleFactory.java?rev=664406&r1=664405&r2=664406&view=diff
==============================================================================
--- 
incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/BasicMessageBundleFactory.java
 (original)
+++ 
incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/BasicMessageBundleFactory.java
 Sat Jun  7 15:17:35 2008
@@ -18,9 +18,6 @@
  */
 package org.apache.shindig.gadgets;
 
-import com.google.inject.Inject;
-import com.google.inject.name.Named;
-
 import org.apache.shindig.common.cache.Cache;
 import org.apache.shindig.common.cache.LruCache;
 import org.apache.shindig.gadgets.http.HttpFetcher;
@@ -29,6 +26,9 @@
 import org.apache.shindig.gadgets.spec.LocaleSpec;
 import org.apache.shindig.gadgets.spec.MessageBundle;
 
+import com.google.inject.Inject;
+import com.google.inject.name.Named;
+
 import java.net.URI;
 import java.util.logging.Level;
 import java.util.logging.Logger;
@@ -49,11 +49,19 @@
 
   public MessageBundle getBundle(LocaleSpec localeSpec, GadgetContext context)
       throws GadgetException {
-    return getBundle(localeSpec.getMessages(), context.getIgnoreCache());
+    URI messages = localeSpec.getMessages();
+    if (messages == null || messages.toString().length() == 0) {
+      return localeSpec.getMessageBundle();
+    }
+    return getBundle(messages, context.getIgnoreCache());
   }
 
   public MessageBundle getBundle(URI bundleUrl, boolean ignoreCache)
       throws GadgetException {
+    if (ignoreCache) {
+      return fetchBundleFromWeb(bundleUrl, true);
+    }
+
     MessageBundle bundle = null;
     long expiration = -1;
     synchronized (inMemoryBundleCache) {
@@ -63,25 +71,9 @@
         expiration = entry.timeout;
       }
     }
-    if (ignoreCache || bundle == null || expiration < 
System.currentTimeMillis()) {
+    if (bundle == null || expiration < System.currentTimeMillis()) {
       try {
-        HttpRequest request
-            = HttpRequest.getRequest(bundleUrl, ignoreCache);
-        HttpResponse response = bundleFetcher.fetch(request);
-        if (response.getHttpStatusCode() != HttpResponse.SC_OK) {
-          throw new GadgetException(
-              GadgetException.Code.FAILED_TO_RETRIEVE_CONTENT,
-              "Unable to retrieve message bundle xml. HTTP error " +
-                  response.getHttpStatusCode());
-        }
-        bundle = new MessageBundle(bundleUrl, response.getResponseAsString());
-
-        // Add the updated bundle back to the cache and force the min TTL
-        expiration = Math
-            .max(response.getCacheExpiration(), System.currentTimeMillis() + 
bundleMinTTL);
-        synchronized (inMemoryBundleCache) {
-          inMemoryBundleCache.addElement(bundleUrl, new 
BundleTimeoutPair(bundle, expiration));
-        }
+        return fetchBundleFromWeb(bundleUrl, false);
       } catch (GadgetException ge) {
         if (bundle == null) {
           throw ge;
@@ -94,6 +86,27 @@
     return bundle;
   }
 
+  private MessageBundle fetchBundleFromWeb(URI bundleUrl, boolean ignoreCache)
+      throws GadgetException {
+    HttpRequest request = HttpRequest.getRequest(bundleUrl, ignoreCache);
+    HttpResponse response = bundleFetcher.fetch(request);
+    if (response.getHttpStatusCode() != HttpResponse.SC_OK) {
+      throw new 
GadgetException(GadgetException.Code.FAILED_TO_RETRIEVE_CONTENT,
+          "Unable to retrieve message bundle xml. HTTP error " +
+          response.getHttpStatusCode());
+    }
+    MessageBundle bundle
+        = new MessageBundle(bundleUrl, response.getResponseAsString());
+
+    synchronized (inMemoryBundleCache) {
+      long expiration = Math.max(response.getCacheExpiration(),
+          System.currentTimeMillis() + bundleMinTTL);
+      inMemoryBundleCache.addElement(bundleUrl,
+          new BundleTimeoutPair(bundle, expiration));
+    }
+    return bundle;
+  }
+
   @Inject
   public BasicMessageBundleFactory(HttpFetcher bundleFetcher,
       @Named("message-bundle.cache.capacity")int messageBundleCacheCapacity,

Modified: 
incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/spec/LocaleSpec.java
URL: 
http://svn.apache.org/viewvc/incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/spec/LocaleSpec.java?rev=664406&r1=664405&r2=664406&view=diff
==============================================================================
--- 
incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/spec/LocaleSpec.java
 (original)
+++ 
incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/spec/LocaleSpec.java
 Sat Jun  7 15:17:35 2008
@@ -24,6 +24,7 @@
 import java.net.URI;
 import java.net.URISyntaxException;
 import java.net.URL;
+import java.util.Map;
 
 /**
  * Represents a Locale tag.
@@ -68,18 +69,28 @@
     return messages;
   }
 
+  /**
+   * Locale/msg
+   */
+  private final MessageBundle messageBundle;
+  public MessageBundle getMessageBundle() {
+    return messageBundle;
+  }
+
   @Override
   public String toString() {
     StringBuilder buf = new StringBuilder();
-    buf.append("<Locale lang=\"")
-       .append(language)
-       .append("\" country=\"")
-       .append(country)
-       .append("\" language_direction=\"")
-       .append(languageDirection)
-       .append("\" messages=\"")
-       .append(messages)
-       .append("\"/>");
+    buf.append("<Locale")
+       .append(" lang='").append(language).append("'")
+       .append(" country='").append(country).append("'")
+       .append(" language_direction='").append(languageDirection).append("'")
+       .append(" messages='").append(messages).append("'>\n");
+    for (Map.Entry<String, String> entry : 
messageBundle.getMessages().entrySet()) {
+      buf.append("<msg name='").append(entry.getKey()).append("'>")
+         .append(entry.getValue())
+         .append("</msg>\n");
+    }
+    buf.append("</Locale>");
     return buf.toString();
   }
 
@@ -111,5 +122,6 @@
         throw new SpecParserException("[EMAIL PROTECTED] url is invalid.");
       }
     }
+    messageBundle = new MessageBundle(element);
   }
 }

Modified: 
incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/spec/MessageBundle.java
URL: 
http://svn.apache.org/viewvc/incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/spec/MessageBundle.java?rev=664406&r1=664405&r2=664406&view=diff
==============================================================================
--- 
incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/spec/MessageBundle.java
 (original)
+++ 
incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/spec/MessageBundle.java
 Sat Jun  7 15:17:35 2008
@@ -36,6 +36,7 @@
   public static final MessageBundle EMPTY = new MessageBundle();
 
   private final Map<String, String> messages;
+
   /**
    * @return A read-only view of the message bundle.
    */
@@ -43,6 +44,27 @@
     return messages;
   }
 
+  /**
+   * Extracts messages from an element.
+   */
+  private Map<String, String> parseMessages(Element element)
+      throws SpecParserException {
+    NodeList nodes = element.getElementsByTagName("msg");
+    Map<String, String> messages
+        = new HashMap<String, String>(nodes.getLength(), 1);
+
+    for (int i = 0, j = nodes.getLength(); i < j; ++i) {
+      Element msg = (Element)nodes.item(i);
+      String name = XmlUtil.getAttribute(msg, "name");
+      if (name == null) {
+        throw new SpecParserException(
+            "All message bundle entries must have a name attribute.");
+      }
+      messages.put(name, msg.getTextContent().trim());
+    }
+    return Collections.unmodifiableMap(messages);
+  }
+
   @Override
   public String toString() {
     StringBuilder buf = new StringBuilder();
@@ -69,21 +91,14 @@
       throw new SpecParserException("Malformed XML in file " + url.toString()
           + ": " + e.getMessage());
     }
+    messages = parseMessages(doc);
+  }
 
-    NodeList nodes = doc.getElementsByTagName("msg");
-    Map<String, String> messages
-        = new HashMap<String, String>(nodes.getLength(), 1);
-
-    for (int i = 0, j = nodes.getLength(); i < j; ++i) {
-      Element msg = (Element)nodes.item(i);
-      String name = XmlUtil.getAttribute(msg, "name");
-      if (name == null) {
-        throw new SpecParserException(
-            "All message bundle entries must have a name attribute.");
-      }
-      messages.put(name, msg.getTextContent().trim());
-    }
-    this.messages = Collections.unmodifiableMap(messages);
+  /**
+   * Constructs a message bundle from an existing element.
+   */
+  public MessageBundle(Element element) throws SpecParserException {
+    messages = parseMessages(element);
   }
 
   private MessageBundle() {

Added: 
incubator/shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/BasicMessageBundleFactoryTest.java
URL: 
http://svn.apache.org/viewvc/incubator/shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/BasicMessageBundleFactoryTest.java?rev=664406&view=auto
==============================================================================
--- 
incubator/shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/BasicMessageBundleFactoryTest.java
 (added)
+++ 
incubator/shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/BasicMessageBundleFactoryTest.java
 Sat Jun  7 15:17:35 2008
@@ -0,0 +1,143 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.shindig.gadgets;
+
+import static org.easymock.EasyMock.expect;
+import static org.easymock.EasyMock.isA;
+import static org.easymock.EasyMock.replay;
+import static org.easymock.EasyMock.verify;
+import static org.junit.Assert.assertEquals;
+
+import org.apache.shindig.common.xml.XmlUtil;
+import org.apache.shindig.gadgets.http.HttpFetcher;
+import org.apache.shindig.gadgets.http.HttpRequest;
+import org.apache.shindig.gadgets.http.HttpResponse;
+import org.apache.shindig.gadgets.spec.LocaleSpec;
+import org.apache.shindig.gadgets.spec.MessageBundle;
+
+import com.google.common.collect.Maps;
+
+import org.easymock.EasyMock;
+import org.junit.Test;
+
+import java.net.URI;
+import java.util.Arrays;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * Tests for BasicMessageBundleFactory
+ */
+public class BasicMessageBundleFactoryTest {
+  private final static URI BUNDLE_URI
+      = URI.create("http://example.org/messagex.xml";);
+  private final static URI SPEC_URI
+      = URI.create("http://example.org/gadget.xml";);
+
+  private final static String MSG_0_NAME = "messageZero";
+  private final static String MSG_1_NAME = "message1";
+  private final static String MSG_0_VALUE = "Message 0 VALUE";
+  private final static String MSG_1_VALUE = "msg one val";
+  private final static String BASIC_BUNDLE
+      = "<messagebundle>" +
+        "  <msg name='" + MSG_0_NAME + "'>" + MSG_0_VALUE + "</msg>" +
+        "  <msg name='" + MSG_1_NAME + "'>" + MSG_1_VALUE + "</msg>" +
+        "</messagebundle>";
+  private final static GadgetContext NO_CACHE_CONTEXT = new GadgetContext() {
+    @Override
+    public boolean getIgnoreCache() {
+      return true;
+    }
+  };
+
+  private final HttpFetcher fetcher = 
EasyMock.createNiceMock(HttpFetcher.class);
+  private final MessageBundleFactory bundleFactory;
+
+  public BasicMessageBundleFactoryTest() {
+    bundleFactory = new BasicMessageBundleFactory(fetcher, 5, -1000);
+  }
+
+  @Test
+  public void getBundleByUri() throws Exception {
+    HttpResponse response = new HttpResponse(BASIC_BUNDLE);
+
+    expect(fetcher.fetch(isA(HttpRequest.class))).andReturn(response);
+    replay(fetcher);
+
+    MessageBundle bundle = bundleFactory.getBundle(BUNDLE_URI, true);
+
+    assertEquals(MSG_0_VALUE, bundle.getMessages().get(MSG_0_NAME));
+    assertEquals(MSG_1_VALUE, bundle.getMessages().get(MSG_1_NAME));
+  }
+
+  @Test
+  public void getBundleByLocaleSpec() throws Exception {
+    String localeXml = "<Locale messages='" + BUNDLE_URI + "'/>";
+    LocaleSpec locale = new LocaleSpec(XmlUtil.parse(localeXml), SPEC_URI);
+    HttpResponse response = new HttpResponse(BASIC_BUNDLE);
+
+    expect(fetcher.fetch(isA(HttpRequest.class))).andReturn(response);
+    replay(fetcher);
+
+    MessageBundle bundle = bundleFactory.getBundle(locale, NO_CACHE_CONTEXT);
+
+    assertEquals(MSG_0_VALUE, bundle.getMessages().get(MSG_0_NAME));
+    assertEquals(MSG_1_VALUE, bundle.getMessages().get(MSG_1_NAME));
+  }
+
+  @Test
+  public void getBundleByLocaleSpecWithNestedMessages() throws Exception {
+    String localeXml
+        = "<Locale>" +
+          "<msg name='" + MSG_0_NAME + "'>" + MSG_0_VALUE + "</msg>" +
+          "</Locale>";
+    LocaleSpec locale = new LocaleSpec(XmlUtil.parse(localeXml), SPEC_URI);
+
+    MessageBundle bundle = bundleFactory.getBundle(locale, NO_CACHE_CONTEXT);
+
+    assertEquals(MSG_0_VALUE, bundle.getMessages().get(MSG_0_NAME));
+  }
+
+  @Test
+  public void badResponseServedFromCache() throws Exception {
+    String localeXml
+        = "<Locale>" +
+          "<msg name='" + MSG_0_NAME + "'>" + MSG_0_VALUE + "</msg>" +
+          "</Locale>";
+    LocaleSpec locale = new LocaleSpec(XmlUtil.parse(localeXml), SPEC_URI);
+    Map<String, List<String>> headers = Maps.newHashMap();
+    headers.put("Pragma", Arrays.asList("no-cache"));
+    HttpResponse expiredResponse = new HttpResponse(
+        HttpResponse.SC_OK, BASIC_BUNDLE.getBytes("UTF-8"), headers);
+    HttpResponse badResponse = HttpResponse.error();
+
+    expect(fetcher.fetch(isA(HttpRequest.class)))
+        .andReturn(expiredResponse).once();
+    expect(fetcher.fetch(isA(HttpRequest.class)))
+        .andReturn(badResponse).once();
+    replay(fetcher);
+
+    MessageBundle bundle = bundleFactory.getBundle(BUNDLE_URI, true);
+    MessageBundle bundle2 = bundleFactory.getBundle(BUNDLE_URI, false);
+
+    verify(fetcher);
+
+    assertEquals(MSG_0_VALUE, bundle2.getMessages().get(MSG_0_NAME));
+  }
+}

Modified: 
incubator/shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/spec/LocaleSpecTest.java
URL: 
http://svn.apache.org/viewvc/incubator/shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/spec/LocaleSpecTest.java?rev=664406&r1=664405&r2=664406&view=diff
==============================================================================
--- 
incubator/shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/spec/LocaleSpecTest.java
 (original)
+++ 
incubator/shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/spec/LocaleSpecTest.java
 Sat Jun  7 15:17:35 2008
@@ -19,16 +19,19 @@
 
 package org.apache.shindig.gadgets.spec;
 
+import static org.junit.Assert.assertEquals;
+
 import org.apache.shindig.common.xml.XmlUtil;
 
-import junit.framework.TestCase;
+import org.junit.Test;
 
 import java.net.URI;
 
-public class LocaleSpecTest extends TestCase {
+public class LocaleSpecTest {
   private static final URI SPEC_URL = URI.create("http://example.org/foo.xml";);
 
-  public void testNormalLocale() throws Exception {
+  @Test
+  public void normalLocale() throws Exception {
     String xml = "<Locale" +
                  " lang=\"en\"" +
                  " country=\"US\"" +
@@ -43,37 +46,59 @@
         locale.getMessages().toString());
   }
 
-  public void testRelativeLocale() throws Exception {
+  @Test
+  public void relativeLocale() throws Exception {
     String xml = "<Locale messages=\"/test/msgs.xml\"/>";
     LocaleSpec locale = new LocaleSpec(XmlUtil.parse(xml), SPEC_URL);
     assertEquals("http://example.org/test/msgs.xml";,
         locale.getMessages().toString());
   }
 
-  public void testDefaultLanguageAndCountry() throws Exception {
+  @Test
+  public void defaultLanguageAndCountry() throws Exception {
     String xml = "<Locale/>";
     LocaleSpec locale = new LocaleSpec(XmlUtil.parse(xml), SPEC_URL);
     assertEquals("all", locale.getLanguage());
     assertEquals("ALL", locale.getCountry());
   }
 
-  public void testInvalidLanguageDirection() throws Exception {
+  @Test(expected = SpecParserException.class)
+  public void invalidLanguageDirection() throws Exception {
     String xml = "<Locale language_direction=\"invalid\"/>";
-    try {
-      LocaleSpec locale = new LocaleSpec(XmlUtil.parse(xml), SPEC_URL);
-      fail("No exception thrown when invalid language_direction is 
specified.");
-    } catch (SpecParserException e) {
-      // OK.
-    }
+    LocaleSpec locale = new LocaleSpec(XmlUtil.parse(xml), SPEC_URL);
   }
 
-  public void testInvalidMessagesUrl() throws Exception {
+  @Test(expected = SpecParserException.class)
+  public void invalidMessagesUrl() throws Exception {
     String xml = "<Locale messages=\"[EMAIL PROTECTED]"/>";
-    try {
-      LocaleSpec locale = new LocaleSpec(XmlUtil.parse(xml), SPEC_URL);
-      fail("No exception thrown when invalid messages url is specified.");
-    } catch (SpecParserException e) {
-      // OK.
-    }
+    LocaleSpec locale = new LocaleSpec(XmlUtil.parse(xml), SPEC_URL);
+  }
+
+  @Test
+  public void nestedMessages() throws Exception {
+    String msgName = "message name";
+    String msgValue = "message value";
+    String xml = "<Locale>" +
+                 "<msg name=\"" + msgName + "\">" + msgValue + "</msg>" +
+                 "</Locale>";
+    LocaleSpec locale = new LocaleSpec(XmlUtil.parse(xml), SPEC_URL);
+    assertEquals(msgValue, 
locale.getMessageBundle().getMessages().get(msgName));
+  }
+
+  @Test
+  public void toStringIsSane() throws Exception {
+    String xml = "<Locale lang='en' country='US' language_direction='rtl'" +
+                 " messages='foo'>" +
+                 "  <msg name='hello'>World</msg>" +
+                 "  <msg name='foo'>Bar</msg>" +
+                 "</Locale>";
+    LocaleSpec loc = new LocaleSpec(XmlUtil.parse(xml), SPEC_URL);
+    LocaleSpec loc2 = new LocaleSpec(XmlUtil.parse(loc.toString()), SPEC_URL);
+    assertEquals(loc.getLanguage(), loc2.getLanguage());
+    assertEquals(loc.getCountry(), loc2.getCountry());
+    assertEquals(loc.getLanguageDirection(), loc2.getLanguageDirection());
+    assertEquals(loc.getMessages(), loc2.getMessages());
+    assertEquals(loc.getMessageBundle().getMessages(),
+                 loc2.getMessageBundle().getMessages());
   }
 }

Modified: 
incubator/shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/spec/MessageBundleTest.java
URL: 
http://svn.apache.org/viewvc/incubator/shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/spec/MessageBundleTest.java?rev=664406&r1=664405&r2=664406&view=diff
==============================================================================
--- 
incubator/shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/spec/MessageBundleTest.java
 (original)
+++ 
incubator/shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/spec/MessageBundleTest.java
 Sat Jun  7 15:17:35 2008
@@ -19,50 +19,72 @@
 
 package org.apache.shindig.gadgets.spec;
 
-import junit.framework.TestCase;
+import static org.junit.Assert.assertEquals;
 
-import org.apache.shindig.gadgets.GadgetException;
+import org.apache.shindig.common.xml.XmlUtil;
+
+import com.google.common.collect.Maps;
+
+import org.junit.Test;
+import org.w3c.dom.Element;
 
 import java.net.URI;
-import java.util.HashMap;
 import java.util.Map;
 
-public class MessageBundleTest extends TestCase {
+public class MessageBundleTest {
   private static final URI BUNDLE_URL = URI.create("http://example.org/m.xml";);
-  public void testNormalMessageBundle() throws Exception {
-    Map<String, String> messages = new HashMap<String, String>();
-    messages.put("hello", "world");
-    messages.put("foo", "bar");
-
-    String xml = "<messagebundle>";
-    for (Map.Entry<String, String> entry : messages.entrySet()) {
-      xml += "<msg name=\"" + entry.getKey() + "\">" + entry.getValue() +
-          "</msg>";
+  private static final Map<String, String> MESSAGES = Maps.newHashMap();
+  private static final String XML;
+  static {
+    MESSAGES.put("hello", "world");
+    MESSAGES.put("foo", "bar");
+    StringBuilder buf = new StringBuilder();
+    buf.append("<messagebundle>");
+    for (Map.Entry<String, String> entry : MESSAGES.entrySet()) {
+      buf.append("<msg name='").append(entry.getKey()).append("'>")
+         .append(entry.getValue())
+         .append("</msg>");
     }
-    xml += "</messagebundle>";
-    MessageBundle bundle = new MessageBundle(BUNDLE_URL, xml);
-    assertEquals(messages, bundle.getMessages());
+    buf.append("</messagebundle>");
+    XML = buf.toString();
+  }
+
+  @Test
+  public void normalMessageBundleParsesOk() throws Exception {
+    MessageBundle bundle = new MessageBundle(BUNDLE_URL, XML);
+    assertEquals(MESSAGES, bundle.getMessages());
   }
 
-  public void testMissingNames() {
+  @Test(expected = SpecParserException.class)
+  public void missingNameThrows() throws SpecParserException {
     String xml = "<messagebundle><msg>foo</msg></messagebundle>";
-    try {
-      MessageBundle bundle = new MessageBundle(BUNDLE_URL, xml);
-      fail("No exception thrown when a msg has no name.");
-    } catch (SpecParserException e) {
-      // OK.
-    }
+    MessageBundle bundle = new MessageBundle(BUNDLE_URL, xml);
   }
 
-  public void testMalformedXml() {
+  @Test(expected = SpecParserException.class)
+  public void malformedXmlThrows() throws SpecParserException {
     String xml = "</messagebundle>";
-    try {
-      MessageBundle bundle = new MessageBundle(BUNDLE_URL, xml);
-      fail("No exception thrown on malformed XML.");
-    } catch (SpecParserException e) {
-      // OK
-      assertEquals(GadgetException.Code.MALFORMED_XML_DOCUMENT, e.getCode());
-      assertTrue(e.getMessage().contains(BUNDLE_URL.toString()));
-    }
+    MessageBundle bundle = new MessageBundle(BUNDLE_URL, xml);
+  }
+
+  @Test
+  public void extractFromElement() throws Exception {
+    Element element = XmlUtil.parse(XML);
+    MessageBundle bundle = new MessageBundle(element);
+    assertEquals(MESSAGES, bundle.getMessages());
+  }
+
+  @Test(expected = SpecParserException.class)
+  public void extractFromElementsWithNoName() throws Exception {
+    String xml = "<messagebundle><msg>foo</msg></messagebundle>";
+    Element element = XmlUtil.parse(xml);
+    MessageBundle bundle = new MessageBundle(element);
+  }
+
+  @Test
+  public void toStringIsSane() throws Exception {
+    MessageBundle b0 = new MessageBundle(BUNDLE_URL, XML);
+    MessageBundle b1 = new MessageBundle(BUNDLE_URL, b0.toString());
+    assertEquals(b0.getMessages(), b1.getMessages());
   }
 }


Reply via email to