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 d604d6a Tests d604d6a is described below commit d604d6a40104b3471ae04e8193e1069193d920f0 Author: JamesBognar <jamesbog...@apache.org> AuthorDate: Mon Aug 27 20:09:03 2018 -0400 Tests --- .../juneau/httppart/OpenApiPartSerializerTest.java | 6 +- .../apache/juneau/http/annotation/FormData.java | 1 + .../org/apache/juneau/http/annotation/Header.java | 2 - .../org/apache/juneau/http/annotation/Path.java | 2 - .../org/apache/juneau/http/annotation/Query.java | 1 + .../java/org/apache/juneau/httppart/Constants.java | 151 +++++++++++++++++++++ .../java/org/apache/juneau/marshall/OpenApi.java | 71 ++++++++++ .../juneau/oapi/OpenApiSerializerSession.java | 2 +- .../java/org/apache/juneau/oapi/package-info.java | 18 +++ .../juneau/rest/client/remote/package-info.java | 18 +++ .../rest/client/remote/FormDataAnnotationTest.java | 102 +++++++++++++- .../rest/client/remote/HeaderAnnotationTest.java | 63 ++++++++- .../rest/client/remote/PathAnnotationTest.java | 61 ++++++++- .../rest/client/remote/QueryAnnotationTest.java | 103 +++++++++++++- 14 files changed, 582 insertions(+), 19 deletions(-) diff --git a/juneau-core/juneau-core-test/src/test/java/org/apache/juneau/httppart/OpenApiPartSerializerTest.java b/juneau-core/juneau-core-test/src/test/java/org/apache/juneau/httppart/OpenApiPartSerializerTest.java index e9d85cb..45518bc 100644 --- a/juneau-core/juneau-core-test/src/test/java/org/apache/juneau/httppart/OpenApiPartSerializerTest.java +++ b/juneau-core/juneau-core-test/src/test/java/org/apache/juneau/httppart/OpenApiPartSerializerTest.java @@ -408,7 +408,7 @@ public class OpenApiPartSerializerTest { @Test public void d05_arrayType_collectionFormatUon() throws Exception { - HttpPartSchema ps = schema("array","uon").build(); + HttpPartSchema ps = schema("array").collectionFormat("uon").build(); assertEquals("@(foo,bar,'null',null)", s.serialize(ps, new String[]{"foo","bar","null",null})); assertEquals("@(foo,bar,'null',null)", s.serialize(ps, new Object[]{"foo","bar","null",null})); assertEquals("@(foo,bar,'null',null)", s.serialize(ps, new D[]{new D("foo"),new D("bar"),new D("null"),null})); @@ -958,7 +958,7 @@ public class OpenApiPartSerializerTest { @Test public void h04_objectType_2d_uon() throws Exception { - HttpPartSchema ps = schema("array","uon").items(schema("object")).build(); + HttpPartSchema ps = schema("array").collectionFormat("uon").items(schema("object")).build(); assertEquals("@((f1='1',f2=2,f3=true),(),null)", s.serialize(ps, new H1[]{new H1("1",2,true),new H1(null,null,null),null})); assertEquals("@((f1='1',f2=2,f3=true),(),null)", s.serialize(ps, AList.create(new H1("1",2,true),new H1(null,null,null),null))); assertEquals("@((f1='1',f2=2,f3=true),(f1=null,f2=null,f3=null),null)", s.serialize(ps, new ObjectMap[]{new ObjectMap("{f1:'1',f2:2,f3:true}"),new ObjectMap("{f1:null,f2:null,f3:null}"),null})); @@ -997,7 +997,7 @@ public class OpenApiPartSerializerTest { @Test public void h03_objectType_3d_uon() throws Exception { - HttpPartSchema ps = schema("array","uon").items(schema("array").items(schema("object"))).build(); + HttpPartSchema ps = schema("array").collectionFormat("uon").items(schema("array").items(schema("object"))).build(); assertEquals("@(@((f1='1',f2=2,f3=true),(f1=x,f2=3,f3=false)),@((),null),null)", s.serialize(ps, new H1[][]{{new H1("1",2,true),new H1("x",3,false)},{new H1(null,null,null),null},null})); assertEquals("@(@((f1='1',f2=2,f3=true),(f1=x,f2=3,f3=false)),@((),null),null)", s.serialize(ps, AList.create(new H1[]{new H1("1",2,true),new H1("x",3,false)},new H1[]{new H1(null,null,null),null},null))); assertEquals("@(@((f1='1',f2=2,f3=true),(f1=x,f2=3,f3=false)),@((),null),null)", s.serialize(ps, AList.create(AList.create(new H1("1",2,true),new H1("x",3,false)),AList.create(new H1(null,null,null),null),null))); diff --git a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/annotation/FormData.java b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/annotation/FormData.java index 32649a1..538c8ee 100644 --- a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/annotation/FormData.java +++ b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/annotation/FormData.java @@ -460,6 +460,7 @@ public @interface FormData { * <js>"pipes</js> - Pipe-separated values (e.g. <js>"foo|bar"</js>). * <li> * <js>"multi"</js> - Corresponds to multiple parameter instances instead of multiple values for a single instance (e.g. <js>"foo=bar&foo=baz"</js>). + * <br>Note: This is not supported by {@link OpenApiSerializer}. * <li> * <js>"uon"</js> - UON notation (e.g. <js>"@(foo,bar)"</js>). * </ul> diff --git a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/annotation/Header.java b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/annotation/Header.java index 95537b2..b82b87e 100644 --- a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/annotation/Header.java +++ b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/annotation/Header.java @@ -436,8 +436,6 @@ public @interface Header { * <li> * <js>"pipes</js> - Pipe-separated values (e.g. <js>"foo|bar"</js>). * <li> - * <js>"multi"</js> - Corresponds to multiple parameter instances instead of multiple values for a single instance (e.g. <js>"foo=bar&foo=baz"</js>). - * <li> * <js>"uon"</js> - UON notation (e.g. <js>"@(foo,bar)"</js>). * <li> * </ul> diff --git a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/annotation/Path.java b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/annotation/Path.java index bc6073a..14a126f 100644 --- a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/annotation/Path.java +++ b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/annotation/Path.java @@ -410,8 +410,6 @@ public @interface Path { * <li> * <js>"pipes</js> - Pipe-separated values (e.g. <js>"foo|bar"</js>). * <li> - * <js>"multi"</js> - Corresponds to multiple parameter instances instead of multiple values for a single instance (e.g. <js>"foo=bar&foo=baz"</js>). - * <li> * <js>"uon"</js> - UON notation (e.g. <js>"@(foo,bar)"</js>). * <li> * </ul> diff --git a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/annotation/Query.java b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/annotation/Query.java index 3d90855..c18ed48 100644 --- a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/annotation/Query.java +++ b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/annotation/Query.java @@ -449,6 +449,7 @@ public @interface Query { * <js>"pipes</js> - Pipe-separated values (e.g. <js>"foo|bar"</js>). * <li> * <js>"multi"</js> - Corresponds to multiple parameter instances instead of multiple values for a single instance (e.g. <js>"foo=bar&foo=baz"</js>). + * <br>Note: This is not supported by {@link OpenApiSerializer}. * <li> * <js>"uon"</js> - UON notation (e.g. <js>"@(foo,bar)"</js>). * </ul> diff --git a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/httppart/Constants.java b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/httppart/Constants.java new file mode 100644 index 0000000..8fc01c9 --- /dev/null +++ b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/httppart/Constants.java @@ -0,0 +1,151 @@ +// *************************************************************************************************************************** +// * 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.httppart; + +/** + * HTTP-Part constants. + */ +public class Constants { + + //----------------------------------------------------------------------------------------------------------------- + // CollectionFormat + //----------------------------------------------------------------------------------------------------------------- + + /** + * Comma-separated values (e.g. <js>"foo,bar"</js>). + */ + public static final String CF_CSV = "csv"; + + /** + * Space-separated values (e.g. <js>"foo bar"</js>). + */ + public static final String CF_SSV = "ssv"; + + /** + * Tab-separated values (e.g. <js>"foo\tbar"</js>). + */ + public static final String CF_TSV = "tsv"; + + /** + * Pipe-separated values (e.g. <js>"foo|bar"</js>). + */ + public static final String CF_PIPES = "pipes"; + + /** + * Corresponds to multiple parameter instances instead of multiple values for a single instance (e.g. <js>"foo=bar&foo=baz"</js>). + */ + public static final String CF_MULTI = "multi"; + + /** + * UON notation (e.g. <js>"@(foo,bar)"</js>). + */ + public static final String CF_UON = "uon"; + + //----------------------------------------------------------------------------------------------------------------- + // Type + //----------------------------------------------------------------------------------------------------------------- + + /** + * String. + */ + public static final String TYPE_STRING = "string"; + + /** + * Floating point number. + */ + public static final String TYPE_NUMBER = "number"; + + /** + * Decimal number. + */ + public static final String TYPE_INTEGER = "integer"; + + /** + * Boolean. + */ + public static final String TYPE_BOOLEAN = "boolean"; + + /** + * Array or collection. + */ + public static final String TYPE_ARRAY = "array"; + + /** + * Map or bean. + */ + public static final String TYPE_OBJECT = "object"; + + /** + * File. + */ + public static final String TYPE_FILE = "file"; + + //----------------------------------------------------------------------------------------------------------------- + // Format + //----------------------------------------------------------------------------------------------------------------- + + /** + * Signed 32 bits. + */ + public static final String FORMAT_INT32 = "int32"; + + /** + * Signed 64 bits. + */ + public static final String FORMAT_INT64 = "int64"; + + /** + * 32-bit floating point number. + */ + public static final String FORMAT_FLOAT = "float"; + + /** + * 64-bit floating point number. + */ + public static final String FORMAT_DOUBLE = "double"; + + /** + * BASE-64 encoded characters. + */ + public static final String FORMAT_BYTE = "byte"; + + /** + * Hexadecimal encoded octets (e.g. <js>"00FF"</js>). + */ + public static final String FORMAT_BINARY = "binary"; + + /** + * Spaced-separated hexadecimal encoded octets (e.g. <js>"00 FF"</js>). + */ + public static final String FORMAT_BINARY_SPACED = "binary-spaced"; + + /** + * An <a href='http://xml2rfc.ietf.org/public/rfc/html/rfc3339.html#anchor14'>RFC3339 full-date</a>. + */ + public static final String FORMAT_DATE = "date"; + + /** + * An <a href='http://xml2rfc.ietf.org/public/rfc/html/rfc3339.html#anchor14'>RFC3339 date-time</a>. + */ + public static final String FORMAT_DATE_TIME = "date-time"; + + /** + * Used to hint UIs the input needs to be obscured. + */ + public static final String FORMAT_PASSWORD = "password"; + + /** + * UON notation (e.g. <js>"(foo=bar,baz=@(qux,123))"</js>). + */ + public static final String FORMAT_UON = "uon"; +} diff --git a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/marshall/OpenApi.java b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/marshall/OpenApi.java new file mode 100644 index 0000000..d0e05e6 --- /dev/null +++ b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/marshall/OpenApi.java @@ -0,0 +1,71 @@ +// *************************************************************************************************************************** +// * 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.marshall; + +import org.apache.juneau.oapi.*; + +/** + * A pairing of a {@link OpenApiSerializer} and {@link OpenApiParser} into a single class with convenience read/write methods. + * + * <p> + * The general idea is to combine a single serializer and parser inside a simplified API for reading and writing POJOs. + * + * <h5 class='figure'>Examples:</h5> + * <p class='bcode w800'> + * <jc>// Using instance.</jc> + * OpenApi oapi = <jk>new</jk> OpenApi(); + * MyPojo myPojo = oapi.read(string, MyPojo.<jk>class</jk>); + * String string = oapi.write(myPojo); + * </p> + * <p class='bcode w800'> + * <jc>// Using DEFAULT instance.</jc> + * MyPojo myPojo = OpenApi.<jsf>DEFAULT</jsf>.read(string, MyPojo.<jk>class</jk>); + * String string = OpenApi.<jsf>DEFAULT</jsf>.write(myPojo); + * </p> + * + * <h5 class='section'>See Also:</h5> + * <ul> + * <li class='link'>{@doc juneau-marshall.Marshalls} + * </ul> + */ +public class OpenApi extends CharMarshall { + + /** + * Default reusable instance. + */ + public static final OpenApi DEFAULT = new OpenApi(); + + /** + * Constructor. + * + * @param s + * The serializer to use for serializing output. + * <br>Must not be <jk>null</jk>. + * @param p + * The parser to use for parsing input. + * <br>Must not be <jk>null</jk>. + */ + public OpenApi(OpenApiSerializer s, OpenApiParser p) { + super(s, p); + } + + /** + * Constructor. + * + * <p> + * Uses {@link OpenApiSerializer#DEFAULT} and {@link OpenApiParser#DEFAULT}. + */ + public OpenApi() { + this(OpenApiSerializer.DEFAULT, OpenApiParser.DEFAULT); + } +} diff --git a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/oapi/OpenApiSerializerSession.java b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/oapi/OpenApiSerializerSession.java index d41481b..3d81424 100644 --- a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/oapi/OpenApiSerializerSession.java +++ b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/oapi/OpenApiSerializerSession.java @@ -132,7 +132,7 @@ public class OpenApiSerializerSession extends UonSerializerSession { } else if (t == ARRAY) { - if (f == HttpPartSchema.Format.UON) + if (cf == HttpPartSchema.CollectionFormat.UON) out = super.serialize(partType, null, toList(partType, type, value, schema)); else { List<String> l = new ArrayList<>(); diff --git a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/oapi/package-info.java b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/oapi/package-info.java new file mode 100755 index 0000000..594838c --- /dev/null +++ b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/oapi/package-info.java @@ -0,0 +1,18 @@ +// *************************************************************************************************************************** +// * 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. * +// *************************************************************************************************************************** + +/** + * OpenAPI Marshalling Support + */ +package org.apache.juneau.oapi; + diff --git a/juneau-rest/juneau-rest-client/src/main/java/org/apache/juneau/rest/client/remote/package-info.java b/juneau-rest/juneau-rest-client/src/main/java/org/apache/juneau/rest/client/remote/package-info.java new file mode 100644 index 0000000..45368fc --- /dev/null +++ b/juneau-rest/juneau-rest-client/src/main/java/org/apache/juneau/rest/client/remote/package-info.java @@ -0,0 +1,18 @@ +/*************************************************************************************************************************** + * 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. + * + ***************************************************************************************************************************/ + +/** + * Remote REST API + */ +package org.apache.juneau.rest.client.remote; \ No newline at end of file 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 index 549a3fb..3ae3e18 100644 --- 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 @@ -67,9 +67,9 @@ public class FormDataAnnotationTest { @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 postA04b(@FormData(name="x",collectionFormat="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 postA05b(@FormData(name="x",collectionFormat="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); @@ -167,7 +167,7 @@ public class FormDataAnnotationTest { } //================================================================================================================= - // @FormData(_default) + // @FormData(_default/allowEmptyValue) //================================================================================================================= @RestResource @@ -229,4 +229,100 @@ public class FormDataAnnotationTest { public void b04b_defaultIsBlank_allowEmptyValue_emptyString() throws Exception { assertEquals("{x:''}", br.postB04("")); } + + //================================================================================================================= + // @FormData(collectionFormat) + //================================================================================================================= + + @RestResource + public static class C { + @RestMethod + public String postA(@FormData("*") ObjectMap m) { + return m.toString(); + } + @RestMethod + public Reader postB(@Body Reader b) { + return b; + } + } + private static MockRest c = MockRest.create(C.class); + + @RemoteResource + public static interface CR { + @RemoteMethod(path="/a") String postC01a(@FormData(name="x") String...b); + @RemoteMethod(path="/b") String postC01b(@FormData(name="x") String...b); + @RemoteMethod(path="/a") String postC02a(@FormData(name="x",collectionFormat="csv") String...b); + @RemoteMethod(path="/b") String postC02b(@FormData(name="x",collectionFormat="csv") String...b); + @RemoteMethod(path="/a") String postC03a(@FormData(name="x",collectionFormat="ssv") String...b); + @RemoteMethod(path="/b") String postC03b(@FormData(name="x",collectionFormat="ssv") String...b); + @RemoteMethod(path="/a") String postC04a(@FormData(name="x",collectionFormat="tsv") String...b); + @RemoteMethod(path="/b") String postC04b(@FormData(name="x",collectionFormat="tsv") String...b); + @RemoteMethod(path="/a") String postC05a(@FormData(name="x",collectionFormat="pipes") String...b); + @RemoteMethod(path="/b") String postC05b(@FormData(name="x",collectionFormat="pipes") String...b); + @RemoteMethod(path="/a") String postC06a(@FormData(name="x",collectionFormat="multi") String...b); + @RemoteMethod(path="/b") String postC06b(@FormData(name="x",collectionFormat="multi") String...b); + @RemoteMethod(path="/a") String postC07a(@FormData(name="x",collectionFormat="uon") String...b); + @RemoteMethod(path="/b") String postC07b(@FormData(name="x",collectionFormat="uon") String...b); + } + + private static CR cr = RestClient.create().mockHttpConnection(c).build().getRemoteResource(CR.class); + + @Test + public void c01a_default() throws Exception { + assertEquals("{x:'foo,bar'}", cr.postC01a("foo","bar")); + } + @Test + public void c01b_default_raw() throws Exception { + assertEquals("x=foo%2Cbar", cr.postC01b("foo","bar")); + } + @Test + public void c02a_csv() throws Exception { + assertEquals("{x:'foo,bar'}", cr.postC02a("foo","bar")); + } + @Test + public void c02b_csv_raw() throws Exception { + assertEquals("x=foo%2Cbar", cr.postC02b("foo","bar")); + } + @Test + public void c03a_ssv() throws Exception { + assertEquals("{x:'foo bar'}", cr.postC03a("foo","bar")); + } + @Test + public void c03b_ssv_raw() throws Exception { + assertEquals("x=foo+bar", cr.postC03b("foo","bar")); + } + @Test + public void c04a_tsv() throws Exception { + assertEquals("{x:'foo\\tbar'}", cr.postC04a("foo","bar")); + } + @Test + public void c04b_tsv_raw() throws Exception { + assertEquals("x=foo%09bar", cr.postC04b("foo","bar")); + } + @Test + public void c05a_pipes() throws Exception { + assertEquals("{x:'foo|bar'}", cr.postC05a("foo","bar")); + } + @Test + public void c05b_pipes_raw() throws Exception { + assertEquals("x=foo%7Cbar", cr.postC05b("foo","bar")); + } + @Test + public void c06a_multi() throws Exception { + // Not supported, but should be treated as csv. + assertEquals("{x:'foo,bar'}", cr.postC06a("foo","bar")); + } + @Test + public void c06b_multi_raw() throws Exception { + // Not supported, but should be treated as csv. + assertEquals("x=foo%2Cbar", cr.postC06b("foo","bar")); + } + @Test + public void c07a_uon() throws Exception { + assertEquals("{x:'@(foo,bar)'}", cr.postC07a("foo","bar")); + } + @Test + public void c07b_uon_raw() throws Exception { + assertEquals("x=%40%28foo%2Cbar%29", cr.postC07b("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 index 099bbc0..7443d28 100644 --- 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 @@ -66,9 +66,9 @@ public class HeaderAnnotationTest { @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 getA04b(@Header(name="x",collectionFormat="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 getA05b(@Header(name="x",collectionFormat="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); @@ -146,7 +146,7 @@ public class HeaderAnnotationTest { } //================================================================================================================= - // @Header(_default) + // @Header(_default/allowEmptyValue) //================================================================================================================= @RestResource @@ -209,4 +209,61 @@ public class HeaderAnnotationTest { public void b04b_defaultIsBlank_allowEmptyValue_emptyString() throws Exception { assertEquals("{x:''}", br.getB04("")); } + + //================================================================================================================= + // @Header(collectionFormat) + //================================================================================================================= + + @RestResource + public static class C { + @RestMethod + public String getA(@Header("*") ObjectMap m) { + m.removeAll("Accept-Encoding","Connection","Host","User-Agent"); + return m.toString(); + } + } + private static MockRest c = MockRest.create(C.class); + + @RemoteResource + public static interface CR { + @RemoteMethod(path="/a") String getC01(@Header(name="x") String...b); + @RemoteMethod(path="/a") String getC02(@Header(name="x",collectionFormat="csv") String...b); + @RemoteMethod(path="/a") String getC03(@Header(name="x",collectionFormat="ssv") String...b); + @RemoteMethod(path="/a") String getC04(@Header(name="x",collectionFormat="tsv") String...b); + @RemoteMethod(path="/a") String getC05(@Header(name="x",collectionFormat="pipes") String...b); + @RemoteMethod(path="/a") String getC06(@Header(name="x",collectionFormat="multi") String...b); + @RemoteMethod(path="/a") String getC07(@Header(name="x",collectionFormat="uon") String...b); + } + + private static CR cr = RestClient.create().mockHttpConnection(c).build().getRemoteResource(CR.class); + + @Test + public void c01a_default() throws Exception { + assertEquals("{x:'foo,bar'}", cr.getC01("foo","bar")); + } + @Test + public void c02a_csv() throws Exception { + assertEquals("{x:'foo,bar'}", cr.getC02("foo","bar")); + } + @Test + public void c03a_ssv() throws Exception { + assertEquals("{x:'foo bar'}", cr.getC03("foo","bar")); + } + @Test + public void c04a_tsv() throws Exception { + assertEquals("{x:'foo\\tbar'}", cr.getC04("foo","bar")); + } + @Test + public void c05a_pipes() throws Exception { + assertEquals("{x:'foo|bar'}", cr.getC05("foo","bar")); + } + @Test + public void c06a_multi() throws Exception { + // Not supported, but should be treated as csv. + assertEquals("{x:'foo,bar'}", cr.getC06("foo","bar")); + } + @Test + public void c07a_uon() throws Exception { + assertEquals("{x:'@(foo,bar)'}", cr.getC07("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 index 38b3989..d90b5f3 100644 --- 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 @@ -63,9 +63,9 @@ public class PathAnnotationTest { @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 getA04b(@Path(name="x",collectionFormat="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 getA05b(@Path(name="x",collectionFormat="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); @@ -141,4 +141,61 @@ public class PathAnnotationTest { public void a09b_NameValuePairs() throws Exception { assertEquals("bar", a01.getA09b(new NameValuePairs().append("x", "bar"))); } + + + //================================================================================================================= + // @Query(collectionFormat) + //================================================================================================================= + + @RestResource + public static class C { + @RestMethod(path="/a/{x}") + public String getA(@Path("x") Object x) { + return x.toString(); + } + } + private static MockRest c = MockRest.create(C.class); + + @RemoteResource + public static interface CR { + @RemoteMethod(path="/a/{x}") String getC01(@Path(name="x") String...b); + @RemoteMethod(path="/a/{x}") String getC02(@Path(name="x",collectionFormat="csv") String...b); + @RemoteMethod(path="/a/{x}") String getC03(@Path(name="x",collectionFormat="ssv") String...b); + @RemoteMethod(path="/a/{x}") String getC04(@Path(name="x",collectionFormat="tsv") String...b); + @RemoteMethod(path="/a/{x}") String getC05(@Path(name="x",collectionFormat="pipes") String...b); + @RemoteMethod(path="/a/{x}") String getC06(@Path(name="x",collectionFormat="multi") String...b); + @RemoteMethod(path="/a/{x}") String getC07(@Path(name="x",collectionFormat="uon") String...b); + } + + private static CR cr = RestClient.create().mockHttpConnection(c).build().getRemoteResource(CR.class); + + @Test + public void c01a_default() throws Exception { + assertEquals("foo,bar", cr.getC01("foo","bar")); + } + @Test + public void c02a_csv() throws Exception { + assertEquals("foo,bar", cr.getC02("foo","bar")); + } + @Test + public void c03a_ssv() throws Exception { + assertEquals("foo bar", cr.getC03("foo","bar")); + } + @Test + public void c04a_tsv() throws Exception { + assertEquals("foo\tbar", cr.getC04("foo","bar")); + } + @Test + public void c05a_pipes() throws Exception { + assertEquals("foo|bar", cr.getC05("foo","bar")); + } + @Test + public void c06a_multi() throws Exception { + // Not supported, but should be treated as csv. + assertEquals("foo,bar", cr.getC06("foo","bar")); + } + @Test + public void c07a_uon() throws Exception { + assertEquals("@(foo,bar)", cr.getC07("foo","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 index d1a3697..1700e66 100644 --- 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 @@ -21,6 +21,7 @@ import java.util.*; import org.apache.juneau.*; import org.apache.juneau.http.annotation.*; +import org.apache.juneau.rest.*; import org.apache.juneau.rest.annotation.*; import org.apache.juneau.rest.client.*; import org.apache.juneau.rest.mock.*; @@ -66,9 +67,9 @@ public class QueryAnnotationTest { @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 getA04b(@Query(name="x",collectionFormat="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 getA05b(@Query(name="x",collectionFormat="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); @@ -166,7 +167,7 @@ public class QueryAnnotationTest { } //================================================================================================================= - // @Query(_default) + // @Query(_default/allowEmptyValue) //================================================================================================================= @RestResource @@ -228,4 +229,100 @@ public class QueryAnnotationTest { public void b04b_defaultIsBlank_allowEmptyValue_emptyString() throws Exception { assertEquals("{x:''}", br.getB04("")); } + + //================================================================================================================= + // @Query(collectionFormat) + //================================================================================================================= + + @RestResource + public static class C { + @RestMethod + public String getA(@Query("*") ObjectMap m) { + return m.toString(); + } + @RestMethod + public Reader getB(RestRequest req) { + return new StringReader(req.getQueryString()); + } + } + private static MockRest c = MockRest.create(C.class); + + @RemoteResource + public static interface CR { + @RemoteMethod(path="/a") String getC01a(@Query(name="x") String...b); + @RemoteMethod(path="/b") String getC01b(@Query(name="x") String...b); + @RemoteMethod(path="/a") String getC02a(@Query(name="x",collectionFormat="csv") String...b); + @RemoteMethod(path="/b") String getC02b(@Query(name="x",collectionFormat="csv") String...b); + @RemoteMethod(path="/a") String getC03a(@Query(name="x",collectionFormat="ssv") String...b); + @RemoteMethod(path="/b") String getC03b(@Query(name="x",collectionFormat="ssv") String...b); + @RemoteMethod(path="/a") String getC04a(@Query(name="x",collectionFormat="tsv") String...b); + @RemoteMethod(path="/b") String getC04b(@Query(name="x",collectionFormat="tsv") String...b); + @RemoteMethod(path="/a") String getC05a(@Query(name="x",collectionFormat="pipes") String...b); + @RemoteMethod(path="/b") String getC05b(@Query(name="x",collectionFormat="pipes") String...b); + @RemoteMethod(path="/a") String getC06a(@Query(name="x",collectionFormat="multi") String...b); + @RemoteMethod(path="/b") String getC06b(@Query(name="x",collectionFormat="multi") String...b); + @RemoteMethod(path="/a") String getC07a(@Query(name="x",collectionFormat="uon") String...b); + @RemoteMethod(path="/b") String getC07b(@Query(name="x",collectionFormat="uon") String...b); + } + + private static CR cr = RestClient.create().mockHttpConnection(c).build().getRemoteResource(CR.class); + + @Test + public void c01a_default() throws Exception { + assertEquals("{x:'foo,bar'}", cr.getC01a("foo","bar")); + } + @Test + public void c01b_default_raw() throws Exception { + assertEquals("x=foo%2Cbar", cr.getC01b("foo","bar")); + } + @Test + public void c02a_csv() throws Exception { + assertEquals("{x:'foo,bar'}", cr.getC02a("foo","bar")); + } + @Test + public void c02b_csv_raw() throws Exception { + assertEquals("x=foo%2Cbar", cr.getC02b("foo","bar")); + } + @Test + public void c03a_ssv() throws Exception { + assertEquals("{x:'foo bar'}", cr.getC03a("foo","bar")); + } + @Test + public void c03b_ssv_raw() throws Exception { + assertEquals("x=foo+bar", cr.getC03b("foo","bar")); + } + @Test + public void c04a_tsv() throws Exception { + assertEquals("{x:'foo\\tbar'}", cr.getC04a("foo","bar")); + } + @Test + public void c04b_tsv_raw() throws Exception { + assertEquals("x=foo%09bar", cr.getC04b("foo","bar")); + } + @Test + public void c05a_pipes() throws Exception { + assertEquals("{x:'foo|bar'}", cr.getC05a("foo","bar")); + } + @Test + public void c05b_pipes_raw() throws Exception { + assertEquals("x=foo%7Cbar", cr.getC05b("foo","bar")); + } + @Test + public void c06a_multi() throws Exception { + // Not supported, but should be treated as csv. + assertEquals("{x:'foo,bar'}", cr.getC06a("foo","bar")); + } + @Test + public void c06b_multi_raw() throws Exception { + // Not supported, but should be treated as csv. + assertEquals("x=foo%2Cbar", cr.getC06b("foo","bar")); + } + @Test + public void c07a_uon() throws Exception { + assertEquals("{x:'@(foo,bar)'}", cr.getC07a("foo","bar")); + } + @Test + public void c07b_uon_raw() throws Exception { + assertEquals("x=%40%28foo%2Cbar%29", cr.getC07b("foo","bar")); + } }