Adds non-trivial tests to the default app created by webAppCreator, including one that uses delayTestFinish and sends an RPC. Also shows an example of shared client/server code.
Patch by: jlabanca
Review by: jgw
git-svn-id: https://google-web-toolkit.googlecode.com/svn/trunk@7362 8db76d5a-ed1c-0410-87a9-c151d255dfc7
diff --git a/user/src/com/google/gwt/user/tools/AppClassTemplate.javasrc b/user/src/com/google/gwt/user/tools/AppClassTemplate.javasrc
index 433a4d0..45429c3 100644
--- a/user/src/com/google/gwt/user/tools/AppClassTemplate.javasrc
+++ b/user/src/com/google/gwt/user/tools/AppClassTemplate.javasrc
@@ -1,5 +1,6 @@
package @clientPackage;
+import @sharedPackage.FieldVerifier;
import com.google.gwt.core.client.EntryPoint;
import com.google.gwt.core.client.GWT;
import com.google.gwt.event.dom.client.ClickEvent;
@@ -40,6 +41,7 @@
final Button sendButton = new Button("Send");
final TextBox nameField = new TextBox();
nameField.setText("GWT User");
+ final Label errorLabel = new Label();
// We can add style names to widgets
sendButton.addStyleName("sendButton");
@@ -48,6 +50,7 @@
// Use RootPanel.get() to get the entire body element
RootPanel.get("nameFieldContainer").add(nameField);
RootPanel.get("sendButtonContainer").add(sendButton);
+ RootPanel.get("errorLabelContainer").add(errorLabel);
// Focus the cursor on the name field when the app loads
nameField.setFocus(true);
@@ -103,8 +106,16 @@
* Send the name from the nameField to the server and wait for a response.
*/
private void sendNameToServer() {
- sendButton.setEnabled(false);
+ // First, we validate the input.
+ errorLabel.setText("");
String textToServer = nameField.getText();
+ if (!FieldVerifier.isValidName(textToServer)) {
+ errorLabel.setText("Please enter at least four characters");
+ return;
+ }
+
+ // Then, we send the input to the server.
+ sendButton.setEnabled(false);
textToServerLabel.setText(textToServer);
serverResponseLabel.setText("");
greetingService.greetServer(textToServer, new AsyncCallback<String>() {
diff --git a/user/src/com/google/gwt/user/tools/AppHtml.htmlsrc b/user/src/com/google/gwt/user/tools/AppHtml.htmlsrc
index e85d026..75007e9 100644
--- a/user/src/com/google/gwt/user/tools/AppHtml.htmlsrc
+++ b/user/src/com/google/gwt/user/tools/AppHtml.htmlsrc
@@ -56,6 +56,9 @@
<td id="nameFieldContainer"></td>
<td id="sendButtonContainer"></td>
</tr>
+ <tr>
+ <td colspan="2" style="color:red;" id="errorLabelContainer"></td>
+ </tr>
</table>
</body>
</html>
diff --git a/user/src/com/google/gwt/user/tools/JUnit.gwt.xmlsrc b/user/src/com/google/gwt/user/tools/JUnit.gwt.xmlsrc
new file mode 100644
index 0000000..5d70944
--- /dev/null
+++ b/user/src/com/google/gwt/user/tools/JUnit.gwt.xmlsrc
@@ -0,0 +1,9 @@
+<?xml version="1.0" encoding="UTF-8"?>@gwtModuleDtd
+<module>
+ <!-- Inherit our applications main module. -->
+ <inherits name='@moduleName'/>
+
+ <!-- Specify the path to any remote services. -->
+ <servlet path="/@renameTo/greet" class="@serverPackage.GreetingServiceImpl" />
+
+</module>
diff --git a/user/src/com/google/gwt/user/tools/JUnitClassTemplate.javasrc b/user/src/com/google/gwt/user/tools/JUnitClassTemplate.javasrc
index 25a6a58..b63904b 100644
--- a/user/src/com/google/gwt/user/tools/JUnitClassTemplate.javasrc
+++ b/user/src/com/google/gwt/user/tools/JUnitClassTemplate.javasrc
@@ -1,6 +1,10 @@
package @clientPackage;
+import @sharedPackage.FieldVerifier;
+import com.google.gwt.core.client.GWT;
import com.google.gwt.junit.client.GWTTestCase;
+import com.google.gwt.user.client.rpc.AsyncCallback;
+import com.google.gwt.user.client.rpc.ServiceDefTarget;
/**
* GWT JUnit tests must extend GWTTestCase.
@@ -11,14 +15,54 @@
* Must refer to a valid module that sources this class.
*/
public String getModuleName() {
- return "@moduleName";
+ return "@moduleNameJUnit";
}
/**
- * Add as many tests as you like.
+ * Tests the FieldVerifier.
*/
- public void testSimple() {
- assertTrue(true);
+ public void testFieldVerifier() {
+ assertFalse(FieldVerifier.isValidName(null));
+ assertFalse(FieldVerifier.isValidName(""));
+ assertFalse(FieldVerifier.isValidName("a"));
+ assertFalse(FieldVerifier.isValidName("ab"));
+ assertFalse(FieldVerifier.isValidName("abc"));
+ assertTrue(FieldVerifier.isValidName("abcd"));
}
+ /**
+ * This test will send a request to the server using the greetServer method in
+ * GreetingService and verify the response.
+ */
+ public void testGreetingService() {
+ // Create the service that we will test.
+ GreetingServiceAsync greetingService = GWT.create(GreetingService.class);
+ ServiceDefTarget target = (ServiceDefTarget) greetingService;
+ target.setServiceEntryPoint(GWT.getModuleBaseURL() + "/@renameTo/greet");
+
+ // Since RPC calls are asynchronous, we will need to wait for a response
+ // after this test method returns. This line tells the test runner to wait
+ // up to 10 seconds before timing out.
+ delayTestFinish(10000);
+
+ // Send a request to the server.
+ greetingService.greetServer("GWT User", new AsyncCallback<String>() {
+ public void onFailure(Throwable caught) {
+ // The request resulted in an unexpected error.
+ fail("Request failure: " + caught.getMessage());
+ }
+
+ public void onSuccess(String result) {
+ // Verify that the response is correct.
+ assertTrue(result.startsWith("Hello, GWT User!"));
+
+ // Now that we have received a response, we need to tell the test runner
+ // that the test is complete. You must call finishTest() after an
+ // asynchronous test finishes successfully, or the test will time out.
+ finishTest();
+ }
+ });
+ }
+
+
}
diff --git a/user/src/com/google/gwt/user/tools/Module.gwt.xmlsrc b/user/src/com/google/gwt/user/tools/Module.gwt.xmlsrc
index 8be3e85..2f0267e 100644
--- a/user/src/com/google/gwt/user/tools/Module.gwt.xmlsrc
+++ b/user/src/com/google/gwt/user/tools/Module.gwt.xmlsrc
@@ -17,5 +17,6 @@
<!-- Specify the paths for translatable code -->
<source path='client'/>
+ <source path='shared'/>
</module>
diff --git a/user/src/com/google/gwt/user/tools/RpcAsyncClientTemplate.javasrc b/user/src/com/google/gwt/user/tools/RpcAsyncClientTemplate.javasrc
index e91fb2e..fe1abcc 100644
--- a/user/src/com/google/gwt/user/tools/RpcAsyncClientTemplate.javasrc
+++ b/user/src/com/google/gwt/user/tools/RpcAsyncClientTemplate.javasrc
@@ -6,5 +6,6 @@
* The async counterpart of <code>GreetingService</code>.
*/
public interface GreetingServiceAsync {
- void greetServer(String input, AsyncCallback<String> callback);
+ void greetServer(String input, AsyncCallback<String> callback)
+ throws IllegalArgumentException;
}
diff --git a/user/src/com/google/gwt/user/tools/RpcClientTemplate.javasrc b/user/src/com/google/gwt/user/tools/RpcClientTemplate.javasrc
index 40fcca7..3a68c93 100644
--- a/user/src/com/google/gwt/user/tools/RpcClientTemplate.javasrc
+++ b/user/src/com/google/gwt/user/tools/RpcClientTemplate.javasrc
@@ -8,5 +8,5 @@
*/
@RemoteServiceRelativePath("greet")
public interface GreetingService extends RemoteService {
- String greetServer(String name);
+ String greetServer(String name) throws IllegalArgumentException;
}
diff --git a/user/src/com/google/gwt/user/tools/RpcServerTemplate.javasrc b/user/src/com/google/gwt/user/tools/RpcServerTemplate.javasrc
index 4278c86..8d00ff5 100644
--- a/user/src/com/google/gwt/user/tools/RpcServerTemplate.javasrc
+++ b/user/src/com/google/gwt/user/tools/RpcServerTemplate.javasrc
@@ -1,6 +1,7 @@
package @serverPackage;
import @clientPackage.GreetingService;
+import @sharedPackage.FieldVerifier;
import com.google.gwt.user.server.rpc.RemoteServiceServlet;
/**
@@ -10,7 +11,15 @@
public class GreetingServiceImpl extends RemoteServiceServlet implements
GreetingService {
- public String greetServer(String input) {
+ public String greetServer(String input) throws IllegalArgumentException {
+ // Verify that the input is valid.
+ if (!FieldVerifier.isValidName(input)) {
+ // If the input is not valid, throw an IllegalArgumentException back to
+ // the client.
+ throw new IllegalArgumentException(
+ "Name must be at least 4 characters long");
+ }
+
String serverInfo = getServletContext().getServerInfo();
String userAgent = getThreadLocalRequest().getHeader("User-Agent");
return "Hello, " + input + "!<br><br>I am running " + serverInfo
diff --git a/user/src/com/google/gwt/user/tools/SharedClassTemplate.javasrc b/user/src/com/google/gwt/user/tools/SharedClassTemplate.javasrc
new file mode 100644
index 0000000..9a3bb0e
--- /dev/null
+++ b/user/src/com/google/gwt/user/tools/SharedClassTemplate.javasrc
@@ -0,0 +1,42 @@
+package @sharedPackage;
+
+/**
+ * <p>
+ * FieldVerifier validates that the name the user enters is valid.
+ * </p>
+ * <p>
+ * This class is in the <code>shared</code> packing because we use it in both
+ * the client code and on the server. On the client, we verify that the name is
+ * valid before sending an RPC request so the user doesn't have to wait for a
+ * network round trip to get feedback. On the server, we verify that the name is
+ * correct to ensure that the input is correct regardless of where the RPC
+ * originates.
+ * </p>
+ * <p>
+ * When creating a class that is used on both the client and the server, be sure
+ * that all code is translatable and does not use native JavaScript. Code that
+ * is note translatable (such as code that interacts with a database or the file
+ * system) cannot be compiled into client side JavaScript. Code that uses native
+ * JavaScript (such as Widgets) cannot be run on the server.
+ * </p>
+ */
+public class FieldVerifier {
+
+ /**
+ * Verifies that the specified name is valid for our service.
+ *
+ * In this example, we only require that the name is at least four
+ * characters. In your application, you can use more complex checks to ensure
+ * that usernames, passwords, email addresses, URLs, and other fields have the
+ * proper syntax.
+ *
+ * @param name the name to validate
+ * @return true if valid, false if invalid
+ */
+ public static boolean isValidName(String name) {
+ if (name == null) {
+ return false;
+ }
+ return name.length() > 3;
+ }
+}
diff --git a/user/src/com/google/gwt/user/tools/WebAppCreator.java b/user/src/com/google/gwt/user/tools/WebAppCreator.java
index ab20988..667de6d 100644
--- a/user/src/com/google/gwt/user/tools/WebAppCreator.java
+++ b/user/src/com/google/gwt/user/tools/WebAppCreator.java
@@ -290,8 +290,10 @@
'.', '/'), true);
File clientDir = Utility.getDirectory(moduleDir, "client", true);
File serverDir = Utility.getDirectory(moduleDir, "server", true);
- File clientTestDir = Utility.getDirectory(outDir, "test/"
- + modulePackageName.replace('.', '/') + "/client", true);
+ File sharedDir = Utility.getDirectory(moduleDir, "shared", true);
+ File moduleTestDir = Utility.getDirectory(outDir, "test/"
+ + modulePackageName.replace('.', '/'), true);
+ File clientTestDir = Utility.getDirectory(moduleTestDir, "client", true);
// Create a map of replacements
Map<String, String> replacements = new HashMap<String, String>();
@@ -299,6 +301,7 @@
replacements.put("@moduleName", moduleName);
replacements.put("@clientPackage", modulePackageName + ".client");
replacements.put("@serverPackage", modulePackageName + ".server");
+ replacements.put("@sharedPackage", modulePackageName + ".shared");
replacements.put("@gwtSdk", installPath);
replacements.put("@gwtUserPath", gwtUserPath);
replacements.put("@gwtDevPath", gwtDevPath);
@@ -361,16 +364,20 @@
files.add(new FileCreator(webInfDir, "web.xml", "web.xml"));
files.add(new FileCreator(clientDir, moduleShortName + ".java",
"AppClassTemplate.java"));
- files.add(new FileCreator(clientDir, "GreetingService" + ".java",
+ files.add(new FileCreator(clientDir, "GreetingService.java",
"RpcClientTemplate.java"));
- files.add(new FileCreator(clientDir, "GreetingServiceAsync" + ".java",
+ files.add(new FileCreator(clientDir, "GreetingServiceAsync.java",
"RpcAsyncClientTemplate.java"));
- files.add(new FileCreator(serverDir, "GreetingServiceImpl" + ".java",
+ files.add(new FileCreator(serverDir, "GreetingServiceImpl.java",
"RpcServerTemplate.java"));
+ files.add(new FileCreator(sharedDir, "FieldVerifier.java",
+ "SharedClassTemplate.java"));
files.add(new FileCreator(outDir, "build.xml", "project.ant.xml"));
files.add(new FileCreator(outDir, "README.txt", "README.txt"));
if (junitPath != null) {
// create the test file.
+ files.add(new FileCreator(moduleTestDir, moduleShortName
+ + "JUnit.gwt.xml", "JUnit.gwt.xml"));
files.add(new FileCreator(clientTestDir, moduleShortName + "Test"
+ ".java", "JUnitClassTemplate.java"));
}