1   /*
2    * Copyright 2005 The Apache Software Foundation
3    *
4    * Licensed under the Apache License, Version 2.0 (the "License");
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of the License at
7    *
8    *     http://www.apache.org/licenses/LICENSE-2.0
9    *
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS,
12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   * See the License for the specific language governing permissions and
14   * limitations under the License.
15   *
16   */
17  
18  package org.apache.commons.i18n;
19  
20  import junit.framework.TestCase;
21  
22  import java.util.Locale;
23  import java.util.Map;
24  
25  /**
26   * This class tests that the behaviour of a <code>MessageProvider</code> implementation is correct.
27   * If creating new implementations, consider subclassing this class to test the behaviour of that implementation.
28   * The tests assume the provided <code>MessageProvider</code>
29   * contains the following entries:
30   * <p />
31   * <table>
32   *   <tr>
33   *     <th>Language/<code>Locale</code></th>
34   *     <th>ID</th>
35   *     <th>Entry</th>
36   *     <th>Message</th>
37   *   </tr>
38   *   <tr>
39   *     <td>English (en)</td>
40   *     <td>helloWorld</td>
41   *     <td>title</td>
42   *     <td>Hello World</td>
43   *   <tr>
44   *   <tr>
45   *     <td>English (en)</td>
46   *     <td>helloWorld</td>
47   *     <td>text</td>
48   *     <td>Hello World, we are in {0}.</td>
49   *   <tr>
50   *   <tr>
51   *     <td>German (de)</td>
52   *     <td>helloWorld</td>
53   *     <td>title</td>
54   *     <td>Hallo Welt</td>
55   *   <tr>
56   *   <tr>
57   *     <td>German (de)</td>
58   *     <td>helloWorld</td>
59   *     <td>text</td>
60   *     <td>Hallo Welt, wir sind in {0}.</td>
61   *   <tr>
62   *   <tr>
63   *     <td colspan="4"><i>The entry below is used only if possible. If not possible, set
64   *     <code>hasNonTranslatedEntry</code> to false.</i></td>
65   *   <tr>
66   *   <tr>
67   *     <td>English (en)</td>
68   *     <td>helloWorld</td>
69   *     <td>helloWorld</td>
70   *     <td>This entry is not translated to any other languages</td>
71   *   <tr>
72   * </table>
73   * <p />
74   * Specifically, the ID <code>nonExistentId</code> and the entry <code>nonExistentEntry</code> of ID
75   * <code>helloWorld</code> must NOT be existent.
76   */
77  public abstract class MessageProviderTestBase extends TestCase {
78  
79      protected MessageProviderTestBase() {
80      }
81  
82      protected MessageProviderTestBase(String testName) {
83          super(testName);
84      }
85  
86      /**
87       * Set English as default Locale.
88       * If overridden, please remember to call <code>super.setUp()</code>
89       * @throws Exception No exception is thrown, but allow for overriding methods
90       * to throw exceptions.
91       */
92      public void setUp() throws Exception {
93          /* Make sure en_US is the default Locale for tests */
94          Locale.setDefault(Locale.ENGLISH);
95      }
96  
97      public void tearDown() throws Exception {
98          /* Uninstall resource bundles after every test */
99          MessageManager.clearMessageProviders();
100     }
101 
102     /**
103      * Test functionality of getText() method, which should be common for all implementations of the
104      * <code>MessageProvider</code> interface.
105      * @param messageProvider
106      */
107     protected void testGetText(MessageProvider messageProvider) {
108         // Explicit default locale
109         assertEnglishTexts(messageProvider, Locale.ENGLISH);
110 
111         // Default locale with country
112         assertEnglishTexts(messageProvider, Locale.US);
113 
114         // Default locale with variant
115         assertEnglishTexts(messageProvider, new Locale("en", "", "scottish"));
116 
117         // Default locale with country and variant
118         assertEnglishTexts(messageProvider, new Locale("en", "GB", "scottish"));
119 
120         // Non-default locale
121         assertGermanTexts(messageProvider, Locale.GERMAN);
122 
123         // Non-default locale with country
124         assertGermanTexts(messageProvider, Locale.GERMANY);
125 
126         // Non-default locale with variant
127         assertGermanTexts(messageProvider, new Locale("de", "", "foo"));
128 
129         // Non-default locale with country and variant
130         assertGermanTexts(messageProvider, new Locale("de", "CH", "foo"));
131 
132         // Fallback to default
133         assertEnglishTexts(messageProvider, Locale.JAPANESE);
134 
135         // Non-existent entry
136         // try {
137         assertNull(messageProvider.getText("helloWorld", "nonExistentEntry", Locale.ENGLISH));
138         // }
139         // catch(MessageNotFoundException mnfex) {
140         //     assertEquals("Message bundle with key helloWorld does not contain an entry with key nonExistentEntry", mnfex.getMessage());
141         // }
142 
143         // Non-existent id
144         try {
145             assertNull(messageProvider.getText("nonExistentId", "foo", Locale.ENGLISH));
146         }
147         catch(MessageNotFoundException mnfex) {
148             assertEquals("No message entries found for bundle with key nonExistentId", mnfex.getMessage()); // TODO: JDBC
149         }
150     }
151 
152     private void assertEnglishTexts(MessageProvider messageProvider, Locale locale) {
153         assertEquals("Locale = " + locale + ", title",
154                 "Hello World", messageProvider.getText("helloWorld", "title", locale));
155         assertEquals("Locale = " + locale + ", text",
156                 "Hello World, we are in {0}.", messageProvider.getText("helloWorld", "text", locale));
157     }
158 
159     private void assertGermanTexts(MessageProvider messageProvider, Locale locale) {
160         assertEquals("Locale = " + locale + ", title",
161                 "Hallo Welt", messageProvider.getText("helloWorld", "title", locale));
162         assertEquals("Locale = " + locale + ", text",
163                 "Hallo Welt, wir sind in {0}.", messageProvider.getText("helloWorld", "text", locale));
164     }
165 
166     // TODO: Document
167     protected void testGetEntries(MessageProvider messageProvider, boolean hasNonTranslatedEntry) {
168         // TODO: Complete from above
169 
170         // Explicit default locale
171         assertEnglishEntries(messageProvider, Locale.ENGLISH, hasNonTranslatedEntry);
172 
173         // Default locale with country
174         assertEnglishEntries(messageProvider, Locale.US, hasNonTranslatedEntry);
175 
176         // Default locale with country and variant
177         assertEnglishEntries(messageProvider, new Locale("en", "", "scottish"), hasNonTranslatedEntry);
178 
179         assertGermanEntries(messageProvider, Locale.GERMAN);
180 
181         // Default locale with country
182         assertGermanEntries(messageProvider, Locale.GERMANY);
183 
184         // Test use of defaule
185         assertEnglishEntries(messageProvider, Locale.JAPANESE, hasNonTranslatedEntry);
186 
187         // Non-existent id
188         try {
189             messageProvider.getEntries("nonExistentId", Locale.ENGLISH);
190             fail("Non-existent ID should cause exception");
191         }
192         catch(MessageNotFoundException mnfex) {
193             assertEquals("No message entries found for bundle with key nonExistentId", mnfex.getMessage());
194         }
195     }
196 
197     private static void assertEnglishEntries(MessageProvider messageProvider, Locale locale, boolean hasNonTranslatedEntry) {
198         Map entries = messageProvider.getEntries("helloWorld", locale);
199         if(hasNonTranslatedEntry) {
200             assertEquals("Locale = " + locale + ", No of entries", 3, entries.size());
201             assertEquals("Locale = " + locale, "This entry is not translated to any other languages",
202                     entries.get("notTranslated"));
203         }
204         else
205             assertEquals("Locale = " + locale + ", No of entries", 2, entries.size());
206         assertEquals("Locale = " + locale, "Hello World", (String)entries.get("title"));
207         assertEquals("Locale = " + locale, "Hello World, we are in {0}.", entries.get("text"));
208     }
209 
210     private static void assertGermanEntries(MessageProvider messageProvider, Locale locale) {
211         Map entries = messageProvider.getEntries("helloWorld", locale);
212 
213         // TODO: Consider whether all MessageProviders must behave the same way
214         if(entries.size() == 3) // If non-translated entries included
215             assertEquals("This entry is not translated to any other languages", entries.get("notTranslated"));
216         else if(entries.size() != 2)
217             fail("No of entries should be 2 or 3!");
218 
219         assertEquals("Hallo Welt", (String)entries.get("title"));
220         assertEquals("Hallo Welt, wir sind in {0}.", entries.get("text"));
221     }
222 }