From f5928e574fddc08dcc0e1dbeed2aea3f0dc6209a Mon Sep 17 00:00:00 2001 From: chamil321 Date: Wed, 21 Apr 2021 11:15:12 +0530 Subject: [PATCH] Add test cases --- .../http/compiler/CompilerPluginTest.java | 49 +++++++ .../sample_package_10/service.bal | 2 +- .../sample_package_11/Ballerina.toml | 4 + .../sample_package_11/service.bal | 128 ++++++++++++++++++ .../http/compiler/HttpResourceValidator.java | 8 +- 5 files changed, 185 insertions(+), 6 deletions(-) create mode 100644 http-compiler-plugin-tests/src/test/resources/ballerina_sources/sample_package_11/Ballerina.toml create mode 100644 http-compiler-plugin-tests/src/test/resources/ballerina_sources/sample_package_11/service.bal diff --git a/http-compiler-plugin-tests/src/test/java/io/ballerina/stdlib/http/compiler/CompilerPluginTest.java b/http-compiler-plugin-tests/src/test/java/io/ballerina/stdlib/http/compiler/CompilerPluginTest.java index e90d04b86c..ba9f8e9220 100644 --- a/http-compiler-plugin-tests/src/test/java/io/ballerina/stdlib/http/compiler/CompilerPluginTest.java +++ b/http-compiler-plugin-tests/src/test/java/io/ballerina/stdlib/http/compiler/CompilerPluginTest.java @@ -55,6 +55,7 @@ public class CompilerPluginTest { private static final String HTTP_111 = "HTTP_111"; private static final String HTTP_112 = "HTTP_112"; private static final String HTTP_113 = "HTTP_113"; + private static final String HTTP_114 = "HTTP_114"; private static final String REMOTE_METHODS_NOT_ALLOWED = "remote methods are not allowed in http:Service"; @@ -211,4 +212,52 @@ public void testListenerTypes() { err -> err.diagnosticInfo().messageFormat().contains( "invalid resource parameter type: 'ballerina/http")).forEach(Assert::assertTrue); } + +// @Test + public void testCallerInfoAnnotation() { + Package currentPackage = loadPackage("sample_package_10"); + PackageCompilation compilation = currentPackage.getCompilation(); + DiagnosticResult diagnosticResult = compilation.diagnosticResult(); + Assert.assertEquals(diagnosticResult.diagnosticCount(), 6); + assertError(diagnosticResult, 0, "incompatible respond method argument type : expected " + + "'int' according to the 'http:CallerInfo' annotation", HTTP_114); + assertError(diagnosticResult, 1, "incompatible respond method argument type : expected " + + "'decimal' according to the 'http:CallerInfo' annotation", HTTP_114); + assertError(diagnosticResult, 2, "incompatible respond method argument type : expected " + + "'Person' according to the 'http:CallerInfo' annotation", HTTP_114); + assertError(diagnosticResult, 3, "incompatible respond method argument type : expected " + + "'string' according to the 'http:CallerInfo' annotation", HTTP_114); + assertError(diagnosticResult, 4, "incompatible respond method argument type : expected " + + "'Person' according to the 'http:CallerInfo' annotation", HTTP_114); + assertError(diagnosticResult, 5, "incompatible respond method argument type : expected " + + "'Person' according to the 'http:CallerInfo' annotation", HTTP_114); + } + + @Test + public void testCallerInfoTypes() { + Package currentPackage = loadPackage("sample_package_11"); + PackageCompilation compilation = currentPackage.getCompilation(); + DiagnosticResult diagnosticResult = compilation.diagnosticResult(); + Assert.assertEquals(diagnosticResult.diagnosticCount(), 10); + assertError(diagnosticResult, 0, "incompatible respond method argument type : expected " + + "'http:Response' according to the 'http:CallerInfo' annotation", HTTP_114); + assertError(diagnosticResult, 1, "incompatible respond method argument type : expected " + + "'Xml' according to the 'http:CallerInfo' annotation", HTTP_114); + assertError(diagnosticResult, 2, "incompatible respond method argument type : expected " + + "'json' according to the 'http:CallerInfo' annotation", HTTP_114); + assertError(diagnosticResult, 3, "incompatible respond method argument type : expected " + + "'ByteArr' according to the 'http:CallerInfo' annotation", HTTP_114); + assertError(diagnosticResult, 4, "incompatible respond method argument type : expected " + + "'MapJson' according to the 'http:CallerInfo' annotation", HTTP_114); + assertError(diagnosticResult, 5, "incompatible respond method argument type : expected " + + "'PersonTable' according to the 'http:CallerInfo' annotation", HTTP_114); + assertError(diagnosticResult, 6, "incompatible respond method argument type : expected " + + "'MapJsonArr' according to the 'http:CallerInfo' annotation", HTTP_114); + assertError(diagnosticResult, 7, "incompatible respond method argument type : expected " + + "'PersonTableArr' according to the 'http:CallerInfo' annotation", HTTP_114); + assertError(diagnosticResult, 8, "incompatible respond method argument type : expected " + + "'EntityArr' according to the 'http:CallerInfo' annotation", HTTP_114); + assertError(diagnosticResult, 9, "incompatible respond method argument type : expected " + + "'ByteStream' according to the 'http:CallerInfo' annotation", HTTP_114); + } } diff --git a/http-compiler-plugin-tests/src/test/resources/ballerina_sources/sample_package_10/service.bal b/http-compiler-plugin-tests/src/test/resources/ballerina_sources/sample_package_10/service.bal index 92461a0ce6..e707c65c3f 100644 --- a/http-compiler-plugin-tests/src/test/resources/ballerina_sources/sample_package_10/service.bal +++ b/http-compiler-plugin-tests/src/test/resources/ballerina_sources/sample_package_10/service.bal @@ -88,7 +88,7 @@ service http:Service on new http:Listener(9090) { } resource function get callerInfo17(@http:CallerInfo {respondType: Person}http:Caller abc) returns error? { - error? a = abc->respond({school:1.23}); // This getting passed as map + error? a = abc->respond({school:1.23}); // This getting passed as map and this is a limitation } resource function get callerInfo18(@http:CallerInfo {respondType: Person}http:Caller abc) returns error? { diff --git a/http-compiler-plugin-tests/src/test/resources/ballerina_sources/sample_package_11/Ballerina.toml b/http-compiler-plugin-tests/src/test/resources/ballerina_sources/sample_package_11/Ballerina.toml new file mode 100644 index 0000000000..c5bda67204 --- /dev/null +++ b/http-compiler-plugin-tests/src/test/resources/ballerina_sources/sample_package_11/Ballerina.toml @@ -0,0 +1,4 @@ +[package] +org = "http_test" +name = "sample_10" +version = "0.1.0" diff --git a/http-compiler-plugin-tests/src/test/resources/ballerina_sources/sample_package_11/service.bal b/http-compiler-plugin-tests/src/test/resources/ballerina_sources/sample_package_11/service.bal new file mode 100644 index 0000000000..2c06c224a9 --- /dev/null +++ b/http-compiler-plugin-tests/src/test/resources/ballerina_sources/sample_package_11/service.bal @@ -0,0 +1,128 @@ +import ballerina/http; +import ballerina/mime; +import ballerina/io; + +type RetEmployee record {| + readonly int id; + string name; +|}; + +type PersonTable table key(id); +type Xml xml; +type ByteArr byte[]; +type MapJson map; +type MapJsonArr map[]; +type EntityArr mime:Entity[]; +type PersonTableArr PersonTable[]; +type ByteStream stream; + +service http:Service on new http:Listener(9090) { + resource function get callerInfo17(int xyz, @http:CallerInfo {respondType: http:Response} http:Caller abc) { + http:Response res = new; + checkpanic abc->respond(res); + } + + resource function get callerInfo18(int xyz, @http:CallerInfo {respondType: http:Response} http:Caller abc) { + checkpanic abc->respond("res"); // error + } + + resource function get callerInfo20(int xyz, @http:CallerInfo {respondType: Xml} http:Caller abc) { + xml x = xml `Hello World`; + checkpanic abc->respond(x); + } + + resource function get callerInfo21(int xyz, @http:CallerInfo {respondType: Xml} http:Caller abc) { + checkpanic abc->respond("res"); // error + } + + resource function get callerInfo2_2(int xyz, @http:CallerInfo {respondType: json} http:Caller abc) { + json j = {hello: "world"}; + checkpanic abc->respond(j); + } + + resource function get callerInfo22(int xyz, @http:CallerInfo {respondType: json} http:Caller abc) { + checkpanic abc->respond({hello: "world"}); // this is also fails and a limitation for inline json + } + + resource function get callerInfo23(int xyz, @http:CallerInfo {respondType: json} http:Caller abc) { + http:Response res = new; + checkpanic abc->respond(res); // error + } + + resource function get callerInfo24(int xyz, @http:CallerInfo {respondType: ByteArr} http:Caller abc) { + checkpanic abc->respond("Sample Text".toBytes()); + } + + resource function get callerInfo25(int xyz, @http:CallerInfo {respondType: ByteArr} http:Caller abc) { + http:Response res = new; + checkpanic abc->respond(res); // error + } + + resource function get callerInfo26(int xyz, @http:CallerInfo {respondType: MapJson} http:Caller abc) { + map jj = {sam: {hello:"world"}, jon: {no:56}}; + checkpanic abc->respond(jj); + } + + resource function get callerInfo27(int xyz, @http:CallerInfo {respondType: MapJson} http:Caller abc) { + http:Response res = new; + checkpanic abc->respond(res); // error + } + + resource function get callerInfo28(int xyz, @http:CallerInfo {respondType: PersonTable} http:Caller abc) { + PersonTable tbPerson = table [ + {id: 1, name: "John"}, + {id: 2, name: "Bella"} + ]; + checkpanic abc->respond(tbPerson); + } + + resource function get callerInfo29(int xyz, @http:CallerInfo {respondType: PersonTable} http:Caller abc) { + checkpanic abc->respond("res"); // error + } + + resource function get callerInfo30(int xyz, @http:CallerInfo {respondType: MapJsonArr} http:Caller abc) { + map jj = {sam: {hello:"world"}, jon: {no:56}}; + map[] arr = [jj, jj]; + checkpanic abc->respond(arr); + } + + resource function get callerInfo31(int xyz, @http:CallerInfo {respondType: MapJsonArr} http:Caller abc) { + http:Response res = new; + checkpanic abc->respond(res); // error + } + + resource function get callerInfo32(int xyz, @http:CallerInfo {respondType: PersonTableArr} http:Caller abc) { + PersonTable tbPerson = table [ + {id: 1, name: "John"}, + {id: 2, name: "Bella"} + ]; + PersonTableArr arr = [tbPerson, tbPerson]; + checkpanic abc->respond(arr); + } + + resource function get callerInfo33(int xyz, @http:CallerInfo {respondType: PersonTableArr} http:Caller abc) { + checkpanic abc->respond("res"); // error + } + + resource function get callerInfo34(int xyz, @http:CallerInfo {respondType: EntityArr} http:Caller abc) { + mime:Entity bodyPart = new; + bodyPart.setJson({"bodyPart":"jsonPart"}); + checkpanic abc->respond([bodyPart, bodyPart]); + } + + resource function get callerInfo35(int xyz, @http:CallerInfo {respondType: EntityArr} http:Caller abc) { + checkpanic abc->respond("res"); // error + } + + resource function get callerInfo36(http:Request request, + @http:CallerInfo {respondType: ByteStream} http:Caller abc) { + var str = request.getByteStream(); + if (str is stream) { + error? err = abc->respond(str); + } + } + + resource function get callerInfo37(@http:CallerInfo {respondType: ByteStream} http:Caller abc) { + checkpanic abc->respond("res"); // error + } +} diff --git a/http-compiler-plugin/src/main/java/io/ballerina/stdlib/http/compiler/HttpResourceValidator.java b/http-compiler-plugin/src/main/java/io/ballerina/stdlib/http/compiler/HttpResourceValidator.java index abae84fac4..4e72ab1139 100644 --- a/http-compiler-plugin/src/main/java/io/ballerina/stdlib/http/compiler/HttpResourceValidator.java +++ b/http-compiler-plugin/src/main/java/io/ballerina/stdlib/http/compiler/HttpResourceValidator.java @@ -147,10 +147,8 @@ private static void extractInputParamTypeAndValidate(SyntaxNodeAnalysisContext c continue; } String typeName = typeNameOptional.get(); - if (CALLER_OBJ_NAME.equals(typeName) || REQUEST_OBJ_NAME.equals(typeName) || - HEADER_OBJ_NAME.equals(typeName)) { - - } else { + if (!CALLER_OBJ_NAME.equals(typeName) && !REQUEST_OBJ_NAME.equals(typeName) && + !HEADER_OBJ_NAME.equals(typeName)) { reportInvalidParameterType(ctx, member, paramType); } } else { @@ -397,7 +395,7 @@ private static void extractCallerInfoValueAndValidate(SyntaxNodeAnalysisContext TypeSymbol argTypeSymbol = ctx.semanticModel().type(argumentNode.expression()).get(); TypeSymbol annotValueSymbol = (TypeSymbol) ctx.semanticModel().symbol(specificFieldNode.valueExpr().get()).get(); - if (!annotValueSymbol.assignableTo(argTypeSymbol)) { + if (!argTypeSymbol.assignableTo(annotValueSymbol)) { reportInCompatibleCallerInfoType(ctx, argumentNode, expectedType); } }