From 44b24cfa63784b7baa86b4b1ecbbf33f838bb1c9 Mon Sep 17 00:00:00 2001 From: Sasindu Alahakoon Date: Thu, 30 Mar 2023 12:26:40 +0530 Subject: [PATCH 1/6] Fix CCE issues in xml and string query expressions --- .../compiler/desugar/QueryDesugar.java | 4 +- .../semantics/analyzer/QueryTypeChecker.java | 7 + .../test/query/StringQueryExpressionTest.java | 5 + .../test/query/XMLQueryExpressionTest.java | 5 + .../query/string-query-expression.bal | 80 ++++++++ .../test-src/query/xml-query-expression.bal | 193 +++++++++++++++++- 6 files changed, 289 insertions(+), 5 deletions(-) diff --git a/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/desugar/QueryDesugar.java b/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/desugar/QueryDesugar.java index e321b68e1eeb..ce8ed750702d 100644 --- a/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/desugar/QueryDesugar.java +++ b/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/desugar/QueryDesugar.java @@ -297,13 +297,13 @@ BLangStatementExpression desugar(BLangQueryExpr queryExpr, SymbolEnv env, onConflictExpr = null; } else { BType refType = Types.getReferredType(queryExpr.getBType()); - if (isXml(refType)) { + if (isXml(types.getSafeType(refType, true, true))) { if (types.isSubTypeOfReadOnly(refType, env)) { isReadonly.value = true; } result = getStreamFunctionVariableRef(queryBlock, QUERY_TO_XML_FUNCTION, Lists.of(streamRef, isReadonly), pos); - } else if (TypeTags.isStringTypeTag(refType.tag)) { + } else if (TypeTags.isStringTypeTag(types.getSafeType(refType, true, true).tag)) { result = getStreamFunctionVariableRef(queryBlock, QUERY_TO_STRING_FUNCTION, Lists.of(streamRef), pos); } else { BType arrayType = refType; diff --git a/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/semantics/analyzer/QueryTypeChecker.java b/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/semantics/analyzer/QueryTypeChecker.java index 52241ec8775b..5f6ad3d8a490 100644 --- a/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/semantics/analyzer/QueryTypeChecker.java +++ b/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/semantics/analyzer/QueryTypeChecker.java @@ -323,12 +323,19 @@ void solveSelectTypeAndResolveType(BLangQueryExpr queryExpr, BLangExpression sel resolvedType = getResolvedType(selectType, type, isReadonly, env); break; case TypeTags.STRING: + selectType = checkExpr(selectExp, env, type, data); + resolvedType = symTable.stringType; + break; case TypeTags.XML: case TypeTags.XML_COMMENT: case TypeTags.XML_ELEMENT: case TypeTags.XML_PI: case TypeTags.XML_TEXT: selectType = checkExpr(selectExp, env, type, data); + if (types.isAssignable(selectType, symTable.xmlType)) { + resolvedType = getResolvedType(new BXMLType(selectType, null), type, isReadonly, env); + break; + } resolvedType = selectType; break; case TypeTags.INTERSECTION: diff --git a/tests/jballerina-unit-test/src/test/java/org/ballerinalang/test/query/StringQueryExpressionTest.java b/tests/jballerina-unit-test/src/test/java/org/ballerinalang/test/query/StringQueryExpressionTest.java index ff0f4a261288..78e4f8fc9927 100644 --- a/tests/jballerina-unit-test/src/test/java/org/ballerinalang/test/query/StringQueryExpressionTest.java +++ b/tests/jballerina-unit-test/src/test/java/org/ballerinalang/test/query/StringQueryExpressionTest.java @@ -48,6 +48,11 @@ public void testSimpleQueryExprForStringResult() { Assert.assertEquals(returnValues.toString(), "Alex Ranjan John "); } + @Test(description = "Test simple query expression with string result") + public void testSimpleQueryExprForStringResult2() { + BRunUtil.invoke(result, "testSimpleQueryExprForStringResult2"); + } + @Test(description = "Test query expression with where giving string result") public void testQueryExprWithWhereForStringResult() { Object returnValues = BRunUtil.invoke(result, "testQueryExprWithWhereForStringResult"); diff --git a/tests/jballerina-unit-test/src/test/java/org/ballerinalang/test/query/XMLQueryExpressionTest.java b/tests/jballerina-unit-test/src/test/java/org/ballerinalang/test/query/XMLQueryExpressionTest.java index 2789de45a60a..7fdd7a227ab9 100644 --- a/tests/jballerina-unit-test/src/test/java/org/ballerinalang/test/query/XMLQueryExpressionTest.java +++ b/tests/jballerina-unit-test/src/test/java/org/ballerinalang/test/query/XMLQueryExpressionTest.java @@ -101,6 +101,11 @@ public void testSimpleQueryExprForXML3() { "30.0029.9949.9939.95"); } + @Test(description = "Test simple query expression for XMLs - #4") + public void testSimpleQueryExprForXML4() { + BRunUtil.invoke(result, "testSimpleQueryExprForXML4"); + } + @Test(description = "Test simple query expression with limit clause for XMLs") public void testQueryExprWithLimitForXML() { Object returnValues = BRunUtil.invoke(result, "testQueryExprWithLimitForXML"); diff --git a/tests/jballerina-unit-test/src/test/resources/test-src/query/string-query-expression.bal b/tests/jballerina-unit-test/src/test/resources/test-src/query/string-query-expression.bal index 84e5f74fc216..5359e1ef2500 100644 --- a/tests/jballerina-unit-test/src/test/resources/test-src/query/string-query-expression.bal +++ b/tests/jballerina-unit-test/src/test/resources/test-src/query/string-query-expression.bal @@ -41,6 +41,64 @@ function testSimpleQueryExprForStringResult() returns string { return outputNameString; } +type Book record {| + string title; + string author; +|}; + +class BookGenerator { + int i = 0; + + public isolated function next() returns record {|Book value;|}|error? { + self.i += 1; + if (self.i < 0) { + return error("Error"); + } else if (self.i >= 3) { + return (); + } + return { + value: { + title: "Title " + self.i.toString(), author: "Author " + self.i.toString() + } + }; + } +} + +function testSimpleQueryExprForStringResult2() { + error? e = trap simpleQueryExprForStringResult(); + assertFalse(e is error); + + e = trap simpleQueryExprForStringResult2(); + assertFalse(e is error); +} + +function simpleQueryExprForStringResult() returns error? { + string:Char chr = "a"; + BookGenerator bookGenerator = new (); + stream bookStream = new (bookGenerator); + + string strValue = check from Book _ in bookStream + select chr; + + string expectedValue = "aa"; + + assertTrue(strValue is string); + assertEquality(strValue, expectedValue); +} + +function simpleQueryExprForStringResult2() returns error? { + stream bookStream = [{ author: "Author 1", title: "Title 1" }, + {author: "Author 2", title: "Title 2" }].toStream(); + + string strValue = check from Book _ in bookStream + select "a"; + + string expectedValue = "aa"; + + assertTrue(strValue is string); + assertEquality(strValue, expectedValue); +} + function testQueryExprWithWhereForStringResult() returns string { Person p1 = {firstName: "Alex", lastName: "George", age: 23}; Person p2 = {firstName: "Ranjan", lastName: "Fonseka", age: 30}; @@ -336,3 +394,25 @@ function testQueryExprWithLimitForStringResultV2() returns string { return outputNameString; } + +function assertEquality(any|error actual, any|error expected) { + if expected is anydata && actual is anydata && expected == actual { + return; + } + + if expected === actual { + return; + } + + string expectedValAsString = expected is error ? expected.toString() : expected.toString(); + string actualValAsString = actual is error ? actual.toString() : actual.toString(); + panic error("expected '" + expectedValAsString + "', found '" + actualValAsString + "'"); +} + +function assertTrue(any|error actual) { + assertEquality(actual, true); +} + +function assertFalse(any|error actual) { + assertEquality(actual, false); +} diff --git a/tests/jballerina-unit-test/src/test/resources/test-src/query/xml-query-expression.bal b/tests/jballerina-unit-test/src/test/resources/test-src/query/xml-query-expression.bal index f73b5bbe8576..d782871c2e15 100644 --- a/tests/jballerina-unit-test/src/test/resources/test-src/query/xml-query-expression.bal +++ b/tests/jballerina-unit-test/src/test/resources/test-src/query/xml-query-expression.bal @@ -87,6 +87,185 @@ function testSimpleQueryExprForXML3() returns xml { return finalOutput; } +type Book record {| + string title; + string author; +|}; + +class BookGenerator { + int i = 0; + + public isolated function next() returns record {|Book value;|}|error? { + self.i += 1; + if (self.i < 0) { + return error("Error"); + } else if (self.i >= 3) { + return (); + } + return { + value: { + title: "Title " + self.i.toString(), author: "Author " + self.i.toString() + } + }; + } +} + +public function testSimpleQueryExprForXML4() { + error? e = trap simpleQueryExprForXML(); + assertFalse(e is error); + + e = trap simpleQueryExprForXML2(); + assertFalse(e is error); + + e = trap simpleQueryExprForXML3(); + assertFalse(e is error); + + e = trap simpleQueryExprForXML4(); + assertFalse(e is error); + + e = trap simpleQueryExprForXML5(); + assertFalse(e is error); + + e = trap simpleQueryExprForXML6(); + assertFalse(e is error); + + e = trap simpleQueryExprForXML7(); + assertFalse(e is error); +} + +function simpleQueryExprForXML() returns error? { + stream bookStream = [{ author: "Author 1", title: "Title 1" }, + {author: "Author 2", title: "Title 2" }].toStream(); + + xml xmlValue = check from Book book in bookStream + select xml ` + ${book.author} + ${book.title} + `; + + xml expectedValue = xml ` + Author 1 + Title 1 + + Author 2 + Title 2 + `; + + assertTrue(xmlValue is xml); + assertTrue(xmlValue is xml); + assertEquality(xmlValue, expectedValue); +} + +function simpleQueryExprForXML2() returns error? { + stream bookStream = [{ author: "Author 1", title: "Title 1" }, + {author: "Author 2", title: "Title 2" }].toStream(); + + xml xmlValue = from Book book in bookStream + select xml ` + ${book.author} + ${book.title} + `; + + xml expectedValue = xml ` + Author 1 + Title 1 + + Author 2 + Title 2 + `; + + assertTrue(xmlValue is xml); + assertTrue(xmlValue is xml); + assertEquality(xmlValue, expectedValue); +} + +function simpleQueryExprForXML3() returns error? { + BookGenerator bookGenerator = new (); + stream bookStream = new (bookGenerator); + + xml xmlValue = check from Book book in bookStream + select xml ` + ${book.author} + ${book.title} + `; + + xml expectedValue = xml ` + Author 1 + Title 1 + + Author 2 + Title 2 + `; + + assertTrue(xmlValue is xml); + assertTrue(xmlValue is xml); + assertEquality(xmlValue, expectedValue); +} + +function simpleQueryExprForXML4() returns error? { + BookGenerator bookGenerator = new (); + stream bookStream = new (bookGenerator); + + xml xmlValue = check from Book book in bookStream + select xml `${book.title} - ${book.author}.`; + + xml expectedValue = xml `Title 1 - Author 1.Title 2 - Author 2.`; + + assertTrue(xmlValue is xml); + assertTrue(xmlValue is xml); + assertEquality(xmlValue.toString(), expectedValue.toString()); +} + +function simpleQueryExprForXML5() returns error? { + BookGenerator bookGenerator = new (); + stream bookStream = new (bookGenerator); + + xml xmlValue = check from Book book in bookStream + select xml ``; + + xml expectedValue = xml ``; + + assertTrue(xmlValue is xml); + assertTrue(xmlValue is xml); + assertEquality(xmlValue, expectedValue); +} + +function simpleQueryExprForXML6() returns error? { + BookGenerator bookGenerator = new (); + stream bookStream = new (bookGenerator); + + xml xmlValue = check from Book _ in bookStream + select xml ``; + + xml expectedValue = xml ``; + + assertTrue(xmlValue is xml); + assertTrue(xmlValue is xml); + assertEquality(xmlValue, expectedValue); +} + +function simpleQueryExprForXML7() returns error? { + BookGenerator bookGenerator = new (); + stream bookStream = new (bookGenerator); + + xml & readonly xmlValue = check from Book book in bookStream + select xml ` + ${book.author} + ${book.title} + `; + + xml expectedValue = xml ` + Author 1 + Title 1 + + Author 2 + Title 2 + `; + + assertTrue(xmlValue is xml & readonly); + assertEquality(xmlValue, expectedValue); +} + function testQueryExprWithLimitForXML() returns xml { xml bookStore = xml ` @@ -603,7 +782,7 @@ function testSimpleQueryExprForXMLWithReadonly1() { any _ = books1; assertEquality(books1.toString(), (xml `Sherlock Holmes`).toString()); - xml:Element & readonly books2 = from var x in book1 + xml & readonly books2 = from var x in book1 where x is xml:Element select x; any _ = books2; @@ -622,7 +801,7 @@ function testSimpleQueryExprForXMLWithReadonly1() { any _ = cmnt1; assertEquality(cmnt1.toString(), (xml ``).toString()); - xml:Comment & readonly cmnt2 = from var x in comments + xml & readonly cmnt2 = from var x in comments select x; any _ = cmnt2; assertEquality(cmnt2.toString(), (xml ``).toString()); @@ -639,7 +818,7 @@ function testSimpleQueryExprForXMLWithReadonly1() { any _ = pi1; assertEquality(pi1.toString(), (xml ``).toString()); - xml:ProcessingInstruction & readonly pi2 = from var x in processingInstructions + xml & readonly pi2 = from var x in processingInstructions select x; any _ = pi2; assertEquality(pi2.toString(), (xml ``).toString()); @@ -1270,3 +1449,11 @@ function assertEquality(any|error actual, any|error expected) { string actualValAsString = actual is error ? actual.toString() : actual.toString(); panic error("expected '" + expectedValAsString + "', found '" + actualValAsString + "'"); } + +function assertTrue(any|error actual) { + assertEquality(actual, true); +} + +function assertFalse(any|error actual) { + assertEquality(actual, false); +} From 35ec75614ab6aa67688f321ffeb8b3c19441b285 Mon Sep 17 00:00:00 2001 From: Sasindu Alahakoon Date: Mon, 3 Apr 2023 12:08:57 +0530 Subject: [PATCH 2/6] Update select type resolver func with if-else stmt --- .../compiler/desugar/QueryDesugar.java | 5 +- .../semantics/analyzer/QueryTypeChecker.java | 4 +- .../test/query/StringQueryExpressionTest.java | 12 ++- .../test/query/XMLQueryExpressionTest.java | 11 ++- .../string-query-expression-negative.bal | 49 ++++++++++++ .../query/string-query-expression.bal | 16 ++++ .../query/xml-query-expression-negative.bal | 51 ++++++++++++ .../test-src/query/xml-query-expression.bal | 77 +++++++++++++++++++ 8 files changed, 219 insertions(+), 6 deletions(-) create mode 100644 tests/jballerina-unit-test/src/test/resources/test-src/query/string-query-expression-negative.bal diff --git a/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/desugar/QueryDesugar.java b/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/desugar/QueryDesugar.java index ce8ed750702d..d9dfc97adc62 100644 --- a/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/desugar/QueryDesugar.java +++ b/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/desugar/QueryDesugar.java @@ -297,13 +297,14 @@ BLangStatementExpression desugar(BLangQueryExpr queryExpr, SymbolEnv env, onConflictExpr = null; } else { BType refType = Types.getReferredType(queryExpr.getBType()); - if (isXml(types.getSafeType(refType, true, true))) { + BType safeType = types.getSafeType(refType, true, true); + if (isXml(safeType)) { if (types.isSubTypeOfReadOnly(refType, env)) { isReadonly.value = true; } result = getStreamFunctionVariableRef(queryBlock, QUERY_TO_XML_FUNCTION, Lists.of(streamRef, isReadonly), pos); - } else if (TypeTags.isStringTypeTag(types.getSafeType(refType, true, true).tag)) { + } else if (TypeTags.isStringTypeTag(safeType.tag)) { result = getStreamFunctionVariableRef(queryBlock, QUERY_TO_STRING_FUNCTION, Lists.of(streamRef), pos); } else { BType arrayType = refType; diff --git a/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/semantics/analyzer/QueryTypeChecker.java b/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/semantics/analyzer/QueryTypeChecker.java index 5f6ad3d8a490..09cf363d5bbd 100644 --- a/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/semantics/analyzer/QueryTypeChecker.java +++ b/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/semantics/analyzer/QueryTypeChecker.java @@ -334,9 +334,9 @@ void solveSelectTypeAndResolveType(BLangQueryExpr queryExpr, BLangExpression sel selectType = checkExpr(selectExp, env, type, data); if (types.isAssignable(selectType, symTable.xmlType)) { resolvedType = getResolvedType(new BXMLType(selectType, null), type, isReadonly, env); - break; + } else { + resolvedType = selectType; } - resolvedType = selectType; break; case TypeTags.INTERSECTION: type = ((BIntersectionType) type).effectiveType; diff --git a/tests/jballerina-unit-test/src/test/java/org/ballerinalang/test/query/StringQueryExpressionTest.java b/tests/jballerina-unit-test/src/test/java/org/ballerinalang/test/query/StringQueryExpressionTest.java index 78e4f8fc9927..90c601fafe69 100644 --- a/tests/jballerina-unit-test/src/test/java/org/ballerinalang/test/query/StringQueryExpressionTest.java +++ b/tests/jballerina-unit-test/src/test/java/org/ballerinalang/test/query/StringQueryExpressionTest.java @@ -33,11 +33,12 @@ */ public class StringQueryExpressionTest { - private CompileResult result; + private CompileResult result, negativeResult; @BeforeClass public void setup() { result = BCompileUtil.compile("test-src/query/string-query-expression.bal"); + negativeResult = BCompileUtil.compile("test-src/query/string-query-expression-negative.bal"); } @Test(description = "Test simple query expression with string result") @@ -177,6 +178,15 @@ public void testQueryExprWithLimitForStringResultV2() { Assert.assertEquals(returnValues.toString(), "Ranjan John "); } + // issue - #40012 + // @Test(description = "Negative Query expr for String tests") + // public void testNegativeQueryExprForXML() { + // int index = 0; + // validateError(negativeResult, index++, "ambiguous type '[string:Char, string:Char]'", 46, 16); + // validateError(negativeResult, index++, "ambiguous type '[string:Char, string:Char, string:Char]'", 48, 16); + // Assert.assertEquals(negativeResult.getErrorCount(), index); + // } + @AfterClass public void tearDown() { result = null; diff --git a/tests/jballerina-unit-test/src/test/java/org/ballerinalang/test/query/XMLQueryExpressionTest.java b/tests/jballerina-unit-test/src/test/java/org/ballerinalang/test/query/XMLQueryExpressionTest.java index 7fdd7a227ab9..a56bcbf709c7 100644 --- a/tests/jballerina-unit-test/src/test/java/org/ballerinalang/test/query/XMLQueryExpressionTest.java +++ b/tests/jballerina-unit-test/src/test/java/org/ballerinalang/test/query/XMLQueryExpressionTest.java @@ -71,7 +71,16 @@ public void testNegativeQueryExprForXML() { validateError(negativeResult, index++, "incompatible types: expected 'xml<(xml:ProcessingInstruction & readonly)> & readonly', " + "found 'xml:ProcessingInstruction'", 51, 16); - Assert.assertEquals(negativeResult.getErrorCount(), index); + validateError(negativeResult, index++, + "incompatible types: expected '(xml:Element|error)', found '(xml|error)'", 81, 27); + // issue - #40012 + // validateError(negativeResult, index++, + // "ambiguous type '[xml:Element, xml:Element]'", 88, 16); + // validateError(negativeResult, index++, + // "incompatible types: expected 'xml:Text', found 'xml:Element'", 94, 16); + // validateError(negativeResult, index++, + // "ambiguous type '[xml:Element, xml:Element]'", 99, 16); + Assert.assertEquals(negativeResult.getErrorCount(), index + 3); } @Test(description = "Test simple query expression for XMLs - #1") diff --git a/tests/jballerina-unit-test/src/test/resources/test-src/query/string-query-expression-negative.bal b/tests/jballerina-unit-test/src/test/resources/test-src/query/string-query-expression-negative.bal new file mode 100644 index 000000000000..e37110f50de9 --- /dev/null +++ b/tests/jballerina-unit-test/src/test/resources/test-src/query/string-query-expression-negative.bal @@ -0,0 +1,49 @@ +// Copyright (c) 2023 WSO2 Inc. (http://www.wso2.org) All Rights Reserved. +// +// WSO2 Inc. 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. + +type Book record {| + string title; + string author; +|}; + +class BookGenerator { + int i = 0; + + public isolated function next() returns record {|Book value;|}|error? { + self.i += 1; + if (self.i < 0) { + return error("Error"); + } else if (self.i >= 3) { + return (); + } + return { + value: { + title: "Title " + self.i.toString(), author: "Author " + self.i.toString() + } + }; + } +} + +function testSimpleQueryExprForStringNegative() returns error? { + string:Char chr = "a"; + BookGenerator bookGenerator = new (); + stream bookStream = new (bookGenerator); + + string:Char[]|string _ = check from Book _ in bookStream + select chr; + string:Char[]|int|string _ = check from Book _ in bookStream + select chr; +} diff --git a/tests/jballerina-unit-test/src/test/resources/test-src/query/string-query-expression.bal b/tests/jballerina-unit-test/src/test/resources/test-src/query/string-query-expression.bal index 5359e1ef2500..e17cb5964dd3 100644 --- a/tests/jballerina-unit-test/src/test/resources/test-src/query/string-query-expression.bal +++ b/tests/jballerina-unit-test/src/test/resources/test-src/query/string-query-expression.bal @@ -70,6 +70,9 @@ function testSimpleQueryExprForStringResult2() { e = trap simpleQueryExprForStringResult2(); assertFalse(e is error); + + e = trap simpleQueryExprForStringResult3(); + assertFalse(e is error); } function simpleQueryExprForStringResult() returns error? { @@ -99,6 +102,19 @@ function simpleQueryExprForStringResult2() returns error? { assertEquality(strValue, expectedValue); } +function simpleQueryExprForStringResult3() returns error? { + string:Char chr = "a"; + BookGenerator bookGenerator = new (); + stream bookStream = new (bookGenerator); + + string:Char[] strValue = check from Book _ in bookStream + select chr; + + assertTrue(strValue is string:Char[]); + assertEquality(strValue[0], chr); + assertEquality(strValue[1], chr); +} + function testQueryExprWithWhereForStringResult() returns string { Person p1 = {firstName: "Alex", lastName: "George", age: 23}; Person p2 = {firstName: "Ranjan", lastName: "Fonseka", age: 30}; diff --git a/tests/jballerina-unit-test/src/test/resources/test-src/query/xml-query-expression-negative.bal b/tests/jballerina-unit-test/src/test/resources/test-src/query/xml-query-expression-negative.bal index c41fc6bd5dfc..1ce5826dd512 100644 --- a/tests/jballerina-unit-test/src/test/resources/test-src/query/xml-query-expression-negative.bal +++ b/tests/jballerina-unit-test/src/test/resources/test-src/query/xml-query-expression-negative.bal @@ -50,3 +50,54 @@ function testSimpleQueryExprForXMLWithReadonly1() { xml & readonly _ = from xml:ProcessingInstruction x in processingInstructions select x; } + +type Book record {| + string title; + string author; +|}; + +class BookGenerator { + int i = 0; + + public isolated function next() returns record {|Book value;|}|error? { + self.i += 1; + if (self.i < 0) { + return error("Error"); + } else if (self.i >= 3) { + return (); + } + return { + value: { + title: "Title " + self.i.toString(), author: "Author " + self.i.toString() + } + }; + } +} + +BookGenerator bookGenerator = new (); +stream bookStream = new (bookGenerator); + +function testSimpleQueryExprForXML() { + xml:Element _ = check from Book book in bookStream + select xml ` + ${book.author} + ${book.title} + `; + + xml:Element|xml _ = check from Book book in bookStream + select xml ` + ${book.author} + ${book.title} + `; + + xml:Text|xml _ = check from Book book in bookStream + select xml ` + ${book.author} + ${book.title} + `; + xml:Element[]|xml _ = check from Book book in bookStream + select xml ` + ${book.author} + ${book.title} + `; +} diff --git a/tests/jballerina-unit-test/src/test/resources/test-src/query/xml-query-expression.bal b/tests/jballerina-unit-test/src/test/resources/test-src/query/xml-query-expression.bal index d782871c2e15..6d363b621a0e 100644 --- a/tests/jballerina-unit-test/src/test/resources/test-src/query/xml-query-expression.bal +++ b/tests/jballerina-unit-test/src/test/resources/test-src/query/xml-query-expression.bal @@ -131,6 +131,16 @@ public function testSimpleQueryExprForXML4() { e = trap simpleQueryExprForXML7(); assertFalse(e is error); + + // issue - #40012 + // e = trap simpleQueryExprForXML8(); + // assertFalse(e is error); + + e = trap simpleQueryExprForXML9(); + assertFalse(e is error); + + e = trap simpleQueryExprForXML10(); + assertFalse(e is error); } function simpleQueryExprForXML() returns error? { @@ -266,6 +276,73 @@ function simpleQueryExprForXML7() returns error? { assertEquality(xmlValue, expectedValue); } +// issue - #40012 +// function simpleQueryExprForXML8() returns error? { +// BookGenerator bookGenerator = new (); +// stream bookStream = new (bookGenerator); + +// xml|int[] xmlValue = check from Book book in bookStream +// select xml ` +// ${book.author} +// ${book.title} +// `; + +// xml expectedValue = xml ` +// Author 1 +// Title 1 +// +// Author 2 +// Title 2 +// `; + +// assertTrue(xmlValue is xml); +// assertEquality(xmlValue, expectedValue); +// } + +function simpleQueryExprForXML9() returns error? { + BookGenerator bookGenerator = new (); + stream bookStream = new (bookGenerator); + + var xmlValue = check from Book book in bookStream + select xml ` + ${book.author} + ${book.title} + `; + + xml expectedValue = xml ` + Author 1 + Title 1 + `; + + assertTrue(xmlValue is stream); + assertEquality(( (check xmlValue.next())).value, expectedValue); +} + +function simpleQueryExprForXML10() returns error? { + BookGenerator bookGenerator = new (); + stream bookStream = new (bookGenerator); + + xml:Element[] xmlValue = check from Book book in bookStream + select xml ` + ${book.author} + ${book.title} + `; + + xml expectedValueElement1 = xml ` + Author 1 + Title 1 + `; + xml expectedValueElement2 = xml ` + Author 2 + Title 2 + `; + + assertTrue(xmlValue is xml:Element[]); + assertEquality(xmlValue.length(), 2); + assertEquality(xmlValue[0], expectedValueElement1); + assertEquality(xmlValue[1], expectedValueElement2); +} + function testQueryExprWithLimitForXML() returns xml { xml bookStore = xml ` From 33d8472f23a4b08fc4aaaf6310df019784fee05e Mon Sep 17 00:00:00 2001 From: Sasindu Alahakoon Date: Fri, 12 May 2023 02:00:12 +0530 Subject: [PATCH 3/6] Remove unnecessary newlines in string query tests --- .../test-src/query/string-query-expression.bal | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/tests/jballerina-unit-test/src/test/resources/test-src/query/string-query-expression.bal b/tests/jballerina-unit-test/src/test/resources/test-src/query/string-query-expression.bal index e17cb5964dd3..c2a8cce04547 100644 --- a/tests/jballerina-unit-test/src/test/resources/test-src/query/string-query-expression.bal +++ b/tests/jballerina-unit-test/src/test/resources/test-src/query/string-query-expression.bal @@ -79,12 +79,9 @@ function simpleQueryExprForStringResult() returns error? { string:Char chr = "a"; BookGenerator bookGenerator = new (); stream bookStream = new (bookGenerator); - string strValue = check from Book _ in bookStream select chr; - string expectedValue = "aa"; - assertTrue(strValue is string); assertEquality(strValue, expectedValue); } @@ -92,12 +89,9 @@ function simpleQueryExprForStringResult() returns error? { function simpleQueryExprForStringResult2() returns error? { stream bookStream = [{ author: "Author 1", title: "Title 1" }, {author: "Author 2", title: "Title 2" }].toStream(); - string strValue = check from Book _ in bookStream select "a"; - string expectedValue = "aa"; - assertTrue(strValue is string); assertEquality(strValue, expectedValue); } @@ -106,10 +100,8 @@ function simpleQueryExprForStringResult3() returns error? { string:Char chr = "a"; BookGenerator bookGenerator = new (); stream bookStream = new (bookGenerator); - string:Char[] strValue = check from Book _ in bookStream select chr; - assertTrue(strValue is string:Char[]); assertEquality(strValue[0], chr); assertEquality(strValue[1], chr); @@ -119,9 +111,7 @@ function testQueryExprWithWhereForStringResult() returns string { Person p1 = {firstName: "Alex", lastName: "George", age: 23}; Person p2 = {firstName: "Ranjan", lastName: "Fonseka", age: 30}; Person p3 = {firstName: "John", lastName: "David", age: 33}; - Person[] personList = [p1, p2, p3]; - string outputNameString = from var person in personList where person.age >= 30 From ae6e8eb94210f90ff83350a11e3048ce214ded76 Mon Sep 17 00:00:00 2001 From: Sasindu Alahakoon Date: Fri, 12 May 2023 10:52:13 +0530 Subject: [PATCH 4/6] Update license header in string query exp test --- .../ballerinalang/test/query/StringQueryExpressionTest.java | 1 + .../test/resources/test-src/query/string-query-expression.bal | 4 ++-- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/tests/jballerina-unit-test/src/test/java/org/ballerinalang/test/query/StringQueryExpressionTest.java b/tests/jballerina-unit-test/src/test/java/org/ballerinalang/test/query/StringQueryExpressionTest.java index 90c601fafe69..29dbf00143d2 100644 --- a/tests/jballerina-unit-test/src/test/java/org/ballerinalang/test/query/StringQueryExpressionTest.java +++ b/tests/jballerina-unit-test/src/test/java/org/ballerinalang/test/query/StringQueryExpressionTest.java @@ -190,5 +190,6 @@ public void testQueryExprWithLimitForStringResultV2() { @AfterClass public void tearDown() { result = null; + negativeResult = null; } } diff --git a/tests/jballerina-unit-test/src/test/resources/test-src/query/string-query-expression.bal b/tests/jballerina-unit-test/src/test/resources/test-src/query/string-query-expression.bal index c2a8cce04547..23cd05936c4d 100644 --- a/tests/jballerina-unit-test/src/test/resources/test-src/query/string-query-expression.bal +++ b/tests/jballerina-unit-test/src/test/resources/test-src/query/string-query-expression.bal @@ -1,6 +1,6 @@ -// Copyright (c) 2020 WSO2 Inc. (http://www.wso2.org) All Rights Reserved. +// Copyright (c) 2020 WSO2 LLC. (http://www.wso2.org) All Rights Reserved. // -// WSO2 Inc. licenses this file to you under the Apache License, +// WSO2 LLC. 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 From 8c67143d4331adfe9df493e246ef8b6b2df2d213 Mon Sep 17 00:00:00 2001 From: Sasindu Alahakoon Date: Fri, 12 May 2023 10:53:47 +0530 Subject: [PATCH 5/6] Update license heaser in string query neg tests --- .../test-src/query/string-query-expression-negative.bal | 4 ++-- .../test/resources/test-src/query/string-query-expression.bal | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/tests/jballerina-unit-test/src/test/resources/test-src/query/string-query-expression-negative.bal b/tests/jballerina-unit-test/src/test/resources/test-src/query/string-query-expression-negative.bal index e37110f50de9..9a3ab267c216 100644 --- a/tests/jballerina-unit-test/src/test/resources/test-src/query/string-query-expression-negative.bal +++ b/tests/jballerina-unit-test/src/test/resources/test-src/query/string-query-expression-negative.bal @@ -1,6 +1,6 @@ -// Copyright (c) 2023 WSO2 Inc. (http://www.wso2.org) All Rights Reserved. +// Copyright (c) 2023 WSO2 LLC. (http://www.wso2.org) All Rights Reserved. // -// WSO2 Inc. licenses this file to you under the Apache License, +// WSO2 LLC. 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 diff --git a/tests/jballerina-unit-test/src/test/resources/test-src/query/string-query-expression.bal b/tests/jballerina-unit-test/src/test/resources/test-src/query/string-query-expression.bal index 23cd05936c4d..c2a8cce04547 100644 --- a/tests/jballerina-unit-test/src/test/resources/test-src/query/string-query-expression.bal +++ b/tests/jballerina-unit-test/src/test/resources/test-src/query/string-query-expression.bal @@ -1,6 +1,6 @@ -// Copyright (c) 2020 WSO2 LLC. (http://www.wso2.org) All Rights Reserved. +// Copyright (c) 2020 WSO2 Inc. (http://www.wso2.org) All Rights Reserved. // -// WSO2 LLC. licenses this file to you under the Apache License, +// WSO2 Inc. 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 From e77b20a865c207c31635c24ba2f2660ed05ff10a Mon Sep 17 00:00:00 2001 From: SasinduDilshara Date: Tue, 13 Jun 2023 15:20:44 +0530 Subject: [PATCH 6/6] refactor xml query expression bal files --- .../src/test/resources/test-src/query/xml-query-expression.bal | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tests/jballerina-unit-test/src/test/resources/test-src/query/xml-query-expression.bal b/tests/jballerina-unit-test/src/test/resources/test-src/query/xml-query-expression.bal index 6d363b621a0e..9d641e34b018 100644 --- a/tests/jballerina-unit-test/src/test/resources/test-src/query/xml-query-expression.bal +++ b/tests/jballerina-unit-test/src/test/resources/test-src/query/xml-query-expression.bal @@ -99,7 +99,8 @@ class BookGenerator { self.i += 1; if (self.i < 0) { return error("Error"); - } else if (self.i >= 3) { + } + if (self.i >= 3) { return (); } return {