You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@juneau.apache.org by ja...@apache.org on 2018/08/27 15:39:13 UTC

[juneau] branch master updated: Tests

This is an automated email from the ASF dual-hosted git repository.

jamesbognar pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/juneau.git


The following commit(s) were added to refs/heads/master by this push:
     new 4599ad2  Tests
4599ad2 is described below

commit 4599ad2fb2ac31c394c43215c69cf6bfbc76c7b9
Author: JamesBognar <ja...@apache.org>
AuthorDate: Mon Aug 27 11:39:01 2018 -0400

    Tests
---
 .../org/apache/juneau/rest/client/RestCall.java    |   4 +-
 .../rest/client/remote/BodyAnnotationTest.java     |   2 +-
 .../rest/client/remote/FormDataAnnotationTest.java | 167 +++++++++++++++++++++
 .../rest/client/remote/HeaderAnnotationTest.java   | 145 ++++++++++++++++++
 .../rest/client/remote/PathAnnotationTest.java     | 143 ++++++++++++++++++
 .../rest/client/remote/QueryAnnotationTest.java    | 165 ++++++++++++++++++++
 6 files changed, 623 insertions(+), 3 deletions(-)

diff --git a/juneau-rest/juneau-rest-client/src/main/java/org/apache/juneau/rest/client/RestCall.java b/juneau-rest/juneau-rest-client/src/main/java/org/apache/juneau/rest/client/RestCall.java
index bcdf51f..b08c1f0 100644
--- a/juneau-rest/juneau-rest-client/src/main/java/org/apache/juneau/rest/client/RestCall.java
+++ b/juneau-rest/juneau-rest-client/src/main/java/org/apache/juneau/rest/client/RestCall.java
@@ -237,7 +237,7 @@ public final class RestCall extends BeanSession implements Closeable {
 				query(p.getKey(), p.getValue(), skipIfEmpty, serializer, schema);
 		} else if (isBean(value)) {
 			return query(name, toBeanMap(value), skipIfEmpty, serializer, schema);
-		} else if (value instanceof Reader) {
+		} else if (value instanceof Reader || value instanceof InputStream) {
 			try {
 				uriBuilder.setCustomQuery(read(value));
 			} catch (IOException e) {
@@ -355,7 +355,7 @@ public final class RestCall extends BeanSession implements Closeable {
 				formData(p.getKey(), p.getValue(), skipIfEmpty, serializer, schema);
 		} else if (isBean(value)) {
 			return formData(name, toBeanMap(value), skipIfEmpty, serializer, schema);
-		} else if (value instanceof Reader) {
+		} else if (value instanceof Reader || value instanceof InputStream) {
 			contentType("application/x-www-form-urlencoded");
 			body(value);
 		} else if (value instanceof CharSequence) {
diff --git a/juneau-rest/juneau-rest-client/src/test/java/org/apache/juneau/rest/client/remote/BodyAnnotationTest.java b/juneau-rest/juneau-rest-client/src/test/java/org/apache/juneau/rest/client/remote/BodyAnnotationTest.java
index ff5dbe8..181c2aa 100644
--- a/juneau-rest/juneau-rest-client/src/test/java/org/apache/juneau/rest/client/remote/BodyAnnotationTest.java
+++ b/juneau-rest/juneau-rest-client/src/test/java/org/apache/juneau/rest/client/remote/BodyAnnotationTest.java
@@ -35,7 +35,7 @@ import org.junit.*;
 import org.junit.runners.*;
 
 /**
- * Tests the @RemoteResource annotation.
+ * Tests the @Body annotation.
  */
 @SuppressWarnings({"javadoc"})
 @FixMethodOrder(MethodSorters.NAME_ASCENDING)
diff --git a/juneau-rest/juneau-rest-client/src/test/java/org/apache/juneau/rest/client/remote/FormDataAnnotationTest.java b/juneau-rest/juneau-rest-client/src/test/java/org/apache/juneau/rest/client/remote/FormDataAnnotationTest.java
new file mode 100644
index 0000000..f98a1fc
--- /dev/null
+++ b/juneau-rest/juneau-rest-client/src/test/java/org/apache/juneau/rest/client/remote/FormDataAnnotationTest.java
@@ -0,0 +1,167 @@
+// ***************************************************************************************************************************
+// * 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.juneau.rest.client.remote;
+
+import static org.junit.Assert.*;
+
+import java.io.*;
+import java.util.*;
+
+import org.apache.juneau.*;
+import org.apache.juneau.http.annotation.*;
+import org.apache.juneau.http.annotation.Header;
+import org.apache.juneau.rest.annotation.*;
+import org.apache.juneau.rest.client.*;
+import org.apache.juneau.rest.mock.*;
+import org.apache.juneau.utils.*;
+import org.junit.*;
+import org.junit.runners.*;
+
+/**
+ * Tests the @FormData annotation.
+ */
+@SuppressWarnings({"javadoc","resource"})
+@FixMethodOrder(MethodSorters.NAME_ASCENDING)
+public class FormDataAnnotationTest {
+
+	public static class Bean {
+		public int f;
+
+		public static Bean create() {
+			Bean b = new Bean();
+			b.f = 1;
+			return b;
+		}
+	}
+
+	//=================================================================================================================
+	// Basic tests
+	//=================================================================================================================
+
+	@RestResource
+	public static class A {
+		@RestMethod
+		public String postA(@FormData("*") ObjectMap m, @Header("Content-Type") String ct) {
+			assertEquals(ct, "application/x-www-form-urlencoded");
+			return m.toString();
+		}
+	}
+	private static MockRest a = MockRest.create(A.class);
+
+	@RemoteResource
+	public static interface A01 {
+		@RemoteMethod(path="a") String postA01(@FormData("x") int b);
+		@RemoteMethod(path="a") String postA02(@FormData("x") float b);
+		@RemoteMethod(path="a") String postA03a(@FormData("x") Bean b);
+		@RemoteMethod(path="a") String postA03b(@FormData("*") Bean b);
+		@RemoteMethod(path="a") String postA03c(@FormData Bean b);
+		@RemoteMethod(path="a") String postA04a(@FormData("x") Bean[] b);
+		@RemoteMethod(path="a") String postA04b(@FormData(name="x",format="uon") Bean[] b);
+		@RemoteMethod(path="a") String postA05a(@FormData("x") List<Bean> b);
+		@RemoteMethod(path="a") String postA05b(@FormData(name="x",format="uon") List<Bean> b);
+		@RemoteMethod(path="a") String postA06a(@FormData("x") Map<String,Bean> b);
+		@RemoteMethod(path="a") String postA06b(@FormData("*") Map<String,Bean> b);
+		@RemoteMethod(path="a") String postA06c(@FormData Map<String,Bean> b);
+		@RemoteMethod(path="a") String postA06d(@FormData(name="x",format="uon") Map<String,Bean> b);
+		@RemoteMethod(path="a") String postA06e(@FormData(format="uon") Map<String,Bean> b);
+		@RemoteMethod(path="a") String postA07a(@FormData("*") Reader b);
+		@RemoteMethod(path="a") String postA07b(@FormData Reader b);
+		@RemoteMethod(path="a") String postA08a(@FormData("*") InputStream b);
+		@RemoteMethod(path="a") String postA08b(@FormData InputStream b);
+		@RemoteMethod(path="a") String postA09a(@FormData("*") NameValuePairs b);
+		@RemoteMethod(path="a") String postA09b(@FormData NameValuePairs b);
+	}
+
+	private static A01 a01 = RestClient.create().mockHttpConnection(a).build().getRemoteResource(A01.class);
+
+	@Test
+	public void a01_int() throws Exception {
+		assertEquals("{x:'1'}", a01.postA01(1));
+	}
+	@Test
+	public void a02_float() throws Exception {
+		assertEquals("{x:'1.0'}", a01.postA02(1));
+	}
+	@Test
+	public void a03a_Bean() throws Exception {
+		assertEquals("{x:'(f=1)'}", a01.postA03a(Bean.create()));
+	}
+	@Test
+	public void a03b_Bean() throws Exception {
+		assertEquals("{f:'1'}", a01.postA03b(Bean.create()));
+	}
+	@Test
+	public void a03c_Bean() throws Exception {
+		assertEquals("{f:'1'}", a01.postA03c(Bean.create()));
+	}
+	@Test
+	public void a04a_BeanArray() throws Exception {
+		assertEquals("{x:'(f=1),(f=1)'}", a01.postA04a(new Bean[]{Bean.create(),Bean.create()}));
+	}
+	@Test
+	public void a04b_BeanArray() throws Exception {
+		assertEquals("{x:'@((f=1),(f=1))'}", a01.postA04b(new Bean[]{Bean.create(),Bean.create()}));
+	}
+	@Test
+	public void a05a_ListOfBeans() throws Exception {
+		assertEquals("{x:'(f=1),(f=1)'}", a01.postA05a(AList.create(Bean.create(),Bean.create())));
+	}
+	@Test
+	public void a05b_ListOfBeans() throws Exception {
+		assertEquals("{x:'@((f=1),(f=1))'}", a01.postA05b(AList.create(Bean.create(),Bean.create())));
+	}
+	@Test
+	public void a06a_MapOfBeans() throws Exception {
+		assertEquals("{x:'(k1=(f=1))'}", a01.postA06a(AMap.create("k1",Bean.create())));
+	}
+	@Test
+	public void a06b_MapOfBeans() throws Exception {
+		assertEquals("{k1:'(f=1)'}", a01.postA06b(AMap.create("k1",Bean.create())));
+	}
+	@Test
+	public void a06c_MapOfBeans() throws Exception {
+		assertEquals("{k1:'(f=1)'}", a01.postA06c(AMap.create("k1",Bean.create())));
+	}
+	@Test
+	public void a06d_MapOfBeans() throws Exception {
+		assertEquals("{x:'(k1=(f=1))'}", a01.postA06d(AMap.create("k1",Bean.create())));
+	}
+	@Test
+	public void a06e_MapOfBeans() throws Exception {
+		assertEquals("{k1:'(f=1)'}", a01.postA06e(AMap.create("k1",Bean.create())));
+	}
+	@Test
+	public void a07a_Reader() throws Exception {
+		assertEquals("{x:'1'}", a01.postA07a(new StringReader("x=1")));
+	}
+	@Test
+	public void a07b_Reader() throws Exception {
+		assertEquals("{x:'1'}", a01.postA07b(new StringReader("x=1")));
+	}
+	@Test
+	public void a08a_InputStream() throws Exception {
+		assertEquals("{x:'1'}", a01.postA08a(new StringInputStream("x=1")));
+	}
+	@Test
+	public void a08b_InputStream() throws Exception {
+		assertEquals("{x:'1'}", a01.postA08b(new StringInputStream("x=1")));
+	}
+	@Test
+	public void a09a_NameValuePairs() throws Exception {
+		assertEquals("{foo:'bar'}", a01.postA09a(new NameValuePairs().append("foo", "bar")));
+	}
+	@Test
+	public void a09b_NameValuePairs() throws Exception {
+		assertEquals("{foo:'bar'}", a01.postA09b(new NameValuePairs().append("foo", "bar")));
+	}
+}
diff --git a/juneau-rest/juneau-rest-client/src/test/java/org/apache/juneau/rest/client/remote/HeaderAnnotationTest.java b/juneau-rest/juneau-rest-client/src/test/java/org/apache/juneau/rest/client/remote/HeaderAnnotationTest.java
new file mode 100644
index 0000000..046843d
--- /dev/null
+++ b/juneau-rest/juneau-rest-client/src/test/java/org/apache/juneau/rest/client/remote/HeaderAnnotationTest.java
@@ -0,0 +1,145 @@
+// ***************************************************************************************************************************
+// * 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.juneau.rest.client.remote;
+
+import static org.junit.Assert.*;
+
+import java.util.*;
+
+import org.apache.juneau.*;
+import org.apache.juneau.http.annotation.*;
+import org.apache.juneau.rest.annotation.*;
+import org.apache.juneau.rest.client.*;
+import org.apache.juneau.rest.mock.*;
+import org.apache.juneau.utils.*;
+import org.junit.*;
+import org.junit.runners.*;
+
+/**
+ * Tests the @Header annotation.
+ */
+@SuppressWarnings({"javadoc"})
+@FixMethodOrder(MethodSorters.NAME_ASCENDING)
+public class HeaderAnnotationTest {
+
+	public static class Bean {
+		public int f;
+
+		public static Bean create() {
+			Bean b = new Bean();
+			b.f = 1;
+			return b;
+		}
+	}
+
+	//=================================================================================================================
+	// Basic tests
+	//=================================================================================================================
+
+	@RestResource
+	public static class A {
+		@RestMethod
+		public String getA(@Header("*") ObjectMap m) {
+			m.removeAll("Accept-Encoding","Connection","Host","User-Agent");
+			return m.toString();
+		}
+	}
+	private static MockRest a = MockRest.create(A.class);
+
+	@RemoteResource
+	public static interface A01 {
+		@RemoteMethod(path="a") String getA01(@Header("x") int b);
+		@RemoteMethod(path="a") String getA02(@Header("x") float b);
+		@RemoteMethod(path="a") String getA03a(@Header("x") Bean b);
+		@RemoteMethod(path="a") String getA03b(@Header("*") Bean b);
+		@RemoteMethod(path="a") String getA03c(@Header Bean b);
+		@RemoteMethod(path="a") String getA04a(@Header("x") Bean[] b);
+		@RemoteMethod(path="a") String getA04b(@Header(name="x",format="uon") Bean[] b);
+		@RemoteMethod(path="a") String getA05a(@Header("x") List<Bean> b);
+		@RemoteMethod(path="a") String getA05b(@Header(name="x",format="uon") List<Bean> b);
+		@RemoteMethod(path="a") String getA06a(@Header("x") Map<String,Bean> b);
+		@RemoteMethod(path="a") String getA06b(@Header("*") Map<String,Bean> b);
+		@RemoteMethod(path="a") String getA06c(@Header Map<String,Bean> b);
+		@RemoteMethod(path="a") String getA06d(@Header(name="x",format="uon") Map<String,Bean> b);
+		@RemoteMethod(path="a") String getA06e(@Header(format="uon") Map<String,Bean> b);
+		@RemoteMethod(path="a") String getA09a(@Header("*") NameValuePairs b);
+		@RemoteMethod(path="a") String getA09b(@Header NameValuePairs b);
+	}
+
+	private static A01 a01 = RestClient.create().mockHttpConnection(a).build().getRemoteResource(A01.class);
+
+	@Test
+	public void a01_int() throws Exception {
+		assertEquals("{x:'1'}", a01.getA01(1));
+	}
+	@Test
+	public void a02_float() throws Exception {
+		assertEquals("{x:'1.0'}", a01.getA02(1));
+	}
+	@Test
+	public void a03a_Bean() throws Exception {
+		assertEquals("{x:'(f=1)'}", a01.getA03a(Bean.create()));
+	}
+	@Test
+	public void a03b_Bean() throws Exception {
+		assertEquals("{f:'1'}", a01.getA03b(Bean.create()));
+	}
+	@Test
+	public void a03c_Bean() throws Exception {
+		assertEquals("{f:'1'}", a01.getA03c(Bean.create()));
+	}
+	@Test
+	public void a04a_BeanArray() throws Exception {
+		assertEquals("{x:'(f=1),(f=1)'}", a01.getA04a(new Bean[]{Bean.create(),Bean.create()}));
+	}
+	@Test
+	public void a04b_BeanArray() throws Exception {
+		assertEquals("{x:'@((f=1),(f=1))'}", a01.getA04b(new Bean[]{Bean.create(),Bean.create()}));
+	}
+	@Test
+	public void a05a_ListOfBeans() throws Exception {
+		assertEquals("{x:'(f=1),(f=1)'}", a01.getA05a(AList.create(Bean.create(),Bean.create())));
+	}
+	@Test
+	public void a05b_ListOfBeans() throws Exception {
+		assertEquals("{x:'@((f=1),(f=1))'}", a01.getA05b(AList.create(Bean.create(),Bean.create())));
+	}
+	@Test
+	public void a06a_MapOfBeans() throws Exception {
+		assertEquals("{x:'(k1=(f=1))'}", a01.getA06a(AMap.create("k1",Bean.create())));
+	}
+	@Test
+	public void a06b_MapOfBeans() throws Exception {
+		assertEquals("{k1:'(f=1)'}", a01.getA06b(AMap.create("k1",Bean.create())));
+	}
+	@Test
+	public void a06c_MapOfBeans() throws Exception {
+		assertEquals("{k1:'(f=1)'}", a01.getA06c(AMap.create("k1",Bean.create())));
+	}
+	@Test
+	public void a06d_MapOfBeans() throws Exception {
+		assertEquals("{x:'(k1=(f=1))'}", a01.getA06d(AMap.create("k1",Bean.create())));
+	}
+	@Test
+	public void a06e_MapOfBeans() throws Exception {
+		assertEquals("{k1:'(f=1)'}", a01.getA06e(AMap.create("k1",Bean.create())));
+	}
+	@Test
+	public void a09a_NameValuePairs() throws Exception {
+		assertEquals("{foo:'bar'}", a01.getA09a(new NameValuePairs().append("foo", "bar")));
+	}
+	@Test
+	public void a09b_NameValuePairs() throws Exception {
+		assertEquals("{foo:'bar'}", a01.getA09b(new NameValuePairs().append("foo", "bar")));
+	}
+}
diff --git a/juneau-rest/juneau-rest-client/src/test/java/org/apache/juneau/rest/client/remote/PathAnnotationTest.java b/juneau-rest/juneau-rest-client/src/test/java/org/apache/juneau/rest/client/remote/PathAnnotationTest.java
new file mode 100644
index 0000000..91701ef
--- /dev/null
+++ b/juneau-rest/juneau-rest-client/src/test/java/org/apache/juneau/rest/client/remote/PathAnnotationTest.java
@@ -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.juneau.rest.client.remote;
+
+import static org.junit.Assert.*;
+
+import java.util.*;
+
+import org.apache.juneau.http.annotation.*;
+import org.apache.juneau.rest.annotation.*;
+import org.apache.juneau.rest.client.*;
+import org.apache.juneau.rest.mock.*;
+import org.apache.juneau.utils.*;
+import org.junit.*;
+import org.junit.runners.*;
+
+/**
+ * Tests the @Path annotation.
+ */
+@SuppressWarnings({"javadoc"})
+@FixMethodOrder(MethodSorters.NAME_ASCENDING)
+public class PathAnnotationTest {
+
+	public static class Bean {
+		public int x;
+
+		public static Bean create() {
+			Bean b = new Bean();
+			b.x = 1;
+			return b;
+		}
+	}
+
+	//=================================================================================================================
+	// Basic tests
+	//=================================================================================================================
+
+	@RestResource
+	public static class A {
+		@RestMethod(path="/a/{x}")
+		public String getA(@Path("x") Object x) {
+			return x.toString();
+		}
+	}
+	private static MockRest a = MockRest.create(A.class);
+
+	@RemoteResource
+	public static interface A01 {
+		@RemoteMethod(path="a/{x}") String getA01(@Path("x") int b);
+		@RemoteMethod(path="a/{x}") String getA02(@Path("x") float b);
+		@RemoteMethod(path="a/{x}") String getA03a(@Path("x") Bean b);
+		@RemoteMethod(path="a/{x}") String getA03b(@Path("*") Bean b);
+		@RemoteMethod(path="a/{x}") String getA03c(@Path Bean b);
+		@RemoteMethod(path="a/{x}") String getA04a(@Path("x") Bean[] b);
+		@RemoteMethod(path="a/{x}") String getA04b(@Path(name="x",format="uon") Bean[] b);
+		@RemoteMethod(path="a/{x}") String getA05a(@Path("x") List<Bean> b);
+		@RemoteMethod(path="a/{x}") String getA05b(@Path(name="x",format="uon") List<Bean> b);
+		@RemoteMethod(path="a/{x}") String getA06a(@Path("x") Map<String,Bean> b);
+		@RemoteMethod(path="a/{x}") String getA06b(@Path("*") Map<String,Bean> b);
+		@RemoteMethod(path="a/{x}") String getA06c(@Path Map<String,Bean> b);
+		@RemoteMethod(path="a/{x}") String getA06d(@Path(name="x",format="uon") Map<String,Bean> b);
+		@RemoteMethod(path="a/{x}") String getA06e(@Path(format="uon") Map<String,Bean> b);
+		@RemoteMethod(path="a/{x}") String getA09a(@Path("*") NameValuePairs b);
+		@RemoteMethod(path="a/{x}") String getA09b(@Path NameValuePairs b);
+	}
+
+	private static A01 a01 = RestClient.create().mockHttpConnection(a).build().getRemoteResource(A01.class);
+
+	@Test
+	public void a01_int() throws Exception {
+		assertEquals("1", a01.getA01(1));
+	}
+	@Test
+	public void a02_float() throws Exception {
+		assertEquals("1.0", a01.getA02(1));
+	}
+	@Test
+	public void a03a_Bean() throws Exception {
+		assertEquals("(x=1)", a01.getA03a(Bean.create()));
+	}
+	@Test
+	public void a03b_Bean() throws Exception {
+		assertEquals("1", a01.getA03b(Bean.create()));
+	}
+	@Test
+	public void a03c_Bean() throws Exception {
+		assertEquals("1", a01.getA03c(Bean.create()));
+	}
+	@Test
+	public void a04a_BeanArray() throws Exception {
+		assertEquals("(x=1),(x=1)", a01.getA04a(new Bean[]{Bean.create(),Bean.create()}));
+	}
+	@Test
+	public void a04b_BeanArray() throws Exception {
+		assertEquals("@((x=1),(x=1))", a01.getA04b(new Bean[]{Bean.create(),Bean.create()}));
+	}
+	@Test
+	public void a05a_ListOfBeans() throws Exception {
+		assertEquals("(x=1),(x=1)", a01.getA05a(AList.create(Bean.create(),Bean.create())));
+	}
+	@Test
+	public void a05b_ListOfBeans() throws Exception {
+		assertEquals("@((x=1),(x=1))", a01.getA05b(AList.create(Bean.create(),Bean.create())));
+	}
+	@Test
+	public void a06a_MapOfBeans() throws Exception {
+		assertEquals("(x=(x=1))", a01.getA06a(AMap.create("x",Bean.create())));
+	}
+	@Test
+	public void a06b_MapOfBeans() throws Exception {
+		assertEquals("(x=1)", a01.getA06b(AMap.create("x",Bean.create())));
+	}
+	@Test
+	public void a06c_MapOfBeans() throws Exception {
+		assertEquals("(x=1)", a01.getA06c(AMap.create("x",Bean.create())));
+	}
+	@Test
+	public void a06d_MapOfBeans() throws Exception {
+		assertEquals("(x=(x=1))", a01.getA06d(AMap.create("x",Bean.create())));
+	}
+	@Test
+	public void a06e_MapOfBeans() throws Exception {
+		assertEquals("(x=1)", a01.getA06e(AMap.create("x",Bean.create())));
+	}
+	@Test
+	public void a09a_NameValuePairs() throws Exception {
+		assertEquals("bar", a01.getA09a(new NameValuePairs().append("x", "bar")));
+	}
+	@Test
+	public void a09b_NameValuePairs() throws Exception {
+		assertEquals("bar", a01.getA09b(new NameValuePairs().append("x", "bar")));
+	}
+}
diff --git a/juneau-rest/juneau-rest-client/src/test/java/org/apache/juneau/rest/client/remote/QueryAnnotationTest.java b/juneau-rest/juneau-rest-client/src/test/java/org/apache/juneau/rest/client/remote/QueryAnnotationTest.java
new file mode 100644
index 0000000..46ed0ee
--- /dev/null
+++ b/juneau-rest/juneau-rest-client/src/test/java/org/apache/juneau/rest/client/remote/QueryAnnotationTest.java
@@ -0,0 +1,165 @@
+// ***************************************************************************************************************************
+// * 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.juneau.rest.client.remote;
+
+import static org.junit.Assert.*;
+
+import java.io.*;
+import java.util.*;
+
+import org.apache.juneau.*;
+import org.apache.juneau.http.annotation.*;
+import org.apache.juneau.rest.annotation.*;
+import org.apache.juneau.rest.client.*;
+import org.apache.juneau.rest.mock.*;
+import org.apache.juneau.utils.*;
+import org.junit.*;
+import org.junit.runners.*;
+
+/**
+ * Tests the @Query annotation.
+ */
+@SuppressWarnings({"javadoc","resource"})
+@FixMethodOrder(MethodSorters.NAME_ASCENDING)
+public class QueryAnnotationTest {
+
+	public static class Bean {
+		public int f;
+
+		public static Bean create() {
+			Bean b = new Bean();
+			b.f = 1;
+			return b;
+		}
+	}
+
+	//=================================================================================================================
+	// Basic tests
+	//=================================================================================================================
+
+	@RestResource
+	public static class A {
+		@RestMethod
+		public String getA(@Query("*") ObjectMap m) {
+			return m.toString();
+		}
+	}
+	private static MockRest a = MockRest.create(A.class);
+
+	@RemoteResource
+	public static interface A01 {
+		@RemoteMethod(path="a") String getA01(@Query("x") int b);
+		@RemoteMethod(path="a") String getA02(@Query("x") float b);
+		@RemoteMethod(path="a") String getA03a(@Query("x") Bean b);
+		@RemoteMethod(path="a") String getA03b(@Query("*") Bean b);
+		@RemoteMethod(path="a") String getA03c(@Query Bean b);
+		@RemoteMethod(path="a") String getA04a(@Query("x") Bean[] b);
+		@RemoteMethod(path="a") String getA04b(@Query(name="x",format="uon") Bean[] b);
+		@RemoteMethod(path="a") String getA05a(@Query("x") List<Bean> b);
+		@RemoteMethod(path="a") String getA05b(@Query(name="x",format="uon") List<Bean> b);
+		@RemoteMethod(path="a") String getA06a(@Query("x") Map<String,Bean> b);
+		@RemoteMethod(path="a") String getA06b(@Query("*") Map<String,Bean> b);
+		@RemoteMethod(path="a") String getA06c(@Query Map<String,Bean> b);
+		@RemoteMethod(path="a") String getA06d(@Query(name="x",format="uon") Map<String,Bean> b);
+		@RemoteMethod(path="a") String getA06e(@Query(format="uon") Map<String,Bean> b);
+		@RemoteMethod(path="a") String getA07a(@Query("*") Reader b);
+		@RemoteMethod(path="a") String getA07b(@Query Reader b);
+		@RemoteMethod(path="a") String getA08a(@Query("*") InputStream b);
+		@RemoteMethod(path="a") String getA08b(@Query InputStream b);
+		@RemoteMethod(path="a") String getA09a(@Query("*") NameValuePairs b);
+		@RemoteMethod(path="a") String getA09b(@Query NameValuePairs b);
+	}
+
+	private static A01 a01 = RestClient.create().mockHttpConnection(a).build().getRemoteResource(A01.class);
+
+	@Test
+	public void a01_int() throws Exception {
+		assertEquals("{x:'1'}", a01.getA01(1));
+	}
+	@Test
+	public void a02_float() throws Exception {
+		assertEquals("{x:'1.0'}", a01.getA02(1));
+	}
+	@Test
+	public void a03a_Bean() throws Exception {
+		assertEquals("{x:'(f=1)'}", a01.getA03a(Bean.create()));
+	}
+	@Test
+	public void a03b_Bean() throws Exception {
+		assertEquals("{f:'1'}", a01.getA03b(Bean.create()));
+	}
+	@Test
+	public void a03c_Bean() throws Exception {
+		assertEquals("{f:'1'}", a01.getA03c(Bean.create()));
+	}
+	@Test
+	public void a04a_BeanArray() throws Exception {
+		assertEquals("{x:'(f=1),(f=1)'}", a01.getA04a(new Bean[]{Bean.create(),Bean.create()}));
+	}
+	@Test
+	public void a04b_BeanArray() throws Exception {
+		assertEquals("{x:'@((f=1),(f=1))'}", a01.getA04b(new Bean[]{Bean.create(),Bean.create()}));
+	}
+	@Test
+	public void a05a_ListOfBeans() throws Exception {
+		assertEquals("{x:'(f=1),(f=1)'}", a01.getA05a(AList.create(Bean.create(),Bean.create())));
+	}
+	@Test
+	public void a05b_ListOfBeans() throws Exception {
+		assertEquals("{x:'@((f=1),(f=1))'}", a01.getA05b(AList.create(Bean.create(),Bean.create())));
+	}
+	@Test
+	public void a06a_MapOfBeans() throws Exception {
+		assertEquals("{x:'(k1=(f=1))'}", a01.getA06a(AMap.create("k1",Bean.create())));
+	}
+	@Test
+	public void a06b_MapOfBeans() throws Exception {
+		assertEquals("{k1:'(f=1)'}", a01.getA06b(AMap.create("k1",Bean.create())));
+	}
+	@Test
+	public void a06c_MapOfBeans() throws Exception {
+		assertEquals("{k1:'(f=1)'}", a01.getA06c(AMap.create("k1",Bean.create())));
+	}
+	@Test
+	public void a06d_MapOfBeans() throws Exception {
+		assertEquals("{x:'(k1=(f=1))'}", a01.getA06d(AMap.create("k1",Bean.create())));
+	}
+	@Test
+	public void a06e_MapOfBeans() throws Exception {
+		assertEquals("{k1:'(f=1)'}", a01.getA06e(AMap.create("k1",Bean.create())));
+	}
+	@Test
+	public void a07a_Reader() throws Exception {
+		assertEquals("{x:'1'}", a01.getA07a(new StringReader("x=1")));
+	}
+	@Test
+	public void a07b_Reader() throws Exception {
+		assertEquals("{x:'1'}", a01.getA07b(new StringReader("x=1")));
+	}
+	@Test
+	public void a08a_InputStream() throws Exception {
+		assertEquals("{x:'1'}", a01.getA08a(new StringInputStream("x=1")));
+	}
+	@Test
+	public void a08b_InputStream() throws Exception {
+		assertEquals("{x:'1'}", a01.getA08b(new StringInputStream("x=1")));
+	}
+	@Test
+	public void a09a_NameValuePairs() throws Exception {
+		assertEquals("{foo:'bar'}", a01.getA09a(new NameValuePairs().append("foo", "bar")));
+	}
+	@Test
+	public void a09b_NameValuePairs() throws Exception {
+		assertEquals("{foo:'bar'}", a01.getA09b(new NameValuePairs().append("foo", "bar")));
+	}
+}