diff --git a/.github/workflows/build-with-bal-test-graalvm.yml b/.github/workflows/build-with-bal-test-graalvm.yml index 291054d..77a583e 100644 --- a/.github/workflows/build-with-bal-test-graalvm.yml +++ b/.github/workflows/build-with-bal-test-graalvm.yml @@ -35,3 +35,5 @@ jobs: lang_tag: ${{ inputs.lang_tag }} lang_version: ${{ inputs.lang_version }} native_image_options: '-J-Xmx7G ${{ inputs.native_image_options }}' + # TODO : Enable after fixing this issue : https://github.com/ballerina-platform/ballerina-lang/issues/38882 + additional_windows_build_flags: '-x test' diff --git a/.github/workflows/stale_check.yml b/.github/workflows/stale_check.yml new file mode 100644 index 0000000..8763360 --- /dev/null +++ b/.github/workflows/stale_check.yml @@ -0,0 +1,19 @@ +name: 'Close stale pull requests' + +on: + schedule: + - cron: '30 19 * * *' + workflow_dispatch: + +jobs: + stale: + runs-on: ubuntu-latest + steps: + - uses: actions/stale@v3 + with: + stale-pr-message: 'This PR has been open for more than 15 days with no activity. This will be closed in 3 days unless the `stale` label is removed or commented.' + close-pr-message: 'Closed PR due to inactivity for more than 18 days.' + days-before-pr-stale: 15 + days-before-pr-close: 3 + days-before-issue-stale: -1 + days-before-issue-close: -1 diff --git a/.vscode/launch.json b/.vscode/launch.json new file mode 100644 index 0000000..85f0dfd --- /dev/null +++ b/.vscode/launch.json @@ -0,0 +1,28 @@ +{ + "configurations": [ + { + "name": "Ballerina Debug", + "type": "ballerina", + "request": "launch", + "programArgs": [], + "commandOptions": [], + "env": {} + }, + { + "name": "Ballerina Test", + "type": "ballerina", + "request": "launch", + "debugTests": true, + "programArgs": [], + "commandOptions": [], + "env": {} + }, + { + "name": "Ballerina Remote", + "type": "ballerina", + "request": "attach", + "debuggeeHost": "127.0.0.1", + "debuggeePort": "5005" + } + ] +} \ No newline at end of file diff --git a/README.md b/README.md index ba9bc60..4021c40 100644 --- a/README.md +++ b/README.md @@ -1,455 +1 @@ # Ballerina CSV Data Library - -The Ballerina CSV Data Library is a comprehensive toolkit designed to facilitate the handling and manipulation of CSV data within Ballerina applications. It streamlines the process of converting CSV data to native Ballerina data types, enabling developers to work with CSV content seamlessly and efficiently. - -This library is the refined successor of the `ballerina/csvdata` module, incorporating enhanced functionalities and improved performance. - -## Features - -- **Versatile CSV Data Input**: Accept CSV data as a csv, a string, byte array, or a stream and convert it into a Record value. -- **CSV to Record Value Conversion**: Transform CSV data into Ballerina records with ease in compliance with OpenAPI 3 standards. -- **Projection Support**: Perform selective conversion of CSV data subsets into Record values through projection. - -## Usage - -### Converting an CSV value to a Record value - -To convert an CSV value to a Record value, you can utilize the `fromCsvWithType` function provided by the library. The example below showcases the transformation of an CSV value into a Record value. - -```ballerina -import ballerina/data.csv; -import ballerina/io; - -public function main() returns error? { - csv data = csv ` - 0 - string - string - `; - - Book book = check csvdata:fromCsvWithType(data); - io:println(book); -} - -type Book record {| - int id; - string title; - string author; -|}; -``` - -### Converting an external CSV document to a Record value - -For transforming CSV content from an external source into a Record value, the `fromCsvStringWithType` function can be used. This external source can be in the form of a string or a byte array/byte stream that houses the CSV data. This is commonly extracted from files or network sockets. The example below demonstrates the conversion of an CSV value from an external source into a Record value. - -```ballerina -import ballerina/data.csv; -import ballerina/io; - -public function main() returns error? { - string csvContent = check io:fileReadString("path/to/file.csv"); - Book book = check csvdata:fromCsvStringWithType(csvContent); - io:println(book); -} - -type Book record {| - int id; - string title; - string author; -|}; -``` - -Make sure to handle possible errors that may arise during the file reading or CSV to record conversion process. The `check` keyword is utilized to handle these errors, but more sophisticated error handling can be implemented as per your requirements. - -## CSV to Record Canonical Representation - -The translation of CSV to a Record representation is a fundamental feature of the library. It facilitates a structured and type-safe approach to handling CSV data within Ballerina applications. - -Take for instance the following CSV snippet: - -```csv - - 0 - string - string - -``` - -CSV data is inherently hierarchical, forming a tree structure. In the given example, the root element is `book`, which encompasses three child elements: `id`, `title`, and `author`. The `id` element harbors a numeric value `0`, whereas both the `title` and `author` elements contain string values. - -A straightforward record representation of the above CSV data is: - -```ballerina -type Book record {| - int id; - string title; - string author; -|}; -``` - -In this representation, the CSV data is efficiently translated into a record value. The `book` element is mapped to a record of type `Book`, and the child elements `id`, `title`, and `author` are converted into record fields of types `int` and `string` correspondingly. - -This record type definition can be further refined through annotations. Moreover, utilizing open and closed records grants control over the translation process, which is elaborated in subsequent sections. - -### CSV Element Names - -The name of the CSV element serves as the name of the record field, altered to fit a valid Ballerina identifier. Notably, the record field name corresponds to the local name of the CSV element, with any namespace prefixes being disregarded. - -Consider the CSV snippet: - -```csv - - 0 - string - string - -``` - -The canonical representation of the above CSV as a Ballerina record is: - -```ballerina -type Book record {| - int id; - string 'title\-name'; - string 'author\-name'; -|}; -``` - -Observe how the CSV element names `title-name` and `author-name` are represented using delimited identifiers in Ballerina; the `-` characters in the CSV element names are escaped using the `\` character. - -Moreover, the `@Name` annotation can be utilized to explicitly specify the name of the record field, providing control over the translation process: - -```ballerina -import ballerina/data.csv; - -type Book record {| - int id; - @csvdata:Name { value: "title-name" } - string title; - @csvdata:Name { value: "author-name" } - string author; -|}; -``` - -### CSV Attributes - -Similarly to CSV elements, CSV attributes are also represented into record fields within the corresponding parent Record type. The name of the CSV attribute is converted into the name of the record field, ensuring it is a valid Ballerina identifier. It is crucial to emphasize that the record field name aligns with the local name of the CSV attribute, and any namespace prefixes are ignored. - -Consider the following CSV snippet: - -```csv - - 0 - string - string - -``` - -The canonical representation of the above CSV as a Ballerina record is: - -```ballerina -type Book record {| - string lang; - decimal price; - int id; - string title; - string author; -|}; -``` - -Additionally the `@Attribute` annotation can be utilized to explicitly specify the name of the record field, providing control over the translation process. - -### Child Elements - -Child elements are mapped to record fields, with the type reflecting that of the corresponding child element. - -Examine the CSV snippet below: - -```csv - - 0 - string - - string - string - - -``` - -The canonical representation of the above CSV as a Ballerina record is: - -```ballerina -type Book record {| - int id; - string title; - Author author; -|}; - -type Author record {| - string name; - string country; -|}; -``` - -In this transformation, child elements, like the `author` element containing its own sub-elements, are converted into nested records. This maintains the hierarchical structure of the CSV data within the Ballerina type system, enabling intuitive and type-safe data manipulation. - -Alternatively, inline type definitions offer a compact method for representing child elements as records within their parent record. This approach is particularly beneficial when the child record does not require reuse elsewhere and is unique to its parent record. - -Consider the subsequent Ballerina record definition, which employs inline type definition for the `author` field: - -```ballerina -type Book record {| - int id; - string title; - record {| - string name; - string country; - |} author; -|}; -``` - -### CSV Text Content - -The transformation of CSV text content into record fields typically involves types like `string`, `boolean`, `int`, `float`, or `decimal`, depending on the textual content. For numeric values where type information is not explicitly defined, the default conversion type is `decimal`. Conversely, for non-numeric content, the default type is `string`. - -Consider the CSV snippet below: - -```csv - - 0 - string - string - true - 10.5 - -``` - -The translation into a Ballerina record would be as follows: - -```ballerina -type Book record {| - int id; - string title; - string author; - boolean available; - decimal price; -|}; -``` - -In scenarios where the parent CSV element of text content also includes attributes, the CSV text content can be represented by a `string` type field named `#content` within a record type, with the attributes being mapped to their respective fields. - -For instance, examine this CSV: - -```csv - - 0 - string - 10.5 - -``` - -The canonical translation of CSV to a Ballerina record is as such: - -```ballerina -type Book record {| - int id; - Title title; - decimal price; -|}; - -type Title record {| - string \#content; - string lang; -|}; -``` - -Modifications to the default behavior for converting numerical values can be achieved by providing `Options` mappings to the respective functions. This enables developers to choose specific data types and exert finer control over the conversion process. - -### CSV Namespaces - -CSV namespaces are accommodated by the library, supporting the translation of CSV data that contains namespace prefixes. However, the presence of CSV namespaces is not mandatory, and the library is capable of processing CSV data without namespaces. Should namespaces be present, they will be utilized to resolve the names of CSV elements and attributes. - -It's important to note that, unlike in the `csvdata` module, the namespace prefixes do not reflect in the record field names, as the record field names align with the local names of the CSV elements. - -Examine the CSV snippet below with default namespaces: - -```csv - - 0 - string - string - -``` - -The translation into a Ballerina record would be: - -```ballerina -type Book record {| - int id; - string title; - string author; -|}; -``` - -Incorporating namespace validation yields: - -```ballerina -import ballerina/data.csv; - -@csvdata:Namespace { - uri: "http://example.com/book" -} -type Book record {| - int id; - string title; - string author; -|}; -``` - -Here is the same CSV snippet with a namespace prefix: - -```csv - - 0 - string - string - -``` - -The translation into a Ballerina record would be: - -```ballerina -import ballerina/data.csv; - -@csvdata:Namespace { - uri: "http://example.com/book", - prefix: "bk" -} -type Book record {| - int id; - string title; - string author; -|}; -``` - -In these examples, the CSV namespaces are appropriately acknowledged, ensuring the integrity of the CSV structure within the Ballerina records. - -### Working with Arrays - -The library is equipped to handle the transformation of CSV data containing arrays into Ballerina records. - -Take the following CSV snippet as an example: - -```csv - - 0 - string - string - string - string - -``` - -The canonical representation of this CSV as a Ballerina record is: - -```ballerina -type Book record {| - int id; - string title; - string[] author; -|}; -``` - -### Controlling Which Elements to Convert - -The library allows for selective conversion of CSV elements into records through the use of rest fields. This is beneficial when the CSV data contains elements that are not necessary to be transformed into record fields. - -Take this CSV snippet as an example: - -```csv - - 0 - string - string - 10.5 - -``` - -Suppose that only the book `id`, and `title` elements are needed for conversion into record fields. This can be achieved by defining only the required fields in the record type and omitting the rest field: - -```ballerina -type Book record {| - int id; - string title; -|}; -``` - -However, if the rest field is utilized (or if the record type is defined as an open record), all elements in the CSV data will be transformed into record fields: - -```ballerina -type Book record {| - int id; - string title; -|}; -``` - -In this instance, all other elements in the CSV data, such as `author` and `price` along with their attributes, will be transformed into `string` type fields with the corresponding element name as the key. - -This behavior extends to arrays as well. - -The process of projecting CSV data into a record supports various use cases, including the filtering out of unnecessary elements. This functionality is anticipated to be enhanced in the future to accommodate more complex scenarios, such as filtering values based on regular expressions, among others. - -## Issues and projects - -Issues and Projects tabs are disabled for this repository as this is part of the Ballerina standard library. To report bugs, request new features, start new discussions, view project boards, etc. please visit Ballerina standard library [parent repository](https://github.com/ballerina-platform/ballerina-standard-library). - -This repository only contains the source code for the package. - -## Building from the source - -### Set up the prerequisites - -1. Download and install Java SE Development Kit (JDK) version 17 (from one of the following locations). - * [Oracle](https://www.oracle.com/java/technologies/downloads/) - * [OpenJDK](https://adoptium.net/) - -2. Export your GitHub personal access token with the read package permissions as follows. - - export packageUser= - export packagePAT= - -### Building the source - -Execute the commands below to build from source. - -1. To build the library: - - ./gradlew clean build - -2. Publish ZIP artifact to the local `.m2` repository: - - ./gradlew clean build publishToMavenLocal - -3. Publish the generated artifacts to the local Ballerina central repository: - - ./gradlew clean build -PpublishToLocalCentral=true - -4. Publish the generated artifacts to the Ballerina central repository: - - ./gradlew clean build -PpublishToCentral=true - -## Contributing to Ballerina - -As an open source project, Ballerina welcomes contributions from the community. - -For more information, go to the [contribution guidelines](https://github.com/ballerina-platform/ballerina-lang/blob/master/CONTRIBUTING.md). - -## Code of conduct - -All contributors are encouraged to read the [Ballerina code of conduct](https://ballerina.io/code-of-conduct). - -## Useful links - -[//]: # (* For more information go to the [`csvdata` library](https://lib.ballerina.io/ballerina/data.csv/latest).) -* Chat live with us via our [Discord server](https://discord.gg/ballerinalang). -* Post all technical questions on Stack Overflow with the [#ballerina](https://stackoverflow.com/questions/tagged/ballerina) tag. \ No newline at end of file diff --git a/ballerina-tests/build.gradle b/ballerina-tests/build.gradle new file mode 100644 index 0000000..2f401db --- /dev/null +++ b/ballerina-tests/build.gradle @@ -0,0 +1,224 @@ +/* + * Copyright (c) 2024, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. + * + * Licensed 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. + * + */ +plugins { + id 'jacoco' +} + +//apply plugin: 'java' + +import org.apache.tools.ant.taskdefs.condition.Os + +description = 'Ballerina - HTTP/WS Ballerina Tests' + +def packageName = "data.csv" +def packageOrg = "ballerina" +def tomlVersion = stripBallerinaExtensionVersion("${project.version}") +def ballerinaTomlFilePlaceHolder = new File("${project.rootDir}/build-config/resources/BallerinaTest.toml") +def testCommonTomlFilePlaceHolder = new File("${project.rootDir}/build-config/resources/CsvTestCommon.toml") +def ballerinaDist = "${project.rootDir}/target/ballerina-runtime" +def distributionBinPath = "${ballerinaDist}/bin" +def testCoverageParam = "--code-coverage --coverage-format=xml --includes=io.ballerina.stdlib.data.*:ballerina.*" +def testPackages = ["parse-string-array-types-tests", "user-config-tests", "type-compatible-tests", "unicode-tests", "constraint-validation-tests", + "parse-list-types-tests", "parse-record-types-tests", "parse-string-record-types-tests", "union-type-tests"] +def testCommonPackage = "csv-commons" + +def stripBallerinaExtensionVersion(String extVersion) { + if (extVersion.matches(project.ext.timestampedVersionRegex)) { + def splitVersion = extVersion.split('-'); + if (splitVersion.length > 3) { + def strippedValues = splitVersion[0..-4] + return strippedValues.join('-') + } else { + return extVersion + } + } else { + return extVersion.replace("${project.ext.snapshotVersion}", "") + } +} + +task clean { + delete "${project.projectDir}/${testCommonPackage}/target" + + testPackages.each { testPackage -> + delete "${project.projectDir}/${testPackage}/target" + } +} + +task updateTomlVersions { + doLast { + testPackages.each { testPackage -> + def ballerinaTomlFile = new File("${project.projectDir}/${testPackage}/Ballerina.toml") + def newBallerinaToml = ballerinaTomlFilePlaceHolder.text.replace("@project.version@", project.version) + newBallerinaToml = newBallerinaToml.replace("@toml.version@", tomlVersion) + newBallerinaToml = newBallerinaToml.replace("@test.common@", testCommonPackage.replaceAll("-", "_")) + newBallerinaToml = newBallerinaToml.replace("@package.name@", testPackage.replaceAll("-", "_")) + ballerinaTomlFile.text = newBallerinaToml + } + + def ballerinaTomlFile = new File("${project.projectDir}/${testCommonPackage}/Ballerina.toml") + def newBallerinaToml = testCommonTomlFilePlaceHolder.text.replace("@project.version@", project.version) + newBallerinaToml = newBallerinaToml.replace("@toml.version@", tomlVersion) + newBallerinaToml = newBallerinaToml.replace("@package.name@", testCommonPackage.replaceAll("-", "_")) + ballerinaTomlFile.text = newBallerinaToml + } +} + +def groupParams = "" +def disableGroups = "" +def windowsDisableGroups = "--disable-groups disabledOnWindows" +def debugParams = "" +def balJavaDebugParam = "" +def testParams = "" +def graalvmFlag = "" +def parallelTestFlag = "" +def skipTests = false + +task deleteDependencyTomlFile { + if (project.hasProperty("deleteDependencies")) { + delete "${project.projectDir}/${testCommonPackage}/Dependencies.toml" + + testPackages.each { testPackage -> + delete "${project.projectDir}/${testPackage}/Dependencies.toml" + } + } +} + +task initializeVariables { + if (project.hasProperty("groups")) { + groupParams = "--groups ${project.findProperty("groups")}" + } + if (project.hasProperty("disable")) { + disableGroups = "--disable-groups ${project.findProperty("disable")}" + } + if (project.hasProperty("debug")) { + debugParams = "--debug ${project.findProperty("debug")}" + } + if (project.hasProperty("balJavaDebug")) { + balJavaDebugParam = "BAL_JAVA_DEBUG=${project.findProperty("balJavaDebug")}" + } + if (project.hasProperty('balGraalVMTest')) { + graalvmFlag = '--graalvm' + } + if (project.hasProperty('balParallelTest')) { + parallelTestFlag = '--parallel' + } + if (project.hasProperty('balTests')) { + testPackages = project.findProperty('balTests').toString().split(",") + } + if (project.hasProperty('skipBalTests')) { + project.findProperty('skipBalTests').toString().split(",").each {testPackage -> + testPackages.remove(testPackage) + } + } + + + gradle.taskGraph.whenReady { graph -> + if (graph.hasTask(":${packageName}-ballerina-tests:test")) { + if (!project.hasProperty('balGraalVMTest')) { + testParams = "${testCoverageParam}" + } + } else { + skipTests = true + } + } +} + +task publishTestCommonPackageToLocal { + dependsOn(":${packageName}-${packageOrg}:build") + dependsOn(updateTomlVersions) + doLast { + if (!skipTests) { + exec { + workingDir "${project.projectDir}/${testCommonPackage}" + if (Os.isFamily(Os.FAMILY_WINDOWS)) { + commandLine 'cmd', '/c', "${distributionBinPath}/bal.bat pack && exit %%ERRORLEVEL%%" + } else { + commandLine 'sh', '-c', "${distributionBinPath}/bal pack" + } + } + exec { + workingDir "${project.projectDir}/${testCommonPackage}" + if (Os.isFamily(Os.FAMILY_WINDOWS)) { + commandLine 'cmd', '/c', "${distributionBinPath}/bal.bat push --repository=local" + + " && exit %%ERRORLEVEL%%" + } else { + commandLine 'sh', '-c', "${distributionBinPath}/bal push --repository=local" + } + } + } + } +} + +task ballerinaTest { + inputs.dir file(project.projectDir) + dependsOn(":${packageName}-${packageOrg}:build") + dependsOn(updateTomlVersions) + dependsOn(initializeVariables) + dependsOn(publishTestCommonPackageToLocal) + dependsOn(deleteDependencyTomlFile) + + doLast { + testPackages.each { testPackage -> + if (!skipTests) { + exec { + workingDir "${project.projectDir}/${testPackage}" + environment "JAVA_OPTS", "-DBALLERINA_DEV_COMPILE_BALLERINA_ORG=true" + if (Os.isFamily(Os.FAMILY_WINDOWS)) { + commandLine 'cmd', '/c', "${balJavaDebugParam} ${distributionBinPath}/bal.bat test ${graalvmFlag}" + + " ${parallelTestFlag} ${testParams} ${groupParams} ${disableGroups} ${windowsDisableGroups}" + + " ${debugParams} && exit %%ERRORLEVEL%%" + } else { + commandLine 'sh', '-c', "${distributionBinPath}/bal test ${graalvmFlag} ${parallelTestFlag} ${testParams}" + + " ${groupParams} ${disableGroups} ${debugParams}" + } + } + if (project.hasProperty('balGraalVMTest')) { + exec { + workingDir "${project.projectDir}/${testPackage}" + environment "JAVA_OPTS", "-DBALLERINA_DEV_COMPILE_BALLERINA_ORG=true" + if (Os.isFamily(Os.FAMILY_WINDOWS)) { + commandLine 'cmd', '/c', "${distributionBinPath}/bal.bat clean" + } else { + commandLine 'sh', '-c', "${distributionBinPath}/bal clean" + } + } + } + } + } + } +} + +publishing { + repositories { + maven { + name = "GitHubPackages" + url = uri("https://maven.pkg.github.com/ballerina-platform/module-${packageOrg}-${packageName}") + credentials { + username = System.getenv("packageUser") + password = System.getenv("packagePAT") + } + } + } +} + +task test { + dependsOn(ballerinaTest) +} + +task build { + dependsOn(test) +} diff --git a/ballerina-tests/constraint-validation-tests/.gitignore b/ballerina-tests/constraint-validation-tests/.gitignore new file mode 100644 index 0000000..d5fc29a --- /dev/null +++ b/ballerina-tests/constraint-validation-tests/.gitignore @@ -0,0 +1,11 @@ +# Ballerina generates this directory during the compilation of a package. +# It contains compiler-generated artifacts and the final executable if this is an application package. +target/ + +# Ballerina maintains the compiler-generated source code here. +# Remove this if you want to commit generated sources. +generated/ + +# Contains configuration values used during development time. +# See https://ballerina.io/learn/provide-values-to-configurable-variables/ for more details. +Config.toml diff --git a/ballerina-tests/constraint-validation-tests/Ballerina.toml b/ballerina-tests/constraint-validation-tests/Ballerina.toml new file mode 100644 index 0000000..c0b0817 --- /dev/null +++ b/ballerina-tests/constraint-validation-tests/Ballerina.toml @@ -0,0 +1,13 @@ +[package] +org = "ballerina" +name = "constraint_validation_tests" +version = "0.1.0" + +[[dependency]] +org = "ballerina" +name = "csv_commons" +repository = "local" +version = "0.1.0" + +[platform.java17] +graalvmCompatible = true diff --git a/ballerina-tests/constraint-validation-tests/Dependencies.toml b/ballerina-tests/constraint-validation-tests/Dependencies.toml new file mode 100644 index 0000000..7f54d3a --- /dev/null +++ b/ballerina-tests/constraint-validation-tests/Dependencies.toml @@ -0,0 +1,101 @@ +# AUTO-GENERATED FILE. DO NOT MODIFY. + +# This file is auto-generated by Ballerina for managing dependency versions. +# It should not be modified by hand. + +[ballerina] +dependencies-toml-version = "2" +distribution-version = "2201.9.0" + +[[package]] +org = "ballerina" +name = "constraint" +version = "1.5.0" +scope = "testOnly" +dependencies = [ + {org = "ballerina", name = "jballerina.java"} +] +modules = [ + {org = "ballerina", packageName = "constraint", moduleName = "constraint"} +] + +[[package]] +org = "ballerina" +name = "constraint_validation_tests" +version = "0.1.0" +dependencies = [ + {org = "ballerina", name = "constraint"}, + {org = "ballerina", name = "data.csv"}, + {org = "ballerina", name = "test"} +] +modules = [ + {org = "ballerina", packageName = "constraint_validation_tests", moduleName = "constraint_validation_tests"} +] + +[[package]] +org = "ballerina" +name = "data.csv" +version = "0.1.0" +scope = "testOnly" +dependencies = [ + {org = "ballerina", name = "jballerina.java"} +] +modules = [ + {org = "ballerina", packageName = "data.csv", moduleName = "data.csv"} +] + +[[package]] +org = "ballerina" +name = "jballerina.java" +version = "0.0.0" +scope = "testOnly" + +[[package]] +org = "ballerina" +name = "lang.__internal" +version = "0.0.0" +scope = "testOnly" +dependencies = [ + {org = "ballerina", name = "jballerina.java"}, + {org = "ballerina", name = "lang.object"} +] + +[[package]] +org = "ballerina" +name = "lang.array" +version = "0.0.0" +scope = "testOnly" +dependencies = [ + {org = "ballerina", name = "jballerina.java"}, + {org = "ballerina", name = "lang.__internal"} +] + +[[package]] +org = "ballerina" +name = "lang.error" +version = "0.0.0" +scope = "testOnly" +dependencies = [ + {org = "ballerina", name = "jballerina.java"} +] + +[[package]] +org = "ballerina" +name = "lang.object" +version = "0.0.0" +scope = "testOnly" + +[[package]] +org = "ballerina" +name = "test" +version = "0.0.0" +scope = "testOnly" +dependencies = [ + {org = "ballerina", name = "jballerina.java"}, + {org = "ballerina", name = "lang.array"}, + {org = "ballerina", name = "lang.error"} +] +modules = [ + {org = "ballerina", packageName = "test", moduleName = "test"} +] + diff --git a/ballerina-tests/constraint-validation-tests/tests/constraint_validation_test.bal b/ballerina-tests/constraint-validation-tests/tests/constraint_validation_test.bal new file mode 100644 index 0000000..3710770 --- /dev/null +++ b/ballerina-tests/constraint-validation-tests/tests/constraint_validation_test.bal @@ -0,0 +1,63 @@ +import ballerina/constraint; +import ballerina/data.csv as csv; +import ballerina/test; + +type ConstrainedRec record { + @constraint:Int { + minValue: 3, + maxValue: 10 + } + int a?; + @constraint:String { + minLength: 2 + } + string b; +}; + +@test:Config +function testConstraintWithRecords() returns error? { + ConstrainedRec[]|csv:Error cRec1 = csv:parseStringToRecord(string `a,b + 4,abc + 3, cde`); + test:assertEquals(cRec1, [{a: 4, b: "abc"}, {a: 3, b: "cde"}]); + + cRec1 = csv:parseStringToRecord(string `a,b + 4,abc + 11, cde`); + test:assertTrue(cRec1 is csv:Error); + test:assertTrue((cRec1).message().startsWith("Validation failed") + && (cRec1).message().includes("maxValue")); + + cRec1 = csv:parseStringToRecord(string `a,b + 4,abc + 5, "b"`, {}); + test:assertTrue(cRec1 is csv:Error); + test:assertTrue((cRec1).message().startsWith("Validation failed") + && (cRec1).message().includes("minLength")); + + cRec1 = csv:parseRecordAsRecordType([{"a": 4, "b": "abc"}, {"a": 3, "b": "cde"}], {}); + test:assertEquals(cRec1, [{a: 4, b: "abc"}, {a: 3, b: "cde"}]); + + cRec1 = csv:parseRecordAsRecordType([{"a": 4, "b": "abc"}, {"a": 11, "b": "cde"}], {}); + test:assertTrue(cRec1 is csv:Error); + test:assertTrue((cRec1).message().startsWith("Validation failed") + && (cRec1).message().includes("maxValue")); + + cRec1 = csv:parseRecordAsRecordType([{"a": 4, "b": "abc"}, {"a": 5, "b": "b"}], {}); + test:assertTrue(cRec1 is csv:Error); + test:assertTrue((cRec1).message().startsWith("Validation failed") + && (cRec1).message().includes("minLength")); + + cRec1 = csv:parseListAsRecordType([["4", "abc"], ["3", "cde"]], ["a", "b"]); + test:assertEquals(cRec1, [{a: 4, b: "abc"}, {a: 3, b: "cde"}]); + + cRec1 = csv:parseListAsRecordType([["4", "abc"], ["11", "cde"]], ["a", "b"]); + test:assertTrue(cRec1 is csv:Error); + test:assertTrue((cRec1).message().startsWith("Validation failed") + && (cRec1).message().includes("maxValue")); + + cRec1 = csv:parseListAsRecordType([["4", "abc"], ["5", "b"]], ["a", "b"]); + test:assertTrue(cRec1 is csv:Error); + test:assertTrue((cRec1).message().startsWith("Validation failed") + && (cRec1).message().includes("minLength")); +} diff --git a/ballerina-tests/csv-commons/.gitignore b/ballerina-tests/csv-commons/.gitignore new file mode 100644 index 0000000..d5fc29a --- /dev/null +++ b/ballerina-tests/csv-commons/.gitignore @@ -0,0 +1,11 @@ +# Ballerina generates this directory during the compilation of a package. +# It contains compiler-generated artifacts and the final executable if this is an application package. +target/ + +# Ballerina maintains the compiler-generated source code here. +# Remove this if you want to commit generated sources. +generated/ + +# Contains configuration values used during development time. +# See https://ballerina.io/learn/provide-values-to-configurable-variables/ for more details. +Config.toml diff --git a/ballerina-tests/csv-commons/Ballerina.toml b/ballerina-tests/csv-commons/Ballerina.toml new file mode 100644 index 0000000..0b77a15 --- /dev/null +++ b/ballerina-tests/csv-commons/Ballerina.toml @@ -0,0 +1,4 @@ +[package] +org = "ballerina" +name = "csv_commons" +version = "0.1.0" diff --git a/ballerina-tests/csv-commons/Dependencies.toml b/ballerina-tests/csv-commons/Dependencies.toml new file mode 100644 index 0000000..88bd281 --- /dev/null +++ b/ballerina-tests/csv-commons/Dependencies.toml @@ -0,0 +1,17 @@ +# AUTO-GENERATED FILE. DO NOT MODIFY. + +# This file is auto-generated by Ballerina for managing dependency versions. +# It should not be modified by hand. + +[ballerina] +dependencies-toml-version = "2" +distribution-version = "2201.9.0" + +[[package]] +org = "ballerina" +name = "csv_commons" +version = "0.1.0" +modules = [ + {org = "ballerina", packageName = "csv_commons", moduleName = "csv_commons"} +] + diff --git a/ballerina-tests/csv-commons/Package.md b/ballerina-tests/csv-commons/Package.md new file mode 100644 index 0000000..8a7ecb6 --- /dev/null +++ b/ballerina-tests/csv-commons/Package.md @@ -0,0 +1,3 @@ +## Package overview + +This package provides APIs for testing ballerina CSV data module. diff --git a/ballerina-tests/csv-commons/test_utils.bal b/ballerina-tests/csv-commons/test_utils.bal new file mode 100644 index 0000000..64123d1 --- /dev/null +++ b/ballerina-tests/csv-commons/test_utils.bal @@ -0,0 +1,23 @@ +public function generateErrorMessageForMissingRequiredField(string 'field) returns string { + return string `no matching header value is found for the required field '${'field}'`; +} + +public function generateErrorMessageForInvalidCast(string value, string 'type) returns string { + return string `value '${value}' cannot be cast into '${'type}'`; +} + +public function generateErrorMessageForInvalidFieldType(string value, string 'key) returns string { + return string `no mapping type found for value '${value}' in key '${'key}'`; +} + +public function generateErrorMessageForInvalidValueForArrayType(string value, string index, string arrayType) returns string { + return string `value '${value}' in index '${index}' is not compatible with array type '${arrayType}'`; +} + +public function generateErrorMessageForInvalidHeaders(string value, string 'type) returns string{ + return string `value '${value}' cannot be cast into '${'type}', because fields in '${'type}' or the provided expected headers are not matching with the '${value}'`; +} + +public function generateErrorMessageForInvalidCustomHeader(string header) returns string{ + return string `Invalid header value: '${header}'`; +} diff --git a/ballerina-tests/parse-list-types-tests/.gitignore b/ballerina-tests/parse-list-types-tests/.gitignore new file mode 100644 index 0000000..d5fc29a --- /dev/null +++ b/ballerina-tests/parse-list-types-tests/.gitignore @@ -0,0 +1,11 @@ +# Ballerina generates this directory during the compilation of a package. +# It contains compiler-generated artifacts and the final executable if this is an application package. +target/ + +# Ballerina maintains the compiler-generated source code here. +# Remove this if you want to commit generated sources. +generated/ + +# Contains configuration values used during development time. +# See https://ballerina.io/learn/provide-values-to-configurable-variables/ for more details. +Config.toml diff --git a/ballerina-tests/parse-list-types-tests/Ballerina.toml b/ballerina-tests/parse-list-types-tests/Ballerina.toml new file mode 100644 index 0000000..6374fc7 --- /dev/null +++ b/ballerina-tests/parse-list-types-tests/Ballerina.toml @@ -0,0 +1,13 @@ +[package] +org = "ballerina" +name = "parse_list_types_tests" +version = "0.1.0" + +[[dependency]] +org = "ballerina" +name = "csv_commons" +repository = "local" +version = "0.1.0" + +[platform.java17] +graalvmCompatible = true diff --git a/ballerina-tests/parse-list-types-tests/Dependencies.toml b/ballerina-tests/parse-list-types-tests/Dependencies.toml new file mode 100644 index 0000000..279d0c7 --- /dev/null +++ b/ballerina-tests/parse-list-types-tests/Dependencies.toml @@ -0,0 +1,98 @@ +# AUTO-GENERATED FILE. DO NOT MODIFY. + +# This file is auto-generated by Ballerina for managing dependency versions. +# It should not be modified by hand. + +[ballerina] +dependencies-toml-version = "2" +distribution-version = "2201.9.0" + +[[package]] +org = "ballerina" +name = "csv_commons" +version = "0.1.0" +scope = "testOnly" +modules = [ + {org = "ballerina", packageName = "csv_commons", moduleName = "csv_commons"} +] + +[[package]] +org = "ballerina" +name = "data.csv" +version = "0.1.0" +scope = "testOnly" +dependencies = [ + {org = "ballerina", name = "jballerina.java"} +] +modules = [ + {org = "ballerina", packageName = "data.csv", moduleName = "data.csv"} +] + +[[package]] +org = "ballerina" +name = "jballerina.java" +version = "0.0.0" +scope = "testOnly" + +[[package]] +org = "ballerina" +name = "lang.__internal" +version = "0.0.0" +scope = "testOnly" +dependencies = [ + {org = "ballerina", name = "jballerina.java"}, + {org = "ballerina", name = "lang.object"} +] + +[[package]] +org = "ballerina" +name = "lang.array" +version = "0.0.0" +scope = "testOnly" +dependencies = [ + {org = "ballerina", name = "jballerina.java"}, + {org = "ballerina", name = "lang.__internal"} +] + +[[package]] +org = "ballerina" +name = "lang.error" +version = "0.0.0" +scope = "testOnly" +dependencies = [ + {org = "ballerina", name = "jballerina.java"} +] + +[[package]] +org = "ballerina" +name = "lang.object" +version = "0.0.0" +scope = "testOnly" + +[[package]] +org = "ballerina" +name = "parse_list_types_tests" +version = "0.1.0" +dependencies = [ + {org = "ballerina", name = "csv_commons"}, + {org = "ballerina", name = "data.csv"}, + {org = "ballerina", name = "test"} +] +modules = [ + {org = "ballerina", packageName = "parse_list_types_tests", moduleName = "parse_list_types_tests"} +] + +[[package]] +org = "ballerina" +name = "test" +version = "0.0.0" +scope = "testOnly" +dependencies = [ + {org = "ballerina", name = "jballerina.java"}, + {org = "ballerina", name = "lang.array"}, + {org = "ballerina", name = "lang.error"} +] +modules = [ + {org = "ballerina", packageName = "test", moduleName = "test"} +] + diff --git a/ballerina-tests/parse-list-types-tests/tests/parse_list_type_as_list_test.bal b/ballerina-tests/parse-list-types-tests/tests/parse_list_type_as_list_test.bal new file mode 100644 index 0000000..f3ef889 --- /dev/null +++ b/ballerina-tests/parse-list-types-tests/tests/parse_list_type_as_list_test.bal @@ -0,0 +1,416 @@ +import ballerina/csv_commons as common; +import ballerina/data.csv as csv; +import ballerina/test; + +@test:Config +function testFromCsvWithTypeForTupleAndTupleAsExpectedType() { + StringTuple1Array|csv:Error st1st1 = csv:parseListAsListType([st1, st1], {}, StringTuple1Array); + test:assertEquals(st1st1, [ + [s1, s2, "", ""], + [s1, s2, "", ""] + ]); + + StringTuple1Array|csv:Error st2st1 = csv:parseListAsListType([st2, st2], {}, StringTuple1Array); + test:assertEquals(st2st1, [ + [s1, s2, s3, s2], + [s1, s2, s3, s2] + ]); + + StringTuple1Array|csv:Error st3st1 = csv:parseListAsListType([st3, st3], {}, StringTuple1Array); + test:assertEquals(st3st1, [ + [s1, s2, "", ""], + [s1, s2, "", ""] + ]); + + StringTuple1Array|csv:Error st4st1 = csv:parseListAsListType([st4, st4], {}, StringTuple1Array); + test:assertEquals(st4st1, [ + [s1, s2, s3, s2], + [s1, s2, s3, s2] + ]); + + StringTuple2Array|csv:Error st1st2 = csv:parseListAsListType([st1, st1], {}, StringTuple2Array); + test:assertEquals(st1st2, [ + [s1, s2], + [s1, s2] + ]); + + StringTuple2Array|csv:Error st2st2 = csv:parseListAsListType([st2, st2], {}, StringTuple2Array); + test:assertEquals(st2st2, [ + [s1, s2], + [s1, s2] + ]); + + StringTuple2Array|csv:Error st3st2 = csv:parseListAsListType([st3, st3], {}, StringTuple2Array); + test:assertEquals(st3st2, [ + [s1, s2], + [s1, s2] + ]); + + StringTuple2Array|csv:Error st4st2 = csv:parseListAsListType([st4, st4], {}, StringTuple2Array); + test:assertEquals(st4st2, [ + [s1, s2], + [s1, s2] + ]); + + StringTuple3Array|csv:Error st1st3 = csv:parseListAsListType([st1, st1], {}, StringTuple3Array); + test:assertEquals(st1st3, [ + [s1, s2], + [s1, s2] + ]); + + StringTuple3Array|csv:Error st2st3 = csv:parseListAsListType([st2, st2], {}, StringTuple3Array); + test:assertEquals(st2st3, [ + [s1, s2, s3, s2], + [s1, s2, s3, s2] + ]); + + StringTuple3Array|csv:Error st3st3 = csv:parseListAsListType([st3, st3], {}, StringTuple3Array); + test:assertEquals(st3st3, [ + [s1, s2], + [s1, s2] + ]); + + StringTuple3Array|csv:Error st4st3 = csv:parseListAsListType([st4, st4], {}, StringTuple3Array); + test:assertEquals(st4st3, [ + [s1, s2, s3, s2], + [s1, s2, s3, s2] + ]); +} + +@test:Config +function testFromCsvWithTypeForTupleAndTupleAsExpectedType2() { + StringTuple4Array|csv:Error st1st4 = csv:parseListAsListType([st1, st1], {}, StringTuple4Array); + test:assertEquals(st1st4, [ + [s1, s2], + [s1, s2] + ]); + + StringTuple4Array|csv:Error st2st4 = csv:parseListAsListType([st2, st2], {}, StringTuple4Array); + test:assertEquals(st2st4, [ + [s1, s2, s3, s2], + [s1, s2, s3, s2] + ]); + + StringTuple4Array|csv:Error st3st4 = csv:parseListAsListType([st3, st3], {}, StringTuple4Array); + test:assertEquals(st3st4, [ + [s1, s2], + [s1, s2] + ]); + + StringTuple4Array|csv:Error st4st4 = csv:parseListAsListType([st4, st4], {}, StringTuple4Array); + test:assertEquals(st4st4, [ + [s1, s2, s3, s2], + [s1, s2, s3, s2] + ]); + + AnydataTuple3Array|csv:Error st1anydt3 = csv:parseListAsListType([st1, st1], {}, AnydataTuple3Array); + test:assertEquals(st1anydt3, [ + [s1, s2], + [s1, s2] + ]); + + AnydataTuple3Array|csv:Error st2anydt3 = csv:parseListAsListType([st2, st2], {}, AnydataTuple3Array); + test:assertEquals(st2anydt3, [ + [s1, s2, s3, s2], + [s1, s2, s3, s2] + ]); + + AnydataTuple3Array|csv:Error st3anydt3 = csv:parseListAsListType([st3, st3], {}, AnydataTuple3Array); + test:assertEquals(st3anydt3, [ + [s1, s2], + [s1, s2] + ]); + + AnydataTuple3Array|csv:Error st4anydt3 = csv:parseListAsListType([st4, st4], {}, AnydataTuple3Array); + test:assertEquals(st4anydt3, [ + [s1, s2, s3, s2], + [s1, s2, s3, s2] + ]); + + JsonTuple3Array|csv:Error st1jt3 = csv:parseListAsListType([st1, st1], {}, JsonTuple3Array); + test:assertEquals(st1jt3, [ + [s1, s2], + [s1, s2] + ]); + + JsonTuple3Array|csv:Error st2jt3 = csv:parseListAsListType([st2, st2], {}, JsonTuple3Array); + test:assertEquals(st2jt3, [ + [s1, s2, s3, s2], + [s1, s2, s3, s2] + ]); + + JsonTuple3Array|csv:Error st3jt3 = csv:parseListAsListType([st3, st3], {}, JsonTuple3Array); + test:assertEquals(st3jt3, [ + [s1, s2], + [s1, s2] + ]); + + JsonTuple3Array|csv:Error st4jt3 = csv:parseListAsListType([st4, st4], {}, JsonTuple3Array); + test:assertEquals(st4jt3, [ + [s1, s2, s3, s2], + [s1, s2, s3, s2] + ]); + + DecimalTuple4Array|csv:Error st1dta = csv:parseListAsListType([st1, st1], {}, DecimalTuple4Array); + test:assertTrue(st1dta is csv:Error); + test:assertEquals((st1dta).message(), common:generateErrorMessageForInvalidValueForArrayType("string", "0", "decimal")); + + IntegerTuple3Array|csv:Error st2bta = csv:parseListAsListType([st2, st2], {}, IntegerTuple3Array); + test:assertTrue(st2bta is csv:Error); + test:assertEquals((st2bta).message(), common:generateErrorMessageForInvalidValueForArrayType("string", "0", "int")); + + NilTuple3Array|csv:Error st3nta = csv:parseListAsListType([st3, st3], {}, NilTuple3Array); + test:assertTrue(st3nta is csv:Error); + test:assertEquals((st3nta).message(), common:generateErrorMessageForInvalidValueForArrayType("string", "0", "()")); + + BooleanTuple4Array|csv:Error st4bta = csv:parseListAsListType([st4, st4], {}, BooleanTuple4Array); + test:assertTrue(st4bta is csv:Error); + test:assertEquals((st4bta).message(), common:generateErrorMessageForInvalidValueForArrayType("string", "0", "boolean")); +} + +@test:Config +function testFromCsvWithTypeForTupleAndTupleAsExpectedType3() { + [string, boolean, int][]|csv:Error ct1bt4 = csv:parseListAsListType([["a", "true", "1"], ["a", "true", "1"]], {}); + test:assertEquals(ct1bt4, [ + ["a", true, 1], + ["a", true, 1] + ]); + + [(), float, decimal, boolean, int, string][]|csv:Error ct1bt6 = csv:parseListAsListType( + [["null", "2.23", "0", "true", "1", "a"], ["null", "0", "2.23", "true", "1", "a"]]); + test:assertEquals(ct1bt6, [ + [(), 2.23, 0, true, 1, "a"], + [(), 0, 2.23, true, 1, "a"] + ]); + + [decimal, boolean, int, string][]|csv:Error ct1bt7 = csv:parseListAsListType( + [["0", "true", "1", "a"], ["2.23", "true", "1", "a"]]); + test:assertEquals(ct1bt7, [ + [0, true, 1, "a"], + [2.23, true, 1, "a"] + ]); + + [decimal, boolean, int, string, anydata...][]|csv:Error ct1bt8 = csv:parseListAsListType( + [["0", "true", "1", "a", "null", "2.23"], ["2.23", "true", "1", "a", "null", "0"]]); + test:assertEquals(ct1bt8, [ + [0, true, 1, "a", (), 2.23], + [2.23, true, 1, "a", (), 0] + ]); + + [(), float, decimal, boolean, int, string, string...][]|csv:Error ct1bt9 = csv:parseListAsListType( + [["null", "2.23", "0", "true", "1", "a"], ["null", "0", "2.23", "true", "1", "a"]]); + test:assertEquals(ct1bt9, [ + [(), 2.23, 0, true, 1, "a"], + [(), 0, 2.23, true, 1, "a"] + ]); + + [decimal, boolean, int, string, string...][]|csv:Error ct1bt10 = csv:parseListAsListType( + [["0", "true", "1", "a", "null", "2.23"], ["2.23", "true", "1", "a", "null", "0"]]); + test:assertEquals(ct1bt10, [ + [0, true, 1, "a", "null", "2.23"], + [2.23, true, 1, "a", "null", "0"] + ]); + + [decimal, boolean, int, string, ()...][]|csv:Error ct1bt11 = csv:parseListAsListType( + [["null", "2.23", "0", "true", "1", "a"], ["null", "0", "2.23", "true", "1", "a"]]); + test:assertTrue(ct1bt11 is csv:Error); + //TODO: Fix the message + test:assertEquals((ct1bt11).message(), common:generateErrorMessageForInvalidValueForArrayType("null", "0", "decimal")); + + [(), decimal, float, boolean, ()...][]|csv:Error ct1bt11_2 = csv:parseListAsListType( + [["null", "2.23", "0", "true", "1", "a"], ["null", "0", "2.23", "true", "1", "a"]]); + test:assertTrue(ct1bt11_2 is csv:Error); + test:assertEquals((ct1bt11_2).message(), common:generateErrorMessageForInvalidValueForArrayType("1", "4", "()")); + + [()...][]|csv:Error ct1bt12 = csv:parseListAsListType( + [["null", "2.23", "0", "true", "1", "a"], ["null", "0", "2.23", "true", "1", "a"]]); + test:assertTrue(ct1bt12 is csv:Error); + test:assertEquals((ct1bt12).message(), common:generateErrorMessageForInvalidValueForArrayType("2.23", "1", "()")); + + [string...][]|csv:Error ct1bt13 = csv:parseListAsListType( + [["1", "a"], ["1", "a"]]); + test:assertEquals(ct1bt13, [ + ["1", "a"], + ["1", "a"] + ]); + + [boolean...][]|csv:Error ct1bt14 = csv:parseListAsListType( + [["2.23", "null"], ["7", "()"]]); + test:assertTrue(ct1bt14 is csv:Error); + test:assertEquals((ct1bt14).message(), common:generateErrorMessageForInvalidValueForArrayType("2.23", "0", "boolean")); + + int?[][]|csv:Error ct1bt15 = csv:parseListAsListType( + [["1", "()"], ["1", "2"]]); + test:assertEquals(ct1bt15, [ + [1, ()], + [1, 2] + ]); + + int[][]|csv:Error ct1bt16 = csv:parseListAsListType( + [["1", "2"], ["1", "()"]]); + test:assertTrue(ct1bt16 is csv:Error); + test:assertEquals((ct1bt16).message(), common:generateErrorMessageForInvalidValueForArrayType("()", "1", "int")); + + int[][]|csv:Error ct1bt17 = csv:parseListAsListType( + [["a", "b"], ["a", "b"]]); + test:assertTrue(ct1bt17 is csv:Error); + test:assertEquals((ct1bt17).message(), common:generateErrorMessageForInvalidValueForArrayType("a", "0", "int")); +} + +@test:Config +function testFromCsvWithTypeForTupleAndArrayAsExpectedType() { + StringArrayArray|csv:Error st1saa = csv:parseListAsListType([st1, st1], {}, StringArrayArray); + test:assertEquals(st1saa, [ + [s1, s2], + [s1, s2] + ]); + + StringArrayArray|csv:Error st2saa = csv:parseListAsListType([st2, st2], {}, StringArrayArray); + test:assertEquals(st2saa, [ + [s1, s2, s3, s2], + [s1, s2, s3, s2] + ]); + + StringArrayArray|csv:Error st3saa = csv:parseListAsListType([st3, st3], {}, StringArrayArray); + test:assertEquals(st3saa, [ + [s1, s2], + [s1, s2] + ]); + + StringArrayArray|csv:Error st4saa = csv:parseListAsListType([st4, st4], {}, StringArrayArray); + test:assertEquals(st4saa, [ + [s1, s2, s3, s2], + [s1, s2, s3, s2] + ]); + + NillableStringArrayArray|csv:Error st1nsaa = csv:parseListAsListType([st1, st1], {}, NillableStringArrayArray); + test:assertEquals(st1nsaa, [ + [s1, s2], + [s1, s2] + ]); + + NillableStringArrayArray|csv:Error st2nsaa = csv:parseListAsListType([st2, st2], {}, NillableStringArrayArray); + test:assertEquals(st2nsaa, [ + [s1, s2, s3, s2], + [s1, s2, s3, s2] + ]); + + NillableStringArrayArray|csv:Error st3nsaa = csv:parseListAsListType([st3, st3], {}, NillableStringArrayArray); + test:assertEquals(st3nsaa, [ + [s1, s2], + [s1, s2] + ]); + + NillableStringArrayArray|csv:Error st4nsaa = csv:parseListAsListType([st4, st4], {}, NillableStringArrayArray); + test:assertEquals(st4nsaa, [ + [s1, s2, s3, s2], + [s1, s2, s3, s2] + ]); + + NillableIntOrUnionStringArrayArray|csv:Error st1nsuiaa = csv:parseListAsListType([st1, st1], {}, NillableIntOrUnionStringArrayArray); + test:assertEquals(st1nsuiaa, [ + [s1, s2], + [s1, s2] + ]); +} + +@test:Config +function testFromCsvWithTypeForTupleAndTupleAsExpectedType4() { + NillableIntOrUnionStringArrayArray|csv:Error st2nsuiaa = csv:parseListAsListType([st2, st2], {}, NillableIntOrUnionStringArrayArray); + test:assertEquals(st2nsuiaa, [ + [s1, s2, s3, s2], + [s1, s2, s3, s2] + ]); + + NillableIntOrUnionStringArrayArray|csv:Error st3nsuiaa = csv:parseListAsListType([st3, st3], {}, NillableIntOrUnionStringArrayArray); + test:assertEquals(st3nsuiaa, [ + [s1, s2], + [s1, s2] + ]); + + NillableIntOrUnionStringArrayArray|csv:Error st4nsuiaa = csv:parseListAsListType([st4, st4], {}, NillableIntOrUnionStringArrayArray); + test:assertEquals(st4nsuiaa, [ + [s1, s2, s3, s2], + [s1, s2, s3, s2] + ]); + + StringArray2Array|csv:Error st1saa2 = csv:parseListAsListType([st1, st1], {}, StringArray2Array); + test:assertEquals(st1saa2, [ + [s1, s2], + [s1, s2] + ]); + + StringArray2Array|csv:Error st2saa2 = csv:parseListAsListType([st2, st2], {}, StringArray2Array); + test:assertEquals(st2saa2, [ + [s1, s2], + [s1, s2] + ]); + + StringArray2Array|csv:Error st3saa2 = csv:parseListAsListType([st3, st3], {}, StringArray2Array); + test:assertEquals(st3saa2, [ + [s1, s2], + [s1, s2] + ]); + + StringArray2Array|csv:Error st4saa2 = csv:parseListAsListType([st4, st4], {}, StringArray2Array); + test:assertEquals(st4saa2, [ + [s1, s2], + [s1, s2] + ]); + + JsonArray1Array|csv:Error st1jaa = csv:parseListAsListType([st1, st1], {}, JsonArray1Array); + test:assertEquals(st1jaa, [ + [s1, s2], + [s1, s2] + ]); + + JsonArray1Array|csv:Error st2jaa = csv:parseListAsListType([st2, st2], {}, JsonArray1Array); + test:assertEquals(st2jaa, [ + [s1, s2, s3, s2], + [s1, s2, s3, s2] + ]); + + JsonArray1Array|csv:Error st3jaa = csv:parseListAsListType([st3, st3], {}, JsonArray1Array); + test:assertEquals(st3jaa, [ + [s1, s2], + [s1, s2] + ]); + + JsonArray1Array|csv:Error st4jaa = csv:parseListAsListType([st4, st4], {}, JsonArray1Array); + test:assertEquals(st4jaa, [ + [s1, s2, s3, s2], + [s1, s2, s3, s2] + ]); + + AnydataArray1Array|csv:Error st1anyda = csv:parseListAsListType([st1, st1], {}, AnydataArray1Array); + test:assertEquals(st1anyda, [ + [s1, s2], + [s1, s2] + ]); + + AnydataArray1Array|csv:Error st2anyda = csv:parseListAsListType([st2, st2], {}, AnydataArray1Array); + test:assertEquals(st2anyda, [ + [s1, s2, s3, s2], + [s1, s2, s3, s2] + ]); + + AnydataArray1Array|csv:Error st3anyda = csv:parseListAsListType([st3, st3], {}, AnydataArray1Array); + test:assertEquals(st3anyda, [ + [s1, s2], + [s1, s2] + ]); + + AnydataArray1Array|csv:Error st4anyda = csv:parseListAsListType([st4, st4], {}, AnydataArray1Array); + test:assertEquals(st4anyda, [ + [s1, s2, s3, s2], + [s1, s2, s3, s2] + ]); + + DecimalArray1Array|csv:Error st1dda = csv:parseListAsListType([st1, st1], {}, DecimalArray1Array); + test:assertTrue(st1dda is csv:Error); + test:assertEquals((st1dda).message(), common:generateErrorMessageForInvalidValueForArrayType("string", "0", "decimal")); + + DecimalArray1Array|csv:Error st3dda = csv:parseListAsListType([st3, st3], {}, DecimalArray1Array); + test:assertTrue(st3dda is csv:Error); + test:assertEquals((st3dda).message(), common:generateErrorMessageForInvalidValueForArrayType("string", "0", "decimal")); +} diff --git a/ballerina-tests/parse-list-types-tests/tests/parse_list_type_as_record_test.bal b/ballerina-tests/parse-list-types-tests/tests/parse_list_type_as_record_test.bal new file mode 100644 index 0000000..751e756 --- /dev/null +++ b/ballerina-tests/parse-list-types-tests/tests/parse_list_type_as_record_test.bal @@ -0,0 +1,768 @@ +import ballerina/csv_commons as common; +import ballerina/data.csv as csv; +import ballerina/test; + +@test:Config +function testFromCsvWithTypeForTupleAndRecordAsExpectedType() { + StringRecord1Array|csv:Error st1sr1 = csv:parseListAsRecordType([st1, st1], (), {}, StringRecord1Array); + test:assertTrue(st1sr1 is csv:Error); + test:assertEquals((st1sr1).message(), common:generateErrorMessageForMissingRequiredField("s3")); + + StringRecord1Array|csv:Error st2sr1 = csv:parseListAsRecordType([st2, st2], (), {}, StringRecord1Array); + test:assertTrue(st2sr1 is csv:Error); + test:assertEquals((st2sr1).message(), common:generateErrorMessageForMissingRequiredField("s3")); + + StringRecord2Array|csv:Error st1sr2 = csv:parseListAsRecordType([st1, st1], (), {}, StringRecord2Array); + test:assertTrue(st1sr2 is csv:Error); + test:assertEquals((st1sr2).message(), common:generateErrorMessageForInvalidHeaders("[\"string\",\"\"]", "parse_list_types_tests:StringRecord2")); + + StringRecord2Array|csv:Error st2sr2 = csv:parseListAsRecordType([st2, st2], (), {}, StringRecord2Array); + test:assertTrue(st2sr2 is csv:Error); + test:assertEquals((st2sr2).message(), common:generateErrorMessageForInvalidHeaders("[\"string\",\"\",\"a\",\"\"]","parse_list_types_tests:StringRecord2")); + + StringRecord9Array|csv:Error st1sr9 = csv:parseListAsRecordType([st1, st1], (), {}, StringRecord9Array); + test:assertTrue(st1sr9 is csv:Error); + test:assertEquals((st1sr9).message(), common:generateErrorMessageForInvalidHeaders("[\"string\",\"\"]", "parse_list_types_tests:StringRecord9")); + + StringRecord9Array|csv:Error st2sr9 = csv:parseListAsRecordType([st2, st2], (), {}, StringRecord9Array); + test:assertTrue(st2sr9 is csv:Error); + test:assertEquals((st2sr9).message(), common:generateErrorMessageForInvalidHeaders("[\"string\",\"\",\"a\",\"\"]","parse_list_types_tests:StringRecord9")); + + StringRecord10Array|csv:Error st1sr10 = csv:parseListAsRecordType([st1, st1], (), {}, StringRecord10Array); + test:assertEquals(st1sr10, [ + {'1: "string", '2: ""}, + {'1: "string", '2: ""} + ]); + + StringRecord10Array|csv:Error st2sr10 = csv:parseListAsRecordType([st2, st2], (), {}, StringRecord10Array); + test:assertEquals(st2sr10, [ + {'1: "string", '2: "", '3: "a", '4: ""}, + {'1: "string", '2: "", '3: "a", '4: ""} + ]); + + StringRecord19Array|csv:Error st1sr19 = csv:parseListAsRecordType([st1, st1], (), {}, StringRecord19Array); + test:assertEquals(st1sr19, [ + {s1: "", s2: "", "1": s1, "2": s2}, + {s1: "", s2: "", "1": s1, "2": s2} + ]); + + StringRecord19Array|csv:Error st2sr19 = csv:parseListAsRecordType([st2, st2], (), {}, StringRecord19Array); + test:assertEquals(st2sr19, [ + {s1: "", s2: "", '1: s1, '2: s2, '3: s3, '4: s2}, + {s1: "", s2: "", '1: s1, '2: s2, '3: s3, '4: s2} + ]); + + StringRecord20Array|csv:Error st1sr20 = csv:parseListAsRecordType([st1, st1], (), {}, StringRecord20Array); + test:assertEquals(st1sr20, [ + {s1: "", s2: ""}, + {s1: "", s2: ""} + ]); +} + +@test:Config +function testFromCsvWithTypeForTupleAndRecordAsExpectedType2() { + StringRecord20Array|csv:Error st2sr20 = csv:parseListAsRecordType([st2, st2], (), {}, StringRecord20Array); + test:assertEquals(st2sr20, [ + {s1: "", s2: ""}, + {s1: "", s2: ""} + ]); + + StringRecord21Array|csv:Error st1sr21 = csv:parseListAsRecordType([st1, st1], (), {}, StringRecord21Array); + test:assertEquals(st1sr21, [ + {"1": s1, "2": s2}, + {"1": s1, "2": s2} + ]); + + StringRecord21Array|csv:Error st2sr21 = csv:parseListAsRecordType([st2, st2], (), {}, StringRecord21Array); + test:assertEquals(st2sr21, [ + {'1: s1, '2: s2, '3: s3, '4: s2}, + {'1: s1, '2: s2, '3: s3, '4: s2} + ]); + + StringRecord22Array|csv:Error st1sr22 = csv:parseListAsRecordType([st1, st1], (), {}, StringRecord22Array); + test:assertEquals(st1sr22, [ + {s1: "", s2: "", "1": s1, "2": s2}, + {s1: "", s2: "", "1": s1, "2": s2} + ]); + + StringRecord22Array|csv:Error st2sr22 = csv:parseListAsRecordType([st2, st2], (), {}, StringRecord22Array); + test:assertEquals(st2sr22, [ + {s1: "", s2: "", '1: s1, '2: s2, '3: s3, '4: s2}, + {s1: "", s2: "", '1: s1, '2: s2, '3: s3, '4: s2} + ]); + + StringRecord23Array|csv:Error st1sr23 = csv:parseListAsRecordType([st1, st1], (), {}, StringRecord23Array); + test:assertEquals(st1sr23, [ + {"1": s1, "2": s2}, + {"1": s1, "2": s2} + ]); + + StringRecord23Array|csv:Error st2sr23 = csv:parseListAsRecordType([st2, st2], (), {}, StringRecord23Array); + test:assertEquals(st2sr23, [ + {'1: s1, '2: s2, '3: s3, '4: s2}, + {'1: s1, '2: s2, '3: s3, '4: s2} + ]); + + CustomRecord15Array|csv:Error st1cr15 = csv:parseListAsRecordType([st1, st1], (), {}, CustomRecord15Array); + test:assertEquals(st1cr15, [ + {"1": s1, "2": s2}, + {"1": s1, "2": s2} + ]); + + CustomRecord15Array|csv:Error st2cr15 = csv:parseListAsRecordType([st2, st2], (), {}, CustomRecord15Array); + test:assertEquals(st2cr15, [ + {"1": s1, "2": s2}, + {"1": s1, "2": s2} + ]); + + CustomRecord16Array|csv:Error st1cr16 = csv:parseListAsRecordType([st1, st1], (), {}, CustomRecord16Array); + test:assertTrue(st1cr16 is csv:Error); + test:assertEquals((st1cr16).message(), common:generateErrorMessageForMissingRequiredField("3")); + + CustomRecord16Array|csv:Error st2cr16 = csv:parseListAsRecordType([st2, st2], (), {}, CustomRecord16Array); + test:assertEquals(st2cr16, [ + {'1: s1, '2: s2, '3: s3, '4: s2}, + {'1: s1, '2: s2, '3: s3, '4: s2} + ]); + + CustomRecord17Array|csv:Error st1cr17 = csv:parseListAsRecordType([st1, st1], (), {}, CustomRecord17Array); + test:assertEquals(st1cr17, [ + {"1": s1, "2": s2}, + {"1": s1, "2": s2} + ]); +} + +@test:Config +function testFromCsvWithTypeForTupleAndRecordAsExpectedType3() { + CustomRecord17Array|csv:Error st2cr17 = csv:parseListAsRecordType([st2, st2], (), {}, CustomRecord17Array); + test:assertEquals(st2cr17, [ + {'1: s1, '2: s2, '3: s3, '4: s2}, + {'1: s1, '2: s2, '3: s3, '4: s2} + ]); + + CustomRecord18Array|csv:Error st1cr18 = csv:parseListAsRecordType([st1, st1], (), {}, CustomRecord18Array); + test:assertTrue(st1cr18 is csv:Error); + test:assertEquals((st1cr18).message(), common:generateErrorMessageForMissingRequiredField("3")); + + CustomRecord18Array|csv:Error st2cr18 = csv:parseListAsRecordType([st2, st2], (), {}, CustomRecord18Array); + test:assertEquals(st2cr18, [ + {'1: s1, '2: s2, '3: s3, '4: s2}, + {'1: s1, '2: s2, '3: s3, '4: s2} + ]); + + CustomRecord19Array|csv:Error st1cr19 = csv:parseListAsRecordType([st1, st1], (), {}, CustomRecord19Array); + test:assertEquals(st1cr19, [ + {'1: s1, '2: s2, '3: "", '4: ""}, + {'1: s1, '2: s2, '3: "", '4: ""} + ]); + + CustomRecord19Array|csv:Error st2cr19 = csv:parseListAsRecordType([st2, st2], (), {}, CustomRecord19Array); + test:assertEquals(st2cr19, [ + {'1: s1, '2: s2, '3: s3, '4: s2}, + {'1: s1, '2: s2, '3: s3, '4: s2} + ]); + + CustomRecord20Array|csv:Error st1cr20 = csv:parseListAsRecordType([st1, st1], (), {}, CustomRecord20Array); + test:assertEquals(st1cr20, [ + {"1": s1, "2": s2}, + {"1": s1, "2": s2} + ]); + + CustomRecord20Array|csv:Error st2cr20 = csv:parseListAsRecordType([st2, st2], (), {}, CustomRecord20Array); + test:assertEquals(st2cr20, [ + {'1: s1, '2: s2, '3: s3, '4: s2}, + {'1: s1, '2: s2, '3: s3, '4: s2} + ]); + + CustomRecord21Array|csv:Error st1cr21 = csv:parseListAsRecordType([st1, st1], (), {}, CustomRecord21Array); + test:assertEquals(st1cr21, [ + {"1": s1, "2": s2}, + {"1": s1, "2": s2} + ]); + + CustomRecord21Array|csv:Error st2cr21 = csv:parseListAsRecordType([st2, st2], (), {}, CustomRecord21Array); + test:assertEquals(st2cr21, [ + {'1: s1, '2: s2, '3: s3, '4: s2}, + {'1: s1, '2: s2, '3: s3, '4: s2} + ]); + + CustomRecord22Array|csv:Error st1cr22 = csv:parseListAsRecordType([st1, st1], (), {}, CustomRecord22Array); + test:assertEquals(st1cr22, [ + {"1": s1, "2": s2}, + {"1": s1, "2": s2} + ]); +} + +@test:Config +function testFromCsvWithTypeForTupleAndRecordAsExpectedType4() { + CustomRecord22Array|csv:Error st2cr22 = csv:parseListAsRecordType([st2, st2], (), {}, CustomRecord22Array); + test:assertEquals(st2cr22, [ + {'1: s1, '2: s2, '3: s3, '4: s2}, + {'1: s1, '2: s2, '3: s3, '4: s2} + ]); + + CustomRecord23Array|csv:Error st1cr23 = csv:parseListAsRecordType([st1, st1], (), {}, CustomRecord23Array); + test:assertEquals(st1cr23, [ + {"1": s1, "2": s2, a: ""}, + {"1": s1, "2": s2, a: ""} + ]); + + CustomRecord23Array|csv:Error st2cr23 = csv:parseListAsRecordType([st2, st2], (), {}, CustomRecord23Array); + test:assertEquals(st2cr23, [ + {'1: s1, '2: s2, '3: s3, '4: s2, a: ""}, + {'1: s1, '2: s2, '3: s3, '4: s2, a: ""} + ]); + + CustomRecord24Array|csv:Error st1cr24 = csv:parseListAsRecordType([st1, st1], (), {}, CustomRecord24Array); + test:assertEquals(st1cr24, [ + {"1": s1, "2": s2}, + {"1": s1, "2": s2} + ]); + + CustomRecord24Array|csv:Error st2cr24 = csv:parseListAsRecordType([st2, st2], (), {}, CustomRecord24Array); + test:assertEquals(st2cr24, [ + {'1: s1, '2: s2, '3: s3, '4: s2}, + {'1: s1, '2: s2, '3: s3, '4: s2} + ]); + + CustomRecord25Array|csv:Error st1cr25 = csv:parseListAsRecordType([st1, st1], (), {}, CustomRecord25Array); + test:assertTrue(st1cr25 is csv:Error); + test:assertEquals((st1cr25).message(), common:generateErrorMessageForInvalidFieldType("string", "1")); + + CustomRecord25Array|csv:Error st2cr25 = csv:parseListAsRecordType([st2, st2], (), {}, CustomRecord25Array); + test:assertTrue(st2cr25 is csv:Error); + test:assertEquals((st2cr25).message(), common:generateErrorMessageForInvalidFieldType("string", "1")); + + CustomRecord25Array|csv:Error st3cr25 = csv:parseListAsRecordType([st3, st3], (), {}, CustomRecord25Array); + test:assertTrue(st3cr25 is csv:Error); + test:assertEquals((st3cr25).message(), common:generateErrorMessageForInvalidFieldType("string", "1")); + + CustomRecord25Array|csv:Error st4cr25 = csv:parseListAsRecordType([st4, st4], (), {}, CustomRecord25Array); + test:assertTrue(st4cr25 is csv:Error); + test:assertEquals((st4cr25).message(), common:generateErrorMessageForInvalidFieldType("string", "1")); + + CustomRecord26Array|csv:Error st1cr26 = csv:parseListAsRecordType([st1, st1], (), {}, CustomRecord26Array); + test:assertEquals(st1cr26 , [ + {'1: s1}, + {'1: s1} + ]); + + CustomRecord26Array|csv:Error st2cr26 = csv:parseListAsRecordType([st2, st2], (), {}, CustomRecord26Array); + test:assertEquals(st2cr26 , [ + {'1: s1}, + {'1: s1} + ]); + + CustomRecord26Array|csv:Error st3cr26 = csv:parseListAsRecordType([st3, st3], (), {}, CustomRecord26Array); + test:assertEquals(st3cr26 , [ + {'1: s1}, + {'1: s1} + ]); + + CustomRecord26Array|csv:Error st4cr26 = csv:parseListAsRecordType([st4, st4], (), {}, CustomRecord26Array); + test:assertEquals(st4cr26 , [ + {'1: s1}, + {'1: s1} + ]); +} + +@test:Config +function testFromCsvWithTypeForTupleAndRecordAsExpectedType5() { + StringRecord1Array|csv:Error st3sr1 = csv:parseListAsRecordType([st3, st3], (), {}, StringRecord1Array); + test:assertTrue(st3sr1 is csv:Error); + test:assertEquals((st3sr1).message(), common:generateErrorMessageForMissingRequiredField("s3")); + + StringRecord1Array|csv:Error st4sr1 = csv:parseListAsRecordType([st4, st4], (), {}, StringRecord1Array); + test:assertTrue(st4sr1 is csv:Error); + test:assertEquals((st4sr1).message(), common:generateErrorMessageForMissingRequiredField("s3")); + + StringRecord2Array|csv:Error st3sr2 = csv:parseListAsRecordType([st3, st3], (), {}, StringRecord2Array); + test:assertTrue(st3sr2 is csv:Error); + test:assertEquals((st3sr2).message(), common:generateErrorMessageForInvalidHeaders("[\"string\",\"\"]", "parse_list_types_tests:StringRecord2")); + + StringRecord2Array|csv:Error st4sr2 = csv:parseListAsRecordType([st4, st4], (), {}, StringRecord2Array); + test:assertTrue(st4sr2 is csv:Error); + test:assertEquals((st4sr2).message(), common:generateErrorMessageForInvalidHeaders("[\"string\",\"\",\"a\",\"\"]","parse_list_types_tests:StringRecord2")); + + StringRecord9Array|csv:Error st3sr9 = csv:parseListAsRecordType([st3, st3], (), {}, StringRecord9Array); + test:assertTrue(st3sr9 is csv:Error); + test:assertEquals((st3sr9).message(), common:generateErrorMessageForMissingRequiredField("s1")); + + StringRecord9Array|csv:Error st4sr9 = csv:parseListAsRecordType([st4, st4], (), {}, StringRecord9Array); + test:assertTrue(st4sr9 is csv:Error); + test:assertEquals((st4sr9).message(), common:generateErrorMessageForMissingRequiredField("s1")); + + StringRecord10Array|csv:Error st3sr10 = csv:parseListAsRecordType([st3, st3], (), {}, StringRecord10Array); + test:assertEquals(st3sr10, [ + {'1: "string", '2: ""}, + {'1: "string", '2: ""} + ]); + + StringRecord10Array|csv:Error st4sr10 = csv:parseListAsRecordType([st4, st4], (), {}, StringRecord10Array); + test:assertEquals(st4sr10, [ + {'1: "string", '2: "", '3: "a", '4: ""}, + {'1: "string", '2: "", '3: "a", '4: ""} + ]); + + StringRecord19Array|csv:Error st3sr19 = csv:parseListAsRecordType([st3, st3], (), {}, StringRecord19Array); + test:assertEquals(st3sr19, [ + {s1: "", s2: "", "1": s1, "2": s2}, + {s1: "", s2: "", "1": s1, "2": s2} + ]); + + StringRecord19Array|csv:Error st4sr19 = csv:parseListAsRecordType([st4, st4], (), {}, StringRecord19Array); + test:assertEquals(st4sr19, [ + {s1: "", s2: "", '1: s1, '2: s2, '3: s3, '4: s2}, + {s1: "", s2: "", '1: s1, '2: s2, '3: s3, '4: s2} + ]); + + StringRecord20Array|csv:Error st3sr20 = csv:parseListAsRecordType([st3, st3], (), {}, StringRecord20Array); + test:assertEquals(st3sr20, [ + {s1: "", s2: ""}, + {s1: "", s2: ""} + ]); + + StringRecord20Array|csv:Error st4sr20 = csv:parseListAsRecordType([st4, st4], (), {}, StringRecord20Array); + test:assertEquals(st4sr20, [ + {s1: "", s2: ""}, + {s1: "", s2: ""} + ]); + + StringRecord21Array|csv:Error st3sr21 = csv:parseListAsRecordType([st3, st3], (), {}, StringRecord21Array); + test:assertEquals(st3sr21, [ + {"1": s1, "2": s2}, + {"1": s1, "2": s2} + ]); + + StringRecord21Array|csv:Error st4sr21 = csv:parseListAsRecordType([st4, st4], (), {}, StringRecord21Array); + test:assertEquals(st4sr21, [ + {'1: s1, '2: s2, '3: s3, '4: s2}, + {'1: s1, '2: s2, '3: s3, '4: s2} + ]); + + StringRecord22Array|csv:Error st3sr22 = csv:parseListAsRecordType([st3, st3], (), {}, StringRecord22Array); + test:assertEquals(st3sr22, [ + {s1: "", s2: "", "1": s1, "2": s2}, + {s1: "", s2: "", "1": s1, "2": s2} + ]); + + StringRecord22Array|csv:Error st4sr22 = csv:parseListAsRecordType([st4, st4], (), {}, StringRecord22Array); + test:assertEquals(st4sr22, [ + {s1: "", s2: "", '1: s1, '2: s2, '3: s3, '4: s2}, + {s1: "", s2: "", '1: s1, '2: s2, '3: s3, '4: s2} + ]); + + StringRecord23Array|csv:Error st3sr23 = csv:parseListAsRecordType([st3, st3], (), {}, StringRecord23Array); + test:assertEquals(st3sr23, [ + {"1": s1, "2": s2}, + {"1": s1, "2": s2} + ]); + + StringRecord23Array|csv:Error st4sr23 = csv:parseListAsRecordType([st4, st4], (), {}, StringRecord23Array); + test:assertEquals(st4sr23, [ + {'1: s1, '2: s2, '3: s3, '4: s2}, + {'1: s1, '2: s2, '3: s3, '4: s2} + ]); + + CustomRecord15Array|csv:Error st3cr15 = csv:parseListAsRecordType([st3, st3], (), {}, CustomRecord15Array); + test:assertEquals(st3cr15, [ + {"1": s1, "2": s2}, + {"1": s1, "2": s2} + ]); +} + +@test:Config +function testFromCsvWithTypeForTupleAndRecordAsExpectedType6() { + CustomRecord15Array|csv:Error st4cr15 = csv:parseListAsRecordType([st4, st4], (), {}, CustomRecord15Array); + test:assertEquals(st4cr15, [ + {"1": s1, "2": s2}, + {"1": s1, "2": s2} + ]); + + CustomRecord16Array|csv:Error st3cr16 = csv:parseListAsRecordType([st3, st3], (), {}, CustomRecord16Array); + test:assertTrue(st3cr16 is csv:Error); + test:assertEquals((st3cr16).message(), common:generateErrorMessageForMissingRequiredField("3")); + + CustomRecord16Array|csv:Error st4cr16 = csv:parseListAsRecordType([st4, st4], (), {}, CustomRecord16Array); + test:assertEquals(st4cr16, [ + {'1: s1, '2: s2, '3: s3, '4: s2}, + {'1: s1, '2: s2, '3: s3, '4: s2} + ]); + + CustomRecord17Array|csv:Error st3cr17 = csv:parseListAsRecordType([st3, st3], (), {}, CustomRecord17Array); + test:assertEquals(st3cr17, [ + {"1": s1, "2": s2}, + {"1": s1, "2": s2} + ]); + + CustomRecord17Array|csv:Error st4cr17 = csv:parseListAsRecordType([st4, st4], (), {}, CustomRecord17Array); + test:assertEquals(st4cr17, [ + {'1: s1, '2: s2, '3: s3, '4: s2}, + {'1: s1, '2: s2, '3: s3, '4: s2} + ]); + + CustomRecord18Array|csv:Error st3cr18 = csv:parseListAsRecordType([st3, st3], (), {}, CustomRecord18Array); + test:assertTrue(st3cr18 is csv:Error); + test:assertEquals((st3cr18).message(), common:generateErrorMessageForMissingRequiredField("3")); + + CustomRecord18Array|csv:Error st4cr18 = csv:parseListAsRecordType([st4, st4], (), {}, CustomRecord18Array); + test:assertEquals(st4cr18, [ + {'1: s1, '2: s2, '3: s3, '4: s2}, + {'1: s1, '2: s2, '3: s3, '4: s2} + ]); + + CustomRecord19Array|csv:Error st3cr19 = csv:parseListAsRecordType([st3, st3], (), {}, CustomRecord19Array); + test:assertEquals(st3cr19, [ + {'1: s1, '2: s2, '3: "", '4: ""}, + {'1: s1, '2: s2, '3: "", '4: ""} + ]); + + CustomRecord19Array|csv:Error st4cr19 = csv:parseListAsRecordType([st4, st4], (), {}, CustomRecord19Array); + test:assertEquals(st4cr19, [ + {'1: s1, '2: s2, '3: s3, '4: s2}, + {'1: s1, '2: s2, '3: s3, '4: s2} + ]); + + CustomRecord20Array|csv:Error st3cr20 = csv:parseListAsRecordType([st3, st3], (), {}, CustomRecord20Array); + test:assertEquals(st3cr20, [ + {"1": s1, "2": s2}, + {"1": s1, "2": s2} + ]); + + CustomRecord20Array|csv:Error st4cr20 = csv:parseListAsRecordType([st4, st4], (), {}, CustomRecord20Array); + test:assertEquals(st4cr20, [ + {'1: s1, '2: s2, '3: s3, '4: s2}, + {'1: s1, '2: s2, '3: s3, '4: s2} + ]); + + CustomRecord21Array|csv:Error st3cr21 = csv:parseListAsRecordType([st3, st3], (), {}, CustomRecord21Array); + test:assertEquals(st3cr21, [ + {"1": s1, "2": s2}, + {"1": s1, "2": s2} + ]); + + CustomRecord21Array|csv:Error st4cr21 = csv:parseListAsRecordType([st4, st4], (), {}, CustomRecord21Array); + test:assertEquals(st4cr21, [ + {'1: s1, '2: s2, '3: s3, '4: s2}, + {'1: s1, '2: s2, '3: s3, '4: s2} + ]); + + CustomRecord22Array|csv:Error st3cr22 = csv:parseListAsRecordType([st3, st3], (), {}, CustomRecord22Array); + test:assertEquals(st3cr22, [ + {"1": s1, "2": s2}, + {"1": s1, "2": s2} + ]); + + CustomRecord22Array|csv:Error st4cr22 = csv:parseListAsRecordType([st4, st4], (), {}, CustomRecord22Array); + test:assertEquals(st4cr22, [ + {'1: s1, '2: s2, '3: s3, '4: s2}, + {'1: s1, '2: s2, '3: s3, '4: s2} + ]); + + CustomRecord23Array|csv:Error st3cr23 = csv:parseListAsRecordType([st3, st3], (), {}, CustomRecord23Array); + test:assertEquals(st3cr23, [ + {"1": s1, "2": s2, a: ""}, + {"1": s1, "2": s2, a: ""} + ]); + + CustomRecord23Array|csv:Error st4cr23 = csv:parseListAsRecordType([st4, st4], (), {}, CustomRecord23Array); + test:assertEquals(st4cr23, [ + {'1: s1, '2: s2, '3: s3, '4: s2, a: ""}, + {'1: s1, '2: s2, '3: s3, '4: s2, a: ""} + ]); + + CustomRecord24Array|csv:Error st3cr24 = csv:parseListAsRecordType([st3, st3], (), {}, CustomRecord24Array); + test:assertEquals(st3cr24, [ + {"1": s1, "2": s2}, + {"1": s1, "2": s2} + ]); + + CustomRecord24Array|csv:Error st4cr24 = csv:parseListAsRecordType([st4, st4], (), {}, CustomRecord24Array); + test:assertEquals(st4cr24, [ + {'1: s1, '2: s2, '3: s3, '4: s2}, + {'1: s1, '2: s2, '3: s3, '4: s2} + ]); +} + +@test:Config +function testFromCsvWithTypeForTupleAndRecordAsExpectedType7() { + record{string a; boolean b; int c;}[]|csv:Error ct1br4 = csv:parseListAsRecordType([["a", "1", "true"], ["a", "1", "true"]], ["a", "c", "b"], {}); + test:assertEquals(ct1br4, [ + {a: "a", b: true, c: 1}, + {a: "a", b: true, c: 1} + ]); + + record{() a; float b; decimal c; boolean d; int e; string f;}[]|csv:Error ct1br6 = csv:parseListAsRecordType( + [["a", "1", "true", "0", "2.23", "null"], ["a", "1", "true", "2.23", "0", "()"]], + ["f", "e", "d", "c", "b", "a"]); + test:assertEquals(ct1br6, [ + {a: (), b: 2.23, c: 0, d: true, e: 1, f: "a"}, + {a: (), b: 0, c: 2.23, d: true, e: 1, f: "a"} + ]); + + record{|decimal c; boolean d; int e; string f;|}[]|csv:Error ct1br7 = csv:parseListAsRecordType( + [["a", "1", "true", "0", "2.23", "null"], ["a", "1", "true", "2.23", "0", "()"]], + ["f", "e", "d", "c", "b", "a"]); + test:assertEquals(ct1br7, [ + {c: 0, d: true, e: 1, f: "a"}, + {c: 2.23, d: true, e: 1, f: "a"} + ]); + + record{decimal c; boolean d; int e; string f;}[]|csv:Error ct1br8 = csv:parseListAsRecordType( + [["a", "1", "true", "0", "2.23", "null"], ["a", "1", "true", "2.23", "0", "()"]], + ["f", "e", "d", "c", "b", "a"]); + test:assertEquals(ct1br8, [ + {a: (), b: 2.23, c: 0, d: true, e: 1, f: "a"}, + {a: (), b: 0, c: 2.23, d: true, e: 1, f: "a"} + ]); + + record{|int|() a; float b; decimal? c; boolean d; int e; string f; string...;|}[]|csv:Error ct1br9 = csv:parseListAsRecordType( + [["a", "1", "true", "0", "2.23", "null"], ["a", "1", "true", "2.23", "0", "()"]], + ["f", "e", "d", "c", "b", "a"]); + test:assertEquals(ct1br9, [ + {a: (), b: 2.23, c: 0, d: true, e: 1, f: "a"}, + {a: (), b: 0, c: 2.23, d: true, e: 1, f: "a"} + ]); + + record{|int|() a; float b; decimal? c; string|boolean d; int|string e; string f; string...;|}[]|csv:Error ct1br9_2 = csv:parseListAsRecordType( + [["a", "1", "true", "0", "2.23", "null"], ["a", "1", "true", "2.23", "0", "()"]], + ["f", "e", "d", "c", "b", "a"]); + test:assertEquals(ct1br9_2, [ + {a: (), b: 2.23, c: 0, d: true, e: 1, f: "a"}, + {a: (), b: 0, c: 2.23, d: true, e: 1, f: "a"} + ]); +} + +@test:Config +function testFromCsvWithTypeForTupleAndRecordAsExpectedType8() { + record{|decimal c; boolean|string d; int e; string f; string...;|}[]|csv:Error ct1br10 = csv:parseListAsRecordType( + [["a", "1", "true", "0", "2.23", "null"], ["a", "1", "true", "2.23", "0", "()"]], + ["f", "e", "d", "c", "b", "a"]); + test:assertEquals(ct1br10, [ + {a: "null", b: "2.23", c: 0, d: true, e: 1, f: "a"}, + {a: "()", b: "0", c: 2.23, d: true, e: 1, f: "a"} + ]); + + record{|decimal? c; boolean d; int? e; string f; ()...;|}[]|csv:Error ct1br11 = csv:parseListAsRecordType( + [["a", "1", "true", "0", "2.23", "null"], ["a", "1", "true", "2.23", "0", "()"]], + ["f", "e", "d", "c", "b", "a"]); + test:assertEquals(ct1br11, [ + {a: (), c: 0, d: true, e: 1, f: "a"}, + {a: (), c: 2.23, d: true, e: 1, f: "a"} + ]); + + record{|()...;|}[]|csv:Error ct1br12 = csv:parseListAsRecordType( + [["a", "1", "true", "0", "2.23", "null"], ["a", "1", "true", "2.23", "0", "()"]], + ["f", "e", "d", "c", "b", "a"]); + test:assertEquals(ct1br12, [ + {a: ()}, + {a: ()} + ]); + + record{|string?...;|}[]|csv:Error ct1br13 = csv:parseListAsRecordType( + [["a", "1"], ["a", "1"]], + ["f", "e"]); + test:assertEquals(ct1br13, [ + {e: "1", f: "a"}, + {e: "1", f: "a"} + ]); + + record{|boolean...;|}[]|csv:Error ct1br14 = csv:parseListAsRecordType( + [["2.23", "null"], ["7", "()"]], + ["b", "a"]); + test:assertEquals(ct1br14, [ + {}, + {} + ]); + + map[]|csv:Error ct1br15 = csv:parseListAsRecordType( + [["2", "()"], ["2", "1"], ["()", "2"]], + ["f", "e"]); + test:assertEquals(ct1br15, [ + {e: (), f: 2}, + {e: 1, f: 2}, + {e: 2, f: ()} + ]); + + record{|boolean...;|}[]|csv:Error ct1br16 = csv:parseListAsRecordType( + [["2.23", "null"], ["7", "()"]], + ["b", "a"]); + test:assertEquals(ct1br16, [ + {}, + {} + ]); +} + +@test:Config +function testFromCsvWithTypeForTupleAndMapAsExpectedType() { + StringMapArray|csv:Error st1sma = csv:parseListAsRecordType([st1, st1], (), {}, StringMapArray); + test:assertEquals(st1sma , [ + {'1: s1, '2: s2}, + {'1: s1, '2: s2} + ]); + + StringMapArray|csv:Error st2sma = csv:parseListAsRecordType([st2, st2], (), {}, StringMapArray); + test:assertEquals(st2sma , [ + {'1: s1, '2: s2, '3: s3, '4: s2}, + {'1: s1, '2: s2, '3: s3, '4: s2} + ]); + + StringMapArray|csv:Error st3sma = csv:parseListAsRecordType([st3, st3], (), {}, StringMapArray); + test:assertEquals(st3sma , [ + {'1: s1, '2: s2}, + {'1: s1, '2: s2} + ]); + + StringMapArray|csv:Error st4sma = csv:parseListAsRecordType([st4, st4], (), {}, StringMapArray); + test:assertEquals(st4sma , [ + {'1: s1, '2: s2, '3: s3, '4: s2}, + {'1: s1, '2: s2, '3: s3, '4: s2} + ]); + + NillableIntUnionStringMapArray|csv:Error st1niusma = csv:parseListAsRecordType([st1, st1], (), {}, NillableIntUnionStringMapArray); + test:assertEquals(st1niusma , [ + {'1: s1, '2: s2}, + {'1: s1, '2: s2} + ]); + + NillableIntUnionStringMapArray|csv:Error st2niusma = csv:parseListAsRecordType([st2, st2], (), {}, NillableIntUnionStringMapArray); + test:assertEquals(st2niusma , [ + {'1: s1, '2: s2, '3: s3, '4: s2}, + {'1: s1, '2: s2, '3: s3, '4: s2} + ]); + + NillableIntUnionStringMapArray|csv:Error st3niusma = csv:parseListAsRecordType([st3, st3], (), {}, NillableIntUnionStringMapArray); + test:assertEquals(st3niusma , [ + {'1: s1, '2: s2}, + {'1: s1, '2: s2} + ]); + + NillableIntUnionStringMapArray|csv:Error st4niusma = csv:parseListAsRecordType([st4, st4], (), {}, NillableIntUnionStringMapArray); + test:assertEquals(st4niusma , [ + {'1: s1, '2: s2, '3: s3, '4: s2}, + {'1: s1, '2: s2, '3: s3, '4: s2} + ]); + + IntUnionStringMapArray|csv:Error st1iusma = csv:parseListAsRecordType([st1, st1], (), {}, IntUnionStringMapArray); + test:assertEquals(st1iusma , [ + {'1: s1, '2: s2}, + {'1: s1, '2: s2} + ]); + + IntUnionStringMapArray|csv:Error st2iusma = csv:parseListAsRecordType([st2, st2], (), {}, IntUnionStringMapArray); + test:assertEquals(st2iusma , [ + {'1: s1, '2: s2, '3: s3, '4: s2}, + {'1: s1, '2: s2, '3: s3, '4: s2} + ]); + + IntUnionStringMapArray|csv:Error st3iusma = csv:parseListAsRecordType([st3, st3], (), {}, IntUnionStringMapArray); + test:assertEquals(st3iusma , [ + {'1: s1, '2: s2}, + {'1: s1, '2: s2} + ]); + + IntUnionStringMapArray|csv:Error st4iusma = csv:parseListAsRecordType([st4, st4], (), {}, IntUnionStringMapArray); + test:assertEquals(st4iusma , [ + {'1: s1, '2: s2, '3: s3, '4: s2}, + {'1: s1, '2: s2, '3: s3, '4: s2} + ]); + + JsonMapArray|csv:Error st1jma = csv:parseListAsRecordType([st1, st1], (), {}, JsonMapArray); + test:assertEquals(st1jma , [ + {'1: s1, '2: s2}, + {'1: s1, '2: s2} + ]); +} + +@test:Config +function testFromCsvWithTypeForTupleAndMapAsExpectedType2() { + JsonMapArray|csv:Error st2jma = csv:parseListAsRecordType([st2, st2], (), {}, JsonMapArray); + test:assertEquals(st2jma , [ + {'1: s1, '2: s2, '3: s3, '4: s2}, + {'1: s1, '2: s2, '3: s3, '4: s2} + ]); + + JsonMapArray|csv:Error st3jma = csv:parseListAsRecordType([st3, st3], (), {}, JsonMapArray); + test:assertEquals(st3jma , [ + {'1: s1, '2: s2}, + {'1: s1, '2: s2} + ]); + + JsonMapArray|csv:Error st4jma = csv:parseListAsRecordType([st4, st4], (), {}, JsonMapArray); + test:assertEquals(st4jma , [ + {'1: s1, '2: s2, '3: s3, '4: s2}, + {'1: s1, '2: s2, '3: s3, '4: s2} + ]); + + AnydataMapArray|csv:Error st1anydma = csv:parseListAsRecordType([st1, st1], (), {}, AnydataMapArray); + test:assertEquals(st1anydma , [ + {'1: s1, '2: s2}, + {'1: s1, '2: s2} + ]); + + AnydataMapArray|csv:Error st2anydma = csv:parseListAsRecordType([st2, st2], (), {}, AnydataMapArray); + test:assertEquals(st2anydma , [ + {'1: s1, '2: s2, '3: s3, '4: s2}, + {'1: s1, '2: s2, '3: s3, '4: s2} + ]); + + AnydataMapArray|csv:Error st3anydma = csv:parseListAsRecordType([st3, st3], (), {}, AnydataMapArray); + test:assertEquals(st3anydma , [ + {'1: s1, '2: s2}, + {'1: s1, '2: s2} + ]); + + AnydataMapArray|csv:Error st4anydma = csv:parseListAsRecordType([st4, st4], (), {}, AnydataMapArray); + test:assertEquals(st4anydma , [ + {'1: s1, '2: s2, '3: s3, '4: s2}, + {'1: s1, '2: s2, '3: s3, '4: s2} + ]); + + CustomMapArray|csv:Error st1cma = csv:parseListAsRecordType([st1, st1], (), {}, CustomMapArray); + test:assertEquals(st1cma , [ + {'1: s1, '2: s2}, + {'1: s1, '2: s2} + ]); + + CustomMapArray|csv:Error st2cma = csv:parseListAsRecordType([st2, st2], (), {}, CustomMapArray); + test:assertEquals(st2cma , [ + {'1: s1, '2: s2, '3: s3, '4: s2}, + {'1: s1, '2: s2, '3: s3, '4: s2} + ]); + + CustomMapArray|csv:Error st3cma = csv:parseListAsRecordType([st3, st3], (), {}, CustomMapArray); + test:assertEquals(st3cma , [ + {'1: s1, '2: s2}, + {'1: s1, '2: s2} + ]); + + CustomMapArray|csv:Error st4cma = csv:parseListAsRecordType([st4, st4], (), {}, CustomMapArray); + test:assertEquals(st4cma , [ + {'1: s1, '2: s2, '3: s3, '4: s2}, + {'1: s1, '2: s2, '3: s3, '4: s2} + ]); + + NilMapArray|csv:Error st1nma = csv:parseListAsRecordType([st1, st1], (), {}, NilMapArray); + test:assertEquals(st1nma, ([ + {}, + {} + ])); + + IntegerMapArray|csv:Error st2ima = csv:parseListAsRecordType([st2, st2], (), {}, IntegerMapArray); + test:assertEquals(st2ima, ([ + {}, + {} + ])); + + DecimalMapArray|csv:Error st3dma = csv:parseListAsRecordType([st3, st3], (), {}, DecimalMapArray); + test:assertEquals(st3dma, ([ + {}, + {} + ])); + + BooleanMapArray|csv:Error st4bma = csv:parseListAsRecordType([st4, st4], (), {}, BooleanMapArray); + test:assertEquals(st4bma, ([ + {}, + {} + ])); +} diff --git a/ballerina-tests/parse-list-types-tests/tests/test_data_values.bal b/ballerina-tests/parse-list-types-tests/tests/test_data_values.bal new file mode 100644 index 0000000..360a493 --- /dev/null +++ b/ballerina-tests/parse-list-types-tests/tests/test_data_values.bal @@ -0,0 +1,256 @@ +boolean b1 = true; +false b2 = false; +boolean? b3 = (); +boolean|int b4 = false; + +() n1 = (); +int? n2 = (); +() n3 = null; + +int i1 = 1; +int i2 = -2; +int i3 = int:MAX_VALUE; +int i4 = int:MIN_VALUE; +int i5 = 0; +2 i6 = 2; +int? i7 = (); +int|string i8 = 100; + +float f1 = 2.234; +float f2 = -3.21f; +float f3 = 0; +float f4 = float:Infinity; +float f5 = -float:Infinity; +float f6 = float:NaN; +2.3f f7 = 2.3; +float? f8 = (); +float|decimal f9 = 1.21; + +decimal d1 = 2.234; +decimal d2 = -3.21d; +decimal d3 = 0; +2.3d d4 = 2.3; +decimal? d5 = (); +decimal|int d6 = 1.21; + +string s1 = "string"; +string s2 = ""; +string:Char s3 = "a"; + +map bm1 = {b1, b2}; +map bm2 = {b1, b2, b3, n1, n3}; +map bm3 = {b1, b2, b3, b4, i1}; +map<()> bm4 = {n1, n3}; +map bm5 = {b1, b2, b3, b4:true}; + +map m5 = {i1, i2, i3, i4, i5, i6}; +map m6 = {f1, f2, f3, f4, f5, f6, f7}; +map m7 = {d1, d2, d3, d4}; +map m8 = {d1, f1, f9, f10: 1.23}; +map m9 = {s1, s2, s3}; +map m10 = {b1, b2, b3, b4, n1, n2, n3, i1, i2, i3, i4, i5, i6, i7, i8, f1, f2, f3, f4, f5, f6, f7, f8}; +map m11 = {b1, b2, b3, b4, n1, n2, n3, i1, i2, i3, i4, i5, i6, i7, i8, f1, f2, f3, f4, f5, f6, f7, f8}; + +boolean[] arr1 = [b1, b2]; +boolean?[] arr2 = [b1, b2, b3, n1, n3]; +(boolean|int?)[] arr3 = [b1, b2, b3, b4, i1]; +()[] arr4 = [n1, n3]; +int[] arr5 = [i1, i2, i3, i4, i5, i6]; +float[] arr6 = [f1, f2, f3, f4, f5, f6, f7]; +decimal[] arr7 = [d1, d2, d3, d4]; +(decimal|float)[] arr8 = [d1, f1, f9, 1.23]; +string[] arr9 = [s1, s2, s3]; +anydata[] arr10 = [b1, b2, b3, b4, n1, n2, n3, i1, i2, i3, i4, i5, i6, i7, i8, f1, f2, f3, f4, f5, f6, f7, f8]; +json[] arr11 = [b1, b2, b3, b4, n1, n2, n3, i1, i2, i3, i4, i5, i6, i7, i8, f1, f2, f3, f4, f5, f6, f7, f8]; + +[boolean, boolean] bt1 = [b1, b2]; +[boolean, boolean, boolean, boolean] bt2 = [b1, b2, b1, b2]; +[boolean?, boolean?, boolean?, boolean?, boolean?] bt3 = [b1, b2, b3, n1, n3]; +[boolean|int?, boolean|int?, boolean|int?, boolean|int?, boolean|int?] bt4 = [b1, b2, b3, b4, i1]; +[boolean...] bt5 = [b1, b2]; + +[string, string] st1 = [s1, s2]; +[string, string, string, string] st2 = [s1, s2, s3, s2]; +[string...] st3 = [s1, s2]; +[string, string, string...] st4 = [s1, s2, s3, s2]; + +[string?, string?, string?, string?, string?] st5 = [s1, s2, s3, n1, n3]; +[string|int?, string|int?, string|int?, string|int?, string|int?] st6 = [s1, s2, s3, n1, i1]; +[string?...] st7 = [s1, s2]; +[string...] st8 = []; +[string, string, string] st9 = [s1, s2, s3]; + +[(), ()] tup4 = [n1, n3]; +[int, int, int, int, int, int] tup5 = [i1, i2, i3, i4, i5, i6]; +[float, float, float, float, float, float, float] tup6 = [f1, f2, f3, f4, f5, f6, f7]; +[decimal, decimal, decimal, decimal] tup7 = [d1, d2, d3, d4]; +[decimal|float, decimal|float, decimal|float, decimal|float] tup8 = [d1, f1, f9, 1.23]; +[string, string, string] tup9 = [s1, s2, s3]; +[anydata, anydata, anydata, anydata, anydata, anydata, anydata, anydata, + anydata, anydata, anydata, anydata, anydata, anydata, anydata, anydata, + anydata, anydata, anydata, anydata, anydata, anydata, anydata] tup10 = [b1, b2, b3, b4, + n1, n2, n3, i1, i2, i3, i4, i5, i6, i7, i8, f1, f2, f3, f4, f5, f6, f7, f8]; +[json, json, json, json, json, json, json, json, json, json, json, json, + json, json, json, json, json, json, json, json, json, json, json] tup11 = + [b1, b2, b3, b4, n1, n2, n3, i1, i2, i3, i4, i5, i6, i7, i8, f1, + f2, f3, f4, f5, f6, f7, f8]; +[string, string, int, int, boolean, boolean, (), (), decimal, decimal, float, float] tup12 = [ + s1, s2, i1, i2, b1, b2, n1, n3, d1, d2, f1, f2 +]; + +[boolean, boolean...] restTup1 = [b1, b2]; +[boolean?, boolean?, boolean?...] restTup2 = [b1, b2, b3, n1, n3]; +[boolean|int?...] restTup3 = [b1, b2, b3, b4, i1]; +[(), ()...] restTup4 = [n1, n3]; +[int...] restTup5 = [i1, i2, i3, i4, i5, i6]; +[float...] restTup6 = [f1, f2, f3, f4, f5, f6, f7]; +[decimal...] restTup7 = [d1, d2, d3, d4]; +[decimal|float, decimal|float...] restTup8 = [d1, f1, f9, 1.23]; +[string...] restTup9 = [s1, s2, s3]; +[anydata...] restTup10 = [b1, b2, b3, b4, n1, n2, n3, i1, i2, i3, i4, i5, i6, i7, i8, f1, f2, f3, f4, f5, f6, f7, f8]; +[json, json, json...] restTup11 = [b1, b2, b3, b4, n1, n2, n3, i1, i2, i3, i4, i5, i6, i7, i8, f1, f2, f3, f4, f5, f6, f7, f8]; +[string, string, int, int, boolean, boolean, (), (), decimal, decimal, float, float...] restTup12 = [ + s1, s2, i1, i2, b1, b2, n1, n3, d1, d2, f1, f2, f2, f2 +]; + +var booleanRecordArray = [ + {b1, b2, b3, b4}, {b1, b2, b3, b4} +]; + +var booleanRecordArray2 = [ + {},{} +]; + +string csvStringWithBooleanValues1 = string `b1,b2,b3,b4 +true,false,true,false +true,false, true,false +true,false,true,false +`; + +string csvStringWithBooleanValues2 = string `b1,b2,b3,b4,b5 +true,false, true,false,true +true,false, true,false,true`; + +string csvStringWithBooleanValues3 = string `b1,b2,b3 +${" "}${"\t"} +true, false,true +${" "} + TRUE, FALSE,() +${" "} + +true, true,FALSE + +`; + +string csvStringWithBooleanValues4 = string `b1,b2,b3,b4 + true,(), (),false + true,(), null,false + +`; + +string csvStringWithBooleanValues5 = string `b1,b2,b3,b4 + +true,false,true,2 + +true,false,true,3 +`; + +string csvStringWithBooleanValues6 = string `b2,b3 +(),() + +`; + +string csvStringWithBooleanValues7 = string `b1,b2,b3,b4 +${b1},${b2},(),${b4} +`; + +string csvStringData1 = string ` + a, b, c, d, e, f + 1, string1, true, 2.234, 2.234, () + 2, string2, false, 0, 0, null + 3, string3, false, 1.23, 1.23, () + 4, string4, true, -6.51, -6.51, () + 5, string5, true, 3, 3, ()`; + +string csvStringData2 = string ` + hello, hello, (), 12, true, 12.34 + // comment + + a, b, c, d, e, f + + + 1, string1, true, 2.234, 2.234, () + 2, string2, false, 0, 0, null + 3, string3, false, 1.23, 1.23, () + 4, string4, true, -6.51, -6.51, () + 5, string5, true, 3, 3, ()`; + +string csvStringData3 = string ` + a, b, c, d, e, f + + + + 1, string1, true, 2.234, 2.234, () + 2, string2, false, 0, 0, null + 3, string3, false, 1.23, 1.23, () + + 4, string4, true, -6.51, -6.51, () + 5, string5, true, 3, 3, ()`; + +string csvStringData4 = string ` + 1, string1, true, 2.234, 2.234, () + 2, string2, false, 0, 0, null + 3, string3, false, 1.23, 1.23, () + 4, string4, true, -6.51, -6.51, () + 5, string5, true, 3, 3, ()`; + +string csvStringData5 = string ` + + + + 1, string1, true, 2.234, 2.234, () + 2, string2, false, 0, 0, null + + 3, string3, false, 1.23, 1.23, () + 4, string4, true, -6.51, -6.51, () + + 5, string5, true, 3, 3, ()`; + +string csvStringData6 = string ` + + 1, string1, true, 2.234, 2.234, () + 2, string2, false, 0, 0, null + + 3, string3, false, 1.23, 1.23, () + 4, string4, true, -6.51, -6.51, () + + 5, string5, true, 3, 3, ()`; + +string csvStringData7 = string ` + a@ b@ c@ d@ e@ f + 1@ string@ true@ 2.234@ -3.21@ () + 2@ s,tring@ true@ 2.234@ -3.21@ null + 3@ stri,ng@ true@ 2.234@ -3.21@ () + 4@ string@ true@ 2.234@ -3.21@ () + 5@ string@ true@ 2.234@ -3.21@ ()`; +string csvStringData8 = string ` + a@ b@ c@ d@ e@ f + + + + 1@ stri,ng@ true@ 2.234@ -3.21@ () + 2@ string@ true@ 2.234@ ()@-3.21 + 3@ string@ true@ 2.234@ -3.21@ null + + 4@ s,tring@ true@ 2.234@ -3.21@ () + 5@ string@ true@ 2.234@ -3.21@ ()`; + +string csvStringData9 = string ` + + 1@ string@ true@ 2.234@ -3.21@ () + 2@ string@ true@ 2.234@ -3.21@ null + + 3@ string@ true@ 2.234@ -3.21@ () + 4@ string@ true@ 2.234@ ()@-3.21 + + 5@ string@ true@ 2.234@ -3.21@ null`; diff --git a/ballerina-tests/parse-list-types-tests/tests/types.bal b/ballerina-tests/parse-list-types-tests/tests/types.bal new file mode 100644 index 0000000..62f8f98 --- /dev/null +++ b/ballerina-tests/parse-list-types-tests/tests/types.bal @@ -0,0 +1,2535 @@ +type BooleanRecord1 record { + boolean b1; + boolean|string b2; + boolean|string? b3; + boolean b4; +}; + +type BooleanRecord2 record {| + boolean b1; + boolean|string b2; + boolean|string? b3; + boolean b4; +|}; + +type BooleanRecord3 record {| + boolean b1; + boolean? b3; +|}; + +type BooleanRecord4 record { + boolean b1; + boolean? b3; +}; + +type BooleanRecord5 record { + boolean b1; + boolean? b3; + string defaultableField = ""; + string? nillableField = (); +}; + +type BooleanRecord6 record {| + boolean b1; + boolean? b3; + string defaultableField = ""; + string? nillableField = (); +|}; + +type BooleanRecord7 record { + boolean b1; + boolean? b3; + string defaultableField = ""; + string? nillableField = (); + string requiredField; +}; + +type BooleanRecord8 record {| + boolean b1; + boolean? b3; + string defaultableField = ""; + string? nillableField = (); + string requiredField; +|}; + +type BooleanRecord9 record {| + boolean b1; + boolean? b3; + boolean?...; +|}; + +type BooleanRecord10 record {| + boolean...; +|}; + +type BooleanRecord11 record {| + boolean b1; + string defaultableField = ""; + string? nillableField = (); + boolean?|string...; +|}; + +type BooleanRecord12 record {| + boolean b1; + string defaultableField = ""; + string? nillableField = (); + string requiredField; + boolean...; +|}; + +type BooleanRecord13 record {| + string defaultableField = ""; + string? nillableField = (); + string|boolean...; +|}; + +type BooleanRecord14 record {| + string defaultableField = ""; + string? nillableField = (); + string requiredField; + boolean...; +|}; + +type BooleanRecord15 record {| + int b1; + string defaultableField = ""; + string? nillableField = (); + boolean?...; +|}; + +type BooleanRecord16 record {| + boolean?...; +|}; + +type BooleanRecord17 record {| + int...; +|}; + +type BooleanRecord18 record {| + boolean b2; + int?...; +|}; + +type NilRecord1 record { + () n1; + () n2; + () n3; +}; + +type NilRecord2 record {| + () n1; + () n2; + () n3; +|}; + +type NilRecord3 record {| + () n1; + () n4; +|}; + +type NilRecord4 record { + () n1; + () n4; +}; + +type NilRecord5 record { + () n1; + () n4; + string defaultableField = ""; + string? nillableField = (); +}; + +type NilRecord6 record {| + () n1; + () n4; + string defaultableField = ""; + string? nillableField = (); +|}; + +type NilRecord7 record { + () n1; + () n4; + string defaultableField = ""; + string? nillableField = (); + string requiredField; +}; + +type NilRecord8 record {| + () n1; + () n4; + string defaultableField = ""; + string? nillableField = (); + string requiredField; +|}; + +type NilRecord9 record {| + () n1; + () n2; + ()...; +|}; + +type NilRecord10 record {| + ()...; +|}; + +type NilRecord11 record {| + () n1; + string defaultableField = ""; + string? nillableField = (); + ()...; +|}; + +type NilRecord12 record {| + () n1; + string defaultableField = ""; + string? nillableField = (); + string requiredField; + ()...; +|}; + +type NilRecord13 record {| + string defaultableField = ""; + string? nillableField = (); + ()...; +|}; + +type NilRecord14 record {| + string defaultableField = ""; + string? nillableField = (); + string requiredField; + ()...; +|}; + +type IntegerRecord1 record { + int i1; + int i2; + int i3; + int? i4; + int? i5; + int i6; + int i7; + int? i8; +}; + +type IntegerRecord2 record {| + int i1; + int? i2; + int i3; + int i4; + int? i5; + int i6; + int i7; + int? i8; +|}; + +type IntegerRecord3 record {| + int i1; + int i4; + int i6; +|}; + +type IntegerRecord4 record { + int i1; + int i4; + int i6; +}; + +type IntegerRecord5 record { + int i1; + int i4; + int i6; + string defaultableField = ""; + string? nillableField = (); +}; + +type IntegerRecord6 record {| + int i1; + int i4; + int i6; + string defaultableField = ""; + string? nillableField = (); +|}; + +type IntegerRecord7 record { + int i1; + int i4; + int i6; + string defaultableField = ""; + string? nillableField = (); + string requiredField; +}; + +type IntegerRecord8 record {| + int i1; + int i4; + int i6; + string defaultableField = ""; + string? nillableField = (); + string requiredField; +|}; + +type IntegerRecord9 record {| + int i1; + int i2; + int...; +|}; + +type IntegerRecord10 record {| + int...; +|}; + +type IntegerRecord11 record {| + int i1; + string defaultableField = ""; + string? nillableField = (); + int...; +|}; + +type IntegerRecord12 record {| + int i1; + string defaultableField = ""; + string? nillableField = (); + string requiredField; + int...; +|}; + +type IntegerRecord13 record {| + string defaultableField = ""; + string? nillableField = (); + int...; +|}; + +type IntegerRecord14 record {| + string defaultableField = ""; + string? nillableField = (); + string requiredField; + int...; +|}; + +type FloatRecord1 record { + float f1; + float f2; + float f3; + float f4; + float f5; + float f6; + float f7; + float f8; +}; + +type FloatRecord2 record {| + float f1; + float f2; + float f3; + float f4; + float f5; + float f6; + float f7; + float f8; +|}; + +type FloatRecord3 record {| + float f1; + float f4; + float f7; +|}; + +type FloatRecord4 record { + float f1; + float f4; + float f7; +}; + +type FloatRecord5 record { + float f1; + float f4; + float f7; + string defaultableField = ""; + string? nillableField = (); +}; + +type FloatRecord6 record {| + float f1; + float f4; + float f7; + string defaultableField = ""; + string? nillableField = (); +|}; + +type FloatRecord7 record { + float f1; + float f4; + float f7; + string defaultableField = ""; + string? nillableField = (); + string requiredField; +}; + +type FloatRecord8 record {| + float f1; + float f4; + float f7; + string defaultableField = ""; + string? nillableField = (); + string requiredField; +|}; + +type FloatRecord9 record {| + float f1; + float f2; + float...; +|}; + +type FloatRecord10 record {| + float...; +|}; + +type FloatRecord11 record {| + float f1; + string defaultableField = ""; + string? nillableField = (); + float...; +|}; + +type FloatRecord12 record {| + float f1; + string defaultableField = ""; + string? nillableField = (); + string requiredField; + float...; +|}; + +type FloatRecord13 record {| + string defaultableField = ""; + string? nillableField = (); + float...; +|}; + +type FloatRecord14 record {| + string defaultableField = ""; + string? nillableField = (); + string requiredField; + float...; +|}; + +type DecimalRecord1 record { + decimal d1; + decimal d2; + decimal d3; + decimal d4; + decimal d5; + decimal d6; + decimal d7; + decimal d8; +}; + +type DecimalRecord2 record {| + decimal d1; + decimal d2; + decimal d3; + decimal d4; + decimal d5; + decimal d6; + decimal d7; + decimal d8; +|}; + +type DecimalRecord3 record {| + decimal d1; + decimal d4; + decimal d7; +|}; + +type DecimalRecord4 record { + decimal d1; + decimal d4; + decimal d7; +}; + +type DecimalRecord5 record { + decimal d1; + decimal d4; + decimal d7; + string defaultableField = ""; + string? nillableField = (); +}; + +type DecimalRecord6 record {| + decimal d1; + decimal d4; + decimal d7; + string defaultableField = ""; + string? nillableField = (); +|}; + +type DecimalRecord7 record { + decimal d1; + decimal d4; + decimal d7; + string defaultableField = ""; + string? nillableField = (); + string requiredField; +}; + +type DecimalRecord8 record {| + decimal d1; + decimal d4; + decimal d7; + string defaultableField = ""; + string? nillableField = (); + string requiredField; +|}; + +type DecimalRecord9 record {| + decimal d1; + decimal d2; + decimal...; +|}; + +type DecimalRecord10 record {| + decimal...; +|}; + +type DecimalRecord11 record {| + decimal d1; + string defaultableField = ""; + string? nillableField = (); + decimal...; +|}; + +type DecimalRecord12 record {| + decimal d1; + string defaultableField = ""; + string? nillableField = (); + string requiredField; + decimal...; +|}; + +type DecimalRecord13 record {| + string defaultableField = ""; + string? nillableField = (); + decimal...; +|}; + +type DecimalRecord14 record {| + string defaultableField = ""; + string? nillableField = (); + string requiredField; + decimal...; +|}; + +type StringRecord1 record { + string s1; + string s2; + string s3; +}; + +type StringRecord2 record {| + string s1; + string s2; + string s3; +|}; + +type StringRecord3 record {| + string s1; + string s4; +|}; + +type StringRecord4 record { + string s1; + string s4; +}; + +type StringRecord5 record { + string s1; + string s4; + string defaultableField = ""; + string? nillableField = (); +}; + +type StringRecord6 record {| + string s1; + string s4; + string defaultableField = ""; + string? nillableField = (); +|}; + +type StringRecord7 record { + string s1; + string s4; + string defaultableField = ""; + string? nillableField = (); + string requiredField; +}; + +type StringRecord8 record {| + string s1; + string s4; + string defaultableField = ""; + string? nillableField = (); + string requiredField; +|}; + +type StringRecord9 record {| + string s1; + string s2; + string...; +|}; + +type StringRecord10 record {| + string...; +|}; + +type StringRecord11 record {| + string s1; + string defaultableField = ""; + string? nillableField = (); + string...; +|}; + +type StringRecord12 record {| + string d1; + string defaultableField = ""; + string? nillableField = (); + string requiredField; + string...; +|}; + +type StringRecord13 record {| + string defaultableField = ""; + string? nillableField = (); + string...; +|}; + +type StringRecord14 record {| + string defaultableField = ""; + string? nillableField = (); + string requiredField; + string...; +|}; + +type StringRecord15 record {| + string defaultableField = ""; + string? nillableField = (); + string requiredField; + string...; +|}; + +type StringRecord16 record {| + string?...; +|}; + +type StringRecord17 record {| + int...; +|}; + +type StringRecord18 record {| + string b2; + int?...; +|}; + +type StringRecord19 record { + string s1 = ""; + string s2 = ""; +}; + +type StringRecord20 record {| + string s1 = ""; + string s2 = ""; +|}; + +type StringRecord21 record { +}; + +type StringRecord22 record {| + string s1 = ""; + string s2 = ""; + json...; +|}; + +type StringRecord23 record {| + json...; +|}; + +type JsonRecord1 record { + json j1; + json j2; + json j3; +}; + +type JsonRecord2 record {| + json j1; + json j2; + json j3; +|}; + +type JsonRecord3 record {| + json j1; + json j4; +|}; + +type JsonRecord4 record { + json j1; + json j4; +}; + +type JsonRecord5 record { + json j1; + json j4; + json defaultableField = ""; + json? nillableField = (); +}; + +type JsonRecord6 record {| + json j1; + json j4; + json defaultableField = ""; + json? nillableField = (); +|}; + +type JsonRecord7 record { + json j1; + json j4; + json defaultableField = ""; + json? nillableField = (); + json requiredField; +}; + +type JsonRecord8 record {| + json j1; + json j4; + json defaultableField = ""; + json? nillableField = (); + json requiredField; +|}; + +type JsonRecord9 record {| + json j1; + json j2; + json...; +|}; + +type JsonRecord10 record {| + json...; +|}; + +type JsonRecord11 record {| + json j1; + json defaultableField = ""; + json? nillableField = (); + json...; +|}; + +type JsonRecord12 record {| + json j1; + json defaultableField = ""; + json? nillableField = (); + json requiredField; + json...; +|}; + +type JsonRecord13 record {| + json defaultableField = ""; + json? nillableField = (); + json...; +|}; + +type JsonRecord14 record {| + json defaultableField = ""; + json? nillableField = (); + json requiredField; + json...; +|}; + +type AnydataRecord1 record { + anydata anydata1; + anydata anydata2; + anydata anydata3; +}; + +type AnydataRecord2 record {| + anydata anydata1; + anydata anydata2; + anydata anydata3; +|}; + +type AnydataRecord3 record {| + anydata anydata1; + anydata anydata4; +|}; + +type AnydataRecord4 record { + anydata anydata1; + anydata anydata4; +}; + +type AnydataRecord5 record { + anydata anydata1; + anydata anydata4; + anydata defaultableField = ""; + anydata? nillableField = (); +}; + +type AnydataRecord6 record {| + anydata anydata1; + anydata anydata4; + anydata defaultableField = ""; + anydata? nillableField = (); +|}; + +type AnydataRecord7 record { + anydata anydata1; + anydata anydata4; + anydata defaultableField = ""; + anydata? nillableField = (); + anydata requiredField; +}; + +type AnydataRecord8 record {| + anydata anydata1; + anydata anydata4; + anydata defaultableField = ""; + anydata? nillableField = (); + anydata requiredField; +|}; + +type AnydataRecord9 record {| + anydata anydata1; + anydata anydata2; + anydata...; +|}; + +type AnydataRecord10 record {| + anydata...; +|}; + +type AnydataRecord11 record {| + anydata anydata1; + anydata defaultableField = ""; + anydata? nillableField = (); + anydata...; +|}; + +type AnydataRecord12 record {| + anydata anydata1; + anydata defaultableField = ""; + anydata? nillableField = (); + anydata requiredField; + anydata...; +|}; + +type AnydataRecord13 record {| + anydata defaultableField = ""; + anydata? nillableField = (); + anydata...; +|}; + +type AnydataRecord14 record {| + anydata defaultableField = ""; + anydata? nillableField = (); + anydata requiredField; + anydata...; +|}; + +type CustomRecord1 record { + int i1; + int i2; + string s1; + string s2; + boolean b1; + boolean b2; + () n1; + () n2; + float f1; + float f2; + decimal d1; + decimal d2; +}; + +type CustomRecord2 record {| + int i1; + int i2; + string s1; + string s2; + boolean b1; + boolean b2; + () n1; + () n2; + float f1; + float f2; + decimal d1; + decimal d2; +|}; + +type CustomRecord3 record {| + int i1; + string s1; + boolean b1; + () n1; + float f1; + decimal d1; +|}; + +type CustomRecord4 record { + int i1; + string s1; + boolean b1; + () n1; + float f1; + decimal d1; +}; + +type CustomRecord5 record { + int i1; + string s1; + boolean b1; + () n1; + float f1; + decimal d1; + string defaultableField = ""; + string? nillableField = (); +}; + +type CustomRecord6 record {| + int i1; + string s1; + boolean b1; + () n1; + float f1; + decimal d1; + anydata defaultableField = ""; + anydata? nillableField = (); +|}; + +type CustomRecord7 record { + int i1; + string s1; + boolean b1; + () n1; + float f1; + decimal d1; + anydata defaultableField = ""; + anydata? nillableField = (); + anydata requiredField; +}; + +type CustomRecord8 record {| + int i1; + string s1; + boolean b1; + () n1; + float f1; + decimal d1; + anydata defaultableField = ""; + anydata? nillableField = (); + anydata requiredField; +|}; + +type CustomRecord9 record {| + int i1; + string s1; + boolean b1; + () n1; + float f1; + decimal d1; + string...; +|}; + +type CustomRecord10 record {| + string...; +|}; + +type CustomRecord11 record {| + int i1; + string s1; + boolean b1; + () n1; + float f1; + decimal d1; + anydata defaultableField = ""; + anydata? nillableField = (); + string...; +|}; + +type CustomRecord12 record {| + int i1; + string s1; + boolean b1; + () n1; + float f1; + decimal d1; + anydata defaultableField = ""; + anydata? nillableField = (); + anydata requiredField; + string...; +|}; + +type CustomRecord13 record {| + anydata defaultableField = ""; + anydata? nillableField = (); + string...; +|}; + +type CustomRecord14 record {| + anydata defaultableField = ""; + anydata? nillableField = (); + anydata requiredField; + string...; +|}; + +type CustomRecord15 record {| + string '1; + string '2; +|}; + +type CustomRecord16 record {| + string '1; + string '2; + string '3; + string '4; +|}; + +type CustomRecord17 record { + string '1; + string '2; +}; + +type CustomRecord18 record { + string '1; + string '2; + string '3; + string '4; +}; + +type CustomRecord19 record { + string '1; + string '2; + string '3 = ""; + string '4 = ""; +}; + +type CustomRecord20 record { + string '1; +}; + +type CustomRecord21 record {| + string '1; + json...; +|}; + +type CustomRecord22 record {| + string '1; + string...; +|}; + +type CustomRecord23 record {| + string '1; + string a = ""; + string...; +|}; + +type CustomRecord24 record {| + string '1; + string '2 = ""; + string...; +|}; + +type CustomRecord25 record {| + int '1; + string...; +|}; + +type CustomRecord26 record {| + string '1; + int...; +|}; + +type CustomRecord27 record {| + int i1; + string s1; + boolean b1; + () n1; + float f1; + decimal d1; + anydata a1; + json j1; + anydata defaultableField = ""; + anydata? nillableField = (); + string...; +|}; + +type CustomRecord28 record { + string '1; +}; + +type CustomRecord29 record { + int '1; +}; + +type CustomRecord30 record {| + string '1; + string '2; + string '3; + string '4; + string '5; + string '6; +|}; + +type CustomRecord31 record {| + string '1; + string '6; +|}; + +type CustomRecord32 record {| + int '1; +|}; + +type CustomRecord33 record {| + string '1; + string '2; + string '3; + string '4; + string '5; + string '6; +|}; + +type CustomRecord34 record { + string '1; + string '6; + string '5 = ""; +}; + +type CustomRecord35 record { + string '1; + string '6; + string '9 = ""; +}; + +type CustomRecord36 record {| + string '1; + string '6; + string '9 = ""; +|}; + +type CustomRecord37 record {| + string '1; + string '6; + string '5 = ""; +|}; + +type CustomRecord38 record {| + string '1; + string '2; + string '3; + string '4; + string '5; + string '6; + string ...; +|}; + +type CustomRecord39 record {| + string '1; + string '2; + string '3; + string '4; + string '5; + string '6; + json ...; +|}; + +type CustomRecord40 record {| + string '5; + string '6; + json ...; +|}; + +type CustomRecord41 record {| + json ...; +|}; + +type CustomRecord42 record {| + int '1; + string '2; + boolean '3; + decimal '4; + float '5; + () '6; +|}; + +type CustomRecord43 record { + int '1; + string '2; + boolean '3; + decimal '4; + float '5; + () '6; +}; + +type CustomRecord44 record {| + int '1; + string '2; + boolean '3; + decimal '4; + float '5; + () '6; + string ...; +|}; + +type CustomRecord45 record {| + int H1; + string H2; + boolean H3; + decimal H4; + float H5; + () H6; +|}; + +type CustomRecord46 record { + int H1; + string H2; + boolean H3; + decimal H4; + float H5; + () H6; +}; + +type CustomRecord47 record {| + int H1; + string H2; + boolean H3; + decimal H4; + float H5; + () H6; + string ...; +|}; + +type CustomRecord48 record { + string H1; + string H2; + string H3; + string H4; + string H5; + string H6; +}; + +type CustomRecord49 record {| + string H1; + string H2; + string H3; + string H4; + string H5; + string H6; +|}; + +type CustomRecord50 record { + int H1; + float H4; +}; + +type CustomRecord51 record {| + int H1; + float H4; +|}; + +type CustomRecord52 record {| + string H1; + string H4; + string ...; +|}; + +type CustomRecord53 record {| + int H1; + float H4; + decimal ...; +|}; + +type CustomRecord54 record {| + string H1 = ""; + string H4; + string '1; +|}; + +type CustomRecord55 record {| + string H1 = ""; + string H4 = ""; + int '1 = 10; +|}; + +type CustomRecord56 record { + string H1 = ""; + string H4 = ""; + anydata '1 = 10; +}; + +type BooleanTuple1 [boolean, boolean, boolean, boolean]; + +type BooleanTuple2 [boolean, boolean]; + +type BooleanTuple3 [boolean, boolean...]; + +type BooleanTuple4 [boolean...]; + +type NillableBooleanTuple5 [boolean?, boolean?, boolean?, boolean?, boolean?]; + +type NillableBooleanTuple6 [boolean?, boolean?]; + +type NillableBooleanTuple7 [boolean?, boolean?, boolean?...]; + +type NillableBooleanTuple8 [boolean?...]; + +type NillableIntBooleanTuple9 [int|boolean?, int|boolean?...]; + +type NilTuple1 [(), (), ()]; + +type NilTuple2 [(), ()]; + +type NilTuple3 [(), ()...]; + +type NilTuple4 [()...]; + +type IntegerTuple1 [int, int, int, int, int, int]; + +type IntegerTuple2 [int, int]; + +type IntegerTuple3 [int, int...]; + +type IntegerTuple4 [int...]; + +type FloatTuple1 [float, float, float, float, float, float, float]; + +type FloatTuple2 [float, float]; + +type FloatTuple3 [float, float...]; + +type FloatTuple4 [float...]; + +type DecimalTuple1 [decimal, decimal, decimal, decimal]; + +type DecimalTuple2 [decimal, decimal]; + +type DecimalTuple3 [decimal, decimal...]; + +type DecimalTuple4 [decimal...]; + +type StringTuple1 [string, string, string, string]; + +type StringTuple2 [string, string]; + +type StringTuple3 [string, string...]; + +type StringTuple4 [string...]; + +type AnydataTuple1 [anydata, anydata, anydata, anydata, anydata, + anydata, anydata, anydata, anydata, anydata, anydata, anydata, + anydata, anydata, anydata, anydata, anydata, anydata, anydata, + anydata, anydata, anydata, anydata]; + +type AnydataTuple2 [anydata, anydata]; + +type AnydataTuple3 [anydata, anydata...]; + +type AnydataTuple4 [anydata...]; + +type JsonTuple1 [json, json, json, json, json, json, json, json, + json, json, json, json, json, json, json, json, json, json, + json, json, json, json, json]; + +type JsonTuple2 [json, json]; + +type JsonTuple3 [json, json...]; + +type JsonTuple4 [json...]; + +type CustomTuple1 [string, int, decimal, float, (), boolean, anydata, json, string, int, decimal, float, (), boolean, anydata, json]; + +type CustomTuple2 [string, int, decimal, float, (), boolean, anydata, json]; + +type CustomTuple3 [string, int, decimal, float, (), boolean, anydata, json, string...]; + +type CustomTuple4 [string...]; + +type CustomTuple5 [string, int, decimal, float, (), boolean, anydata, json, anydata...]; + +type CustomTuple6 [anydata...]; + +type CustomTuple7 [int, string, boolean, (), float, decimal, json, anydata, string...]; + +type CustomTuple8 [int, string, boolean, (), float, decimal, json, anydata, int...]; + +type IntegerArray1 int[]; + +type IntegerArray2 int[2]; + +type IntegerArray3 int[]; + +type IntegerArray4 int[2]; + +type IntegerArray5 int[3]; + +type IntegerArray6 int[4]; + +type StringArray string[]; + +type NillableStringArray string?[]; + +type NillableIntOrUnionStringArray (int|string?)[]; + +type StringArray1 string[]; + +type StringArray2 string[2]; + +type StringArray3 string[]; + +type StringArray4 string[2]; + +type StringArray5 string[3]; + +type StringArray6 string[4]; + +type FloatArray1 float[]; + +type FloatArray2 float[2]; + +type FloatArray3 float[]; + +type FloatArray4 float[2]; + +type FloatArray5 float[3]; + +type FloatArray6 float[4]; + +type DecimalArray1 decimal[]; + +type DecimalArray2 decimal[2]; + +type DecimalArray3 decimal[]; + +type DecimalArray4 decimal[2]; + +type DecimalArray5 decimal[3]; + +type DecimalArray6 decimal[4]; + +type BooleanArray boolean[]; + +type NillableBooleanArray boolean?[]; + +type NillableIntOrUnionBooleanArray (int|boolean?)[]; + +type BooleanArray2 boolean[2]; + +type BooleanArray3 boolean[3]; + +type BooleanArray4 boolean[]; + +type BooleanArray5 boolean[2]; + +type BooleanArray6 boolean[4]; + +type NilArray1 ()[]; + +type NilArray2 ()[2]; + +type NilArray3 ()[]; + +type NilArray4 ()[2]; + +type NilArray5 ()[3]; + +type NilArray6 ()[4]; + +type JsonArray1 json[]; + +type JsonArray2 json[2]; + +type JsonArray3 json[]; + +type JsonArray4 json[2]; + +type JsonArray5 json[3]; + +type JsonArray6 json[4]; + +type AnydataArray1 anydata[]; + +type AnydataArray2 anydata[2]; + +type AnydataArray3 anydata[]; + +type AnydataArray4 anydata[2]; + +type AnydataArray5 anydata[3]; + +type AnydataArray6 anydata[4]; + +type CustomArray1 CustomTuple2[]; + +type CustomArray2 CustomTuple2[2]; + +type CustomArray3 CustomTuple2[]; + +type CustomArray4 CustomTuple2[2]; + +type CustomArray5 CustomTuple2[3]; + +type CustomArray6 CustomTuple2[4]; + +type IntegerMap map; + +type StringMap map; + +type NillableIntUnionStringMap map; + +type IntUnionStringMap map; + +type DecimalMap map; + +type FloatMap map; + +type BooleanMap map; + +type NillableBooleanMap map; + +type NillableIntUnionBooleanMap map; + +type IntUnionBooleanMap map; + +type NilMap map<()>; + +type JsonMap map; + +type AnydataMap map; + +type CustomMap map; + +type BooleanRecord1Array BooleanRecord1[]; + +type ClosedBooleanRecord1Array BooleanRecord1[3]; + +type BooleanRecord2Array BooleanRecord2[]; + +type ClosedBooleanRecord2Array BooleanRecord2[3]; + +type BooleanRecord3Array BooleanRecord3[]; + +type ClosedBooleanRecord3Array BooleanRecord3[3]; + +type BooleanRecord4Array BooleanRecord4[]; + +type ClosedBooleanRecord4Array BooleanRecord4[3]; + +type BooleanRecord5Array BooleanRecord5[]; + +type ClosedBooleanRecord5Array BooleanRecord5[3]; + +type BooleanRecord6Array BooleanRecord6[]; + +type ClosedBooleanRecord6Array BooleanRecord6[3]; + +type BooleanRecord7Array BooleanRecord7[]; + +type ClosedBooleanRecord7Array BooleanRecord7[3]; + +type BooleanRecord8Array BooleanRecord8[]; + +type ClosedBooleanRecord8Array BooleanRecord8[3]; + +type BooleanRecord9Array BooleanRecord9[]; + +type ClosedBooleanRecord9Array BooleanRecord9[3]; + +type BooleanRecord10Array BooleanRecord10[]; + +type ClosedBooleanRecord10Array BooleanRecord10[3]; + +type BooleanRecord11Array BooleanRecord11[]; + +type ClosedBooleanRecord11Array BooleanRecord11[3]; + +type BooleanRecord12Array BooleanRecord12[]; + +type ClosedBooleanRecord12Array BooleanRecord12[3]; + +type BooleanRecord13Array BooleanRecord13[]; + +type ClosedBooleanRecord13Array BooleanRecord13[3]; + +type BooleanRecord14Array BooleanRecord14[]; + +type ClosedBooleanRecord14Array BooleanRecord14[3]; + +type BooleanRecord15Array BooleanRecord15[]; + +type ClosedBooleanRecord15Array BooleanRecord15[3]; + +type BooleanRecord16Array BooleanRecord16[]; + +type ClosedBooleanRecord16Array BooleanRecord16[3]; + +type BooleanRecord17Array BooleanRecord17[]; + +type ClosedBooleanRecord17Array BooleanRecord17[3]; + +type BooleanRecord18Array BooleanRecord18[]; + +type ClosedBooleanRecord18Array BooleanRecord18[3]; + +type NilRecord1Array NilRecord1[]; + +type ClosedNilRecord1Array NilRecord1[3]; + +type NilRecord2Array NilRecord2[]; + +type ClosedNilRecord2Array NilRecord2[3]; + +type NilRecord3Array NilRecord3[]; + +type ClosedNilRecord3Array NilRecord3[3]; + +type NilRecord4Array NilRecord4[]; + +type ClosedNilRecord4Array NilRecord4[3]; + +type NilRecord5Array NilRecord5[]; + +type ClosedNilRecord5Array NilRecord5[3]; + +type NilRecord6Array NilRecord6[]; + +type ClosedNilRecord6Array NilRecord6[3]; + +type NilRecord7Array NilRecord7[]; + +type ClosedNilRecord7Array NilRecord7[3]; + +type NilRecord8Array NilRecord8[]; + +type ClosedNilRecord8Array NilRecord8[3]; + +type NilRecord9Array NilRecord9[]; + +type ClosedNilRecord9Array NilRecord9[3]; + +type NilRecord10Array NilRecord10[]; + +type ClosedNilRecord10Array NilRecord10[3]; + +type NilRecord11Array NilRecord11[]; + +type ClosedNilRecord11Array NilRecord11[3]; + +type NilRecord12Array NilRecord12[]; + +type ClosedNilRecord12Array NilRecord12[3]; + +type NilRecord13Array NilRecord13[]; + +type ClosedNilRecord13Array NilRecord13[3]; + +type NilRecord14Array NilRecord14[]; + +type ClosedNilRecord14Array NilRecord14[3]; + +type IntegerRecord1Array IntegerRecord1[]; + +type ClosedIntegerRecord1Array IntegerRecord1[3]; + +type IntegerRecord2Array IntegerRecord2[]; + +type ClosedIntegerRecord2Array IntegerRecord2[3]; + +type IntegerRecord3Array IntegerRecord3[]; + +type ClosedIntegerRecord3Array IntegerRecord3[3]; + +type IntegerRecord4Array IntegerRecord4[]; + +type ClosedIntegerRecord4Array IntegerRecord4[3]; + +type IntegerRecord5Array IntegerRecord5[]; + +type ClosedIntegerRecord5Array IntegerRecord5[3]; + +type IntegerRecord6Array IntegerRecord6[]; + +type ClosedIntegerRecord6Array IntegerRecord6[3]; + +type IntegerRecord7Array IntegerRecord7[]; + +type ClosedIntegerRecord7Array IntegerRecord7[3]; + +type IntegerRecord8Array IntegerRecord8[]; + +type ClosedIntegerRecord8Array IntegerRecord8[3]; + +type IntegerRecord9Array IntegerRecord9[]; + +type ClosedIntegerRecord9Array IntegerRecord9[3]; + +type IntegerRecord10Array IntegerRecord10[]; + +type ClosedIntegerRecord10Array IntegerRecord10[3]; + +type IntegerRecord11Array IntegerRecord11[]; + +type ClosedIntegerRecord11Array IntegerRecord11[3]; + +type IntegerRecord12Array IntegerRecord12[]; + +type ClosedIntegerRecord12Array IntegerRecord12[3]; + +type IntegerRecord13Array IntegerRecord13[]; + +type ClosedIntegerRecord13Array IntegerRecord13[3]; + +type IntegerRecord14Array IntegerRecord14[]; + +type ClosedIntegerRecord14Array IntegerRecord14[3]; + +type FloatRecord1Array FloatRecord1[]; + +type ClosedFloatRecord1Array FloatRecord1[3]; + +type FloatRecord2Array FloatRecord2[]; + +type ClosedFloatRecord2Array FloatRecord2[3]; + +type FloatRecord3Array FloatRecord3[]; + +type ClosedFloatRecord3Array FloatRecord3[3]; + +type FloatRecord4Array FloatRecord4[]; + +type ClosedFloatRecord4Array FloatRecord4[3]; + +type FloatRecord5Array FloatRecord5[]; + +type ClosedFloatRecord5Array FloatRecord5[3]; + +type FloatRecord6Array FloatRecord6[]; + +type ClosedFloatRecord6Array FloatRecord6[3]; + +type FloatRecord7Array FloatRecord7[]; + +type ClosedFloatRecord7Array FloatRecord7[3]; + +type FloatRecord8Array FloatRecord8[]; + +type ClosedFloatRecord8Array FloatRecord8[3]; + +type FloatRecord9Array FloatRecord9[]; + +type ClosedFloatRecord9Array FloatRecord9[3]; + +type FloatRecord10Array FloatRecord10[]; + +type ClosedFloatRecord10Array FloatRecord10[3]; + +type FloatRecord11Array FloatRecord11[]; + +type ClosedFloatRecord11Array FloatRecord11[3]; + +type FloatRecord12Array FloatRecord12[]; + +type ClosedFloatRecord12Array FloatRecord12[3]; + +type FloatRecord13Array FloatRecord13[]; + +type ClosedFloatRecord13Array FloatRecord13[3]; + +type FloatRecord14Array FloatRecord14[]; + +type ClosedFloatRecord14Array FloatRecord14[3]; + +type DecimalRecord1Array DecimalRecord1[]; + +type ClosedDecimalRecord1Array DecimalRecord1[3]; + +type DecimalRecord2Array DecimalRecord2[]; + +type ClosedDecimalRecord2Array DecimalRecord2[3]; + +type DecimalRecord3Array DecimalRecord3[]; + +type ClosedDecimalRecord3Array DecimalRecord3[3]; + +type DecimalRecord4Array DecimalRecord4[]; + +type ClosedDecimalRecord4Array DecimalRecord4[3]; + +type DecimalRecord5Array DecimalRecord5[]; + +type ClosedDecimalRecord5Array DecimalRecord5[3]; + +type DecimalRecord6Array DecimalRecord6[]; + +type ClosedDecimalRecord6Array DecimalRecord6[3]; + +type DecimalRecord7Array DecimalRecord7[]; + +type ClosedDecimalRecord7Array DecimalRecord7[3]; + +type DecimalRecord8Array DecimalRecord8[]; + +type ClosedDecimalRecord8Array DecimalRecord8[3]; + +type DecimalRecord9Array DecimalRecord9[]; + +type ClosedDecimalRecord9Array DecimalRecord9[3]; + +type DecimalRecord10Array DecimalRecord10[]; + +type ClosedDecimalRecord10Array DecimalRecord10[3]; + +type DecimalRecord11Array DecimalRecord11[]; + +type ClosedDecimalRecord11Array DecimalRecord11[3]; + +type DecimalRecord12Array DecimalRecord12[]; + +type ClosedDecimalRecord12Array DecimalRecord12[3]; + +type DecimalRecord13Array DecimalRecord13[]; + +type ClosedDecimalRecord13Array DecimalRecord13[3]; + +type DecimalRecord14Array DecimalRecord14[]; + +type ClosedDecimalRecord14Array DecimalRecord14[3]; + +type StringRecord1Array StringRecord1[]; + +type ClosedStringRecord1Array StringRecord1[3]; + +type StringRecord2Array StringRecord2[]; + +type ClosedStringRecord2Array StringRecord2[3]; + +type StringRecord3Array StringRecord3[]; + +type ClosedStringRecord3Array StringRecord3[3]; + +type StringRecord4Array StringRecord4[]; + +type ClosedStringRecord4Array StringRecord4[3]; + +type StringRecord5Array StringRecord5[]; + +type ClosedStringRecord5Array StringRecord5[3]; + +type StringRecord6Array StringRecord6[]; + +type ClosedStringRecord6Array StringRecord6[3]; + +type StringRecord7Array StringRecord7[]; + +type ClosedStringRecord7Array StringRecord7[3]; + +type StringRecord8Array StringRecord8[]; + +type ClosedStringRecord8Array StringRecord8[3]; + +type StringRecord9Array StringRecord9[]; + +type ClosedStringRecord9Array StringRecord9[3]; + +type StringRecord10Array StringRecord10[]; + +type ClosedStringRecord10Array StringRecord10[3]; + +type StringRecord11Array StringRecord11[]; + +type ClosedStringRecord11Array StringRecord11[3]; + +type StringRecord12Array StringRecord12[]; + +type ClosedStringRecord12Array StringRecord12[3]; + +type StringRecord13Array StringRecord13[]; + +type ClosedStringRecord13Array StringRecord13[3]; + +type StringRecord14Array StringRecord14[]; + +type ClosedStringRecord14Array StringRecord14[3]; + +type StringRecord15Array StringRecord15[]; + +type StringRecord16Array StringRecord16[]; + +type StringRecord17Array StringRecord17[]; + +type StringRecord18Array StringRecord18[]; + +type StringRecord19Array StringRecord19[]; + +type StringRecord20Array StringRecord20[]; + +type StringRecord21Array StringRecord21[]; + +type StringRecord22Array StringRecord22[]; + +type StringRecord23Array StringRecord23[]; + +type JsonRecord1Array JsonRecord1[]; + +type ClosedJsonRecord1Array JsonRecord1[3]; + +type JsonRecord2Array JsonRecord2[]; + +type ClosedJsonRecord2Array JsonRecord2[3]; + +type JsonRecord3Array JsonRecord3[]; + +type ClosedJsonRecord3Array JsonRecord3[3]; + +type JsonRecord4Array JsonRecord4[]; + +type ClosedJsonRecord4Array JsonRecord4[3]; + +type JsonRecord5Array JsonRecord5[]; + +type ClosedJsonRecord5Array JsonRecord5[3]; + +type JsonRecord6Array JsonRecord6[]; + +type ClosedJsonRecord6Array JsonRecord6[3]; + +type JsonRecord7Array JsonRecord7[]; + +type ClosedJsonRecord7Array JsonRecord7[3]; + +type JsonRecord8Array JsonRecord8[]; + +type ClosedJsonRecord8Array JsonRecord8[3]; + +type JsonRecord9Array JsonRecord9[]; + +type ClosedJsonRecord9Array JsonRecord9[3]; + +type JsonRecord10Array JsonRecord10[]; + +type ClosedJsonRecord10Array JsonRecord10[3]; + +type JsonRecord11Array JsonRecord11[]; + +type ClosedJsonRecord11Array JsonRecord11[3]; + +type JsonRecord12Array JsonRecord12[]; + +type ClosedJsonRecord12Array JsonRecord12[3]; + +type JsonRecord13Array JsonRecord13[]; + +type ClosedJsonRecord13Array JsonRecord13[3]; + +type JsonRecord14Array JsonRecord14[]; + +type ClosedJsonRecord14Array JsonRecord14[3]; + +type AnydataRecord1Array AnydataRecord1[]; + +type ClosedAnydataRecord1Array AnydataRecord1[3]; + +type AnydataRecord2Array AnydataRecord2[]; + +type ClosedAnydataRecord2Array AnydataRecord2[3]; + +type AnydataRecord3Array AnydataRecord3[]; + +type ClosedAnydataRecord3Array AnydataRecord3[3]; + +type AnydataRecord4Array AnydataRecord4[]; + +type ClosedAnydataRecord4Array AnydataRecord4[3]; + +type AnydataRecord5Array AnydataRecord5[]; + +type ClosedAnydataRecord5Array AnydataRecord5[3]; + +type AnydataRecord6Array AnydataRecord6[]; + +type ClosedAnydataRecord6Array AnydataRecord6[3]; + +type AnydataRecord7Array AnydataRecord7[]; + +type ClosedAnydataRecord7Array AnydataRecord7[3]; + +type AnydataRecord8Array AnydataRecord8[]; + +type ClosedAnydataRecord8Array AnydataRecord8[3]; + +type AnydataRecord9Array AnydataRecord9[]; + +type ClosedAnydataRecord9Array AnydataRecord9[3]; + +type AnydataRecord10Array AnydataRecord10[]; + +type ClosedAnydataRecord10Array AnydataRecord10[3]; + +type AnydataRecord11Array AnydataRecord11[]; + +type ClosedAnydataRecord11Array AnydataRecord11[3]; + +type AnydataRecord12Array AnydataRecord12[]; + +type ClosedAnydataRecord12Array AnydataRecord12[3]; + +type AnydataRecord13Array AnydataRecord13[]; + +type ClosedAnydataRecord13Array AnydataRecord13[3]; + +type AnydataRecord14Array AnydataRecord14[]; + +type ClosedAnydataRecord14Array AnydataRecord14[3]; + +type CustomRecord1Array CustomRecord1[]; + +type ClosedCustomRecord1Array CustomRecord1[3]; + +type CustomRecord2Array CustomRecord2[]; + +type ClosedCustomRecord2Array CustomRecord2[3]; + +type CustomRecord3Array CustomRecord3[]; + +type ClosedCustomRecord3Array CustomRecord3[3]; + +type CustomRecord4Array CustomRecord4[]; + +type ClosedCustomRecord4Array CustomRecord4[3]; + +type CustomRecord5Array CustomRecord5[]; + +type ClosedCustomRecord5Array CustomRecord5[3]; + +type CustomRecord6Array CustomRecord6[]; + +type ClosedCustomRecord6Array CustomRecord6[3]; + +type CustomRecord7Array CustomRecord7[]; + +type ClosedCustomRecord7Array CustomRecord7[3]; + +type CustomRecord8Array CustomRecord8[]; + +type ClosedCustomRecord8Array CustomRecord8[3]; + +type CustomRecord9Array CustomRecord9[]; + +type ClosedCustomRecord9Array CustomRecord9[3]; + +type CustomRecord10Array CustomRecord10[]; + +type ClosedCustomRecord10Array CustomRecord10[3]; + +type CustomRecord11Array CustomRecord11[]; + +type ClosedCustomRecord11Array CustomRecord11[3]; + +type CustomRecord12Array CustomRecord12[]; + +type ClosedCustomRecord12Array CustomRecord12[3]; + +type CustomRecord13Array CustomRecord13[]; + +type ClosedCustomRecord13Array CustomRecord13[3]; + +type CustomRecord14Array CustomRecord14[]; + +type ClosedCustomRecord14Array CustomRecord14[3]; + +type CustomRecord15Array CustomRecord15[]; + +type CustomRecord16Array CustomRecord16[]; + +type CustomRecord17Array CustomRecord17[]; + +type CustomRecord18Array CustomRecord18[]; + +type CustomRecord19Array CustomRecord19[]; + +type CustomRecord20Array CustomRecord20[]; + +type CustomRecord21Array CustomRecord21[]; + +type CustomRecord22Array CustomRecord22[]; + +type CustomRecord23Array CustomRecord23[]; + +type CustomRecord24Array CustomRecord24[]; + +type CustomRecord25Array CustomRecord25[]; + +type CustomRecord26Array CustomRecord26[]; + +type CustomRecord27Array CustomRecord27[]; +type CustomRecord28Array CustomRecord28[]; +type CustomRecord29Array CustomRecord29[]; +type CustomRecord30Array CustomRecord30[]; +type CustomRecord31Array CustomRecord31[]; +type CustomRecord32Array CustomRecord32[]; +type CustomRecord33Array CustomRecord33[]; +type CustomRecord34Array CustomRecord34[]; +type CustomRecord35Array CustomRecord35[]; +type CustomRecord36Array CustomRecord36[]; +type CustomRecord37Array CustomRecord37[]; +type CustomRecord38Array CustomRecord38[]; +type CustomRecord39Array CustomRecord39[]; +type CustomRecord40Array CustomRecord40[]; +type CustomRecord41Array CustomRecord41[]; +type CustomRecord42Array CustomRecord42[]; +type CustomRecord43Array CustomRecord43[]; +type CustomRecord44Array CustomRecord44[]; +type CustomRecord45Array CustomRecord45[]; +type CustomRecord46Array CustomRecord46[]; +type CustomRecord47Array CustomRecord47[]; +type CustomRecord48Array CustomRecord48[]; +type CustomRecord49Array CustomRecord49[]; +type CustomRecord50Array CustomRecord50[]; +type CustomRecord51Array CustomRecord51[]; +type CustomRecord52Array CustomRecord52[]; +type CustomRecord53Array CustomRecord53[]; +type CustomRecord54Array CustomRecord54[]; +type CustomRecord55Array CustomRecord55[]; +type CustomRecord56Array CustomRecord56[]; + +type BooleanTuple1Array BooleanTuple1[]; + +type ClosedBooleanTuple1Array BooleanTuple1[3]; + +type BooleanTuple2Array BooleanTuple2[]; + +type ClosedBooleanTuple2Array BooleanTuple2[3]; + +type BooleanTuple3Array BooleanTuple3[]; + +type ClosedBooleanTuple3Array BooleanTuple3[3]; + +type BooleanTuple4Array BooleanTuple4[]; + +type ClosedBooleanTuple4Array BooleanTuple4[3]; + +type NillableBooleanTuple5Array NillableBooleanTuple5[]; + +type NillableBooleanTuple6Array NillableBooleanTuple6[]; + +type NillableBooleanTuple7Array NillableBooleanTuple7[]; + +type NillableBooleanTuple8Array NillableBooleanTuple8[]; + +type NillableIntBooleanTuple9Array NillableIntBooleanTuple9[]; + +type NilTuple1Array NilTuple1[]; + +type ClosedNilTuple1Array NilTuple1[3]; + +type NilTuple2Array NilTuple2[]; + +type ClosedNilTuple2Array NilTuple2[3]; + +type NilTuple3Array NilTuple3[]; + +type ClosedNilTuple3Array NilTuple3[3]; + +type NilTuple4Array NilTuple4[]; + +type ClosedNilTuple4Array NilTuple4[3]; + +type IntegerTuple1Array IntegerTuple1[]; + +type ClosedIntegerTuple1Array IntegerTuple1[3]; + +type IntegerTuple2Array IntegerTuple2[]; + +type ClosedIntegerTuple2Array IntegerTuple2[3]; + +type IntegerTuple3Array IntegerTuple3[]; + +type ClosedIntegerTuple3Array IntegerTuple3[3]; + +type IntegerTuple4Array IntegerTuple4[]; + +type ClosedIntegerTuple4Array IntegerTuple4[3]; + +type FloatTuple1Array FloatTuple1[]; + +type ClosedFloatTuple1Array FloatTuple1[3]; + +type FloatTuple2Array FloatTuple2[]; + +type ClosedFloatTuple2Array FloatTuple2[3]; + +type FloatTuple3Array FloatTuple3[]; + +type ClosedFloatTuple3Array FloatTuple3[3]; + +type FloatTuple4Array FloatTuple4[]; + +type ClosedFloatTuple4Array FloatTuple4[3]; + +type DecimalTuple1Array DecimalTuple1[]; + +type ClosedDecimalTuple1Array DecimalTuple1[3]; + +type DecimalTuple2Array DecimalTuple2[]; + +type ClosedDecimalTuple2Array DecimalTuple2[3]; + +type DecimalTuple3Array DecimalTuple3[]; + +type ClosedDecimalTuple3Array DecimalTuple3[3]; + +type DecimalTuple4Array DecimalTuple4[]; + +type ClosedDecimalTuple4Array DecimalTuple4[3]; + +type StringTuple1Array StringTuple1[]; + +type ClosedStringTuple1Array StringTuple1[3]; + +type StringTuple2Array StringTuple2[]; + +type ClosedStringTuple2Array StringTuple2[3]; + +type StringTuple3Array StringTuple3[]; + +type ClosedStringTuple3Array StringTuple3[3]; + +type StringTuple4Array StringTuple4[]; + +type ClosedStringTuple4Array StringTuple4[3]; + +type AnydataTuple1Array AnydataTuple1[]; + +type ClosedAnydataTuple1Array AnydataTuple1[3]; + +type AnydataTuple2Array AnydataTuple2[]; + +type ClosedAnydataTuple2Array AnydataTuple2[3]; + +type AnydataTuple3Array AnydataTuple3[]; + +type ClosedAnydataTuple3Array AnydataTuple3[3]; + +type AnydataTuple4Array AnydataTuple4[]; + +type ClosedAnydataTuple4Array AnydataTuple4[3]; + +type JsonTuple1Array JsonTuple1[]; + +type ClosedJsonTuple1Array JsonTuple1[3]; + +type JsonTuple2Array JsonTuple2[]; + +type ClosedJsonTuple2Array JsonTuple2[3]; + +type JsonTuple3Array JsonTuple3[]; + +type ClosedJsonTuple3Array JsonTuple3[3]; + +type JsonTuple4Array JsonTuple4[]; + +type ClosedJsonTuple4Array JsonTuple4[3]; + +type CustomTuple1Array CustomTuple1[]; + +type ClosedCustomTuple1Array CustomTuple1[3]; + +type CustomTuple2Array CustomTuple2[]; + +type ClosedCustomTuple2Array CustomTuple2[3]; + +type CustomTuple3Array CustomTuple3[]; + +type ClosedCustomTuple3Array CustomTuple3[3]; + +type CustomTuple4Array CustomTuple4[]; + +type ClosedCustomTuple4Array CustomTuple4[3]; + +type CustomTuple5Array CustomTuple5[]; + +type ClosedCustomTuple5Array CustomTuple5[3]; + +type CustomTuple6Array CustomTuple6[]; + +type CustomTuple7Array CustomTuple7[]; + +type CustomTuple8Array CustomTuple8[]; + +type ClosedCustomTuple6Array CustomTuple6[3]; + +type IntegerArray1Array IntegerArray1[]; + +type ClosedIntegerArray1Array IntegerArray1[3]; + +type IntegerArray2Array IntegerArray2[]; + +type ClosedIntegerArray2Array IntegerArray2[3]; + +type IntegerArray3Array IntegerArray3[]; + +type ClosedIntegerArray3Array IntegerArray3[3]; + +type IntegerArray4Array IntegerArray4[]; + +type ClosedIntegerArray4Array IntegerArray4[3]; + +type IntegerArray5Array IntegerArray5[]; + +type ClosedIntegerArray5Array IntegerArray5[3]; + +type IntegerArray6Array IntegerArray5[]; + +type ClosedIntegerArray6Array IntegerArray5[3]; + +type StringArray1Array StringArray1[]; + +type StringArrayArray StringArray[]; + +type NillableStringArrayArray NillableStringArray[]; + +type NillableIntOrUnionStringArrayArray NillableIntOrUnionStringArray[]; + +type ClosedStringArray1Array StringArray1[3]; + +type StringArray2Array StringArray2[]; + +type ClosedStringArray2Array StringArray2[3]; + +type StringArray3Array StringArray3[]; + +type ClosedStringArray3Array StringArray3[3]; + +type StringArray4Array StringArray4[]; + +type ClosedStringArray4Array StringArray4[3]; + +type StringArray5Array StringArray5[]; + +type ClosedStringArray5Array StringArray5[3]; + +type StringArray6Array StringArray5[]; + +type ClosedStringArray6Array StringArray5[3]; + +type FloatArray1Array FloatArray1[]; + +type ClosedFloatArray1Array FloatArray1[3]; + +type FloatArray2Array FloatArray2[]; + +type ClosedFloatArray2Array FloatArray2[3]; + +type FloatArray3Array FloatArray3[]; + +type ClosedFloatArray3Array FloatArray3[3]; + +type FloatArray4Array FloatArray4[]; + +type ClosedFloatArray4Array FloatArray4[3]; + +type FloatArray5Array FloatArray5[]; + +type ClosedFloatArray5Array FloatArray5[3]; + +type FloatArray6Array FloatArray5[]; + +type ClosedFloatArray6Array FloatArray5[3]; + +type DecimalArray1Array DecimalArray1[]; + +type ClosedDecimalArray1Array DecimalArray1[3]; + +type DecimalArray2Array DecimalArray2[]; + +type ClosedDecimalArray2Array DecimalArray2[3]; + +type DecimalArray3Array DecimalArray3[]; + +type ClosedDecimalArray3Array DecimalArray3[3]; + +type DecimalArray4Array DecimalArray4[]; + +type ClosedDecimalArray4Array DecimalArray4[3]; + +type DecimalArray5Array DecimalArray5[]; + +type ClosedDecimalArray5Array DecimalArray5[3]; + +type DecimalArray6Array DecimalArray5[]; + +type ClosedDecimalArray6Array DecimalArray5[3]; + +type BooleanArrayArray BooleanArray[]; + +type ClosedBooleanArrayArray BooleanArray[3]; + +type NillableBooleanArrayArray NillableBooleanArray[]; + +type NillableIntOrUnionBooleanArrayArray NillableIntOrUnionBooleanArray[]; + +type BooleanArray2Array BooleanArray2[]; + +type ClosedBooleanArray2Array BooleanArray2[3]; + +type BooleanArray3Array BooleanArray3[]; + +type ClosedBooleanArray3Array BooleanArray3[3]; + +type BooleanArray4Array BooleanArray4[]; + +type ClosedBooleanArray4Array BooleanArray4[3]; + +type BooleanArray5Array BooleanArray5[]; + +type ClosedBooleanArray5Array BooleanArray5[3]; + +type BooleanArray6Array BooleanArray5[]; + +type ClosedBooleanArray6Array BooleanArray5[3]; + +type NilArray1Array NilArray1[]; + +type ClosedNilArray1Array NilArray1[3]; + +type NilArray2Array NilArray2[]; + +type ClosedNilArray2Array NilArray2[3]; + +type NilArray3Array NilArray3[]; + +type ClosedNilArray3Array NilArray3[3]; + +type NilArray4Array NilArray4[]; + +type ClosedNilArray4Array NilArray4[3]; + +type NilArray5Array NilArray5[]; + +type ClosedNilArray5Array NilArray5[3]; + +type NilArray6Array NilArray5[]; + +type ClosedNilArray6Array NilArray5[3]; + +type JsonArray1Array JsonArray1[]; + +type ClosedJsonArray1Array JsonArray1[3]; + +type JsonArray2Array JsonArray2[]; + +type ClosedJsonArray2Array JsonArray2[3]; + +type JsonArray3Array JsonArray3[]; + +type ClosedJsonArray3Array JsonArray3[3]; + +type JsonArray4Array JsonArray4[]; + +type ClosedJsonArray4Array JsonArray4[3]; + +type JsonArray5Array JsonArray5[]; + +type ClosedJsonArray5Array JsonArray5[3]; + +type JsonArray6Array JsonArray5[]; + +type ClosedJsonArray6Array JsonArray5[3]; + +type AnydataArray1Array AnydataArray1[]; + +type ClosedAnydataArray1Array AnydataArray1[3]; + +type AnydataArray2Array AnydataArray2[]; + +type ClosedAnydataArray2Array AnydataArray2[3]; + +type AnydataArray3Array AnydataArray3[]; + +type ClosedAnydataArray3Array AnydataArray3[3]; + +type AnydataArray4Array AnydataArray4[]; + +type ClosedAnydataArray4Array AnydataArray4[3]; + +type AnydataArray5Array AnydataArray5[]; + +type ClosedAnydataArray5Array AnydataArray5[3]; + +type AnydataArray6Array AnydataArray5[]; + +type ClosedAnydataArray6Array AnydataArray5[3]; + +type CustomArray1Array CustomArray1[]; + +type ClosedCustomArray1Array CustomArray1[3]; + +type CustomArray2Array CustomArray2[]; + +type ClosedCustomArray2Array CustomArray2[3]; + +type CustomArray3Array CustomArray3[]; + +type ClosedCustomArray3Array CustomArray3[3]; + +type CustomArray4Array CustomArray4[]; + +type ClosedCustomArray4Array CustomArray4[3]; + +type CustomArray5Array CustomArray5[]; + +type ClosedCustomArray5Array CustomArray5[3]; + +type CustomArray6Array CustomArray5[]; + +type ClosedCustomArray6Array CustomArray5[3]; + +type IntegerMapArray IntegerMap[]; + +type ClosedIntegerMapArray IntegerMap[3]; + +type StringMapArray StringMap[]; + +type NillableIntUnionStringMapArray NillableIntUnionStringMap[]; + +type IntUnionStringMapArray IntUnionStringMap[]; + +type ClosedStringMapArray StringMap[3]; + +type DecimalMapArray DecimalMap[]; + +type ClosedDecimalMapArray DecimalMap[3]; + +type FloatMapArray FloatMap[]; + +type ClosedFloatMapArray FloatMap[3]; + +type BooleanMapArray BooleanMap[]; + +type NillableBooleanMapArray NillableBooleanMap[]; + +type NillableIntUnionBooleanMapArray NillableIntUnionBooleanMap[]; + +type IntUnionBooleanMapArray IntUnionBooleanMap[]; + +type ClosedBooleanMapArray BooleanMap[3]; + +type NilMapArray NilMap[]; + +type ClosedNilMapArray NilMap[3]; + +type JsonMapArray JsonMap[]; + +type ClosedJsonMapArray JsonMap[3]; + +type AnydataMapArray AnydataMap[]; + +type ClosedAnydataMapArray AnydataMap[3]; + +type CustomMapArray CustomMap[]; + +type ClosedCustomMapArray CustomMap[3]; + diff --git a/ballerina-tests/parse-record-types-tests/.gitignore b/ballerina-tests/parse-record-types-tests/.gitignore new file mode 100644 index 0000000..d5fc29a --- /dev/null +++ b/ballerina-tests/parse-record-types-tests/.gitignore @@ -0,0 +1,11 @@ +# Ballerina generates this directory during the compilation of a package. +# It contains compiler-generated artifacts and the final executable if this is an application package. +target/ + +# Ballerina maintains the compiler-generated source code here. +# Remove this if you want to commit generated sources. +generated/ + +# Contains configuration values used during development time. +# See https://ballerina.io/learn/provide-values-to-configurable-variables/ for more details. +Config.toml diff --git a/ballerina-tests/parse-record-types-tests/Ballerina.toml b/ballerina-tests/parse-record-types-tests/Ballerina.toml new file mode 100644 index 0000000..508c204 --- /dev/null +++ b/ballerina-tests/parse-record-types-tests/Ballerina.toml @@ -0,0 +1,13 @@ +[package] +org = "ballerina" +name = "parse_record_types_tests" +version = "0.1.0" + +[[dependency]] +org = "ballerina" +name = "csv_commons" +repository = "local" +version = "0.1.0" + +[platform.java17] +graalvmCompatible = true diff --git a/ballerina-tests/parse-record-types-tests/Dependencies.toml b/ballerina-tests/parse-record-types-tests/Dependencies.toml new file mode 100644 index 0000000..54bfd11 --- /dev/null +++ b/ballerina-tests/parse-record-types-tests/Dependencies.toml @@ -0,0 +1,98 @@ +# AUTO-GENERATED FILE. DO NOT MODIFY. + +# This file is auto-generated by Ballerina for managing dependency versions. +# It should not be modified by hand. + +[ballerina] +dependencies-toml-version = "2" +distribution-version = "2201.9.0" + +[[package]] +org = "ballerina" +name = "csv_commons" +version = "0.1.0" +scope = "testOnly" +modules = [ + {org = "ballerina", packageName = "csv_commons", moduleName = "csv_commons"} +] + +[[package]] +org = "ballerina" +name = "data.csv" +version = "0.1.0" +scope = "testOnly" +dependencies = [ + {org = "ballerina", name = "jballerina.java"} +] +modules = [ + {org = "ballerina", packageName = "data.csv", moduleName = "data.csv"} +] + +[[package]] +org = "ballerina" +name = "jballerina.java" +version = "0.0.0" +scope = "testOnly" + +[[package]] +org = "ballerina" +name = "lang.__internal" +version = "0.0.0" +scope = "testOnly" +dependencies = [ + {org = "ballerina", name = "jballerina.java"}, + {org = "ballerina", name = "lang.object"} +] + +[[package]] +org = "ballerina" +name = "lang.array" +version = "0.0.0" +scope = "testOnly" +dependencies = [ + {org = "ballerina", name = "jballerina.java"}, + {org = "ballerina", name = "lang.__internal"} +] + +[[package]] +org = "ballerina" +name = "lang.error" +version = "0.0.0" +scope = "testOnly" +dependencies = [ + {org = "ballerina", name = "jballerina.java"} +] + +[[package]] +org = "ballerina" +name = "lang.object" +version = "0.0.0" +scope = "testOnly" + +[[package]] +org = "ballerina" +name = "parse_record_types_tests" +version = "0.1.0" +dependencies = [ + {org = "ballerina", name = "csv_commons"}, + {org = "ballerina", name = "data.csv"}, + {org = "ballerina", name = "test"} +] +modules = [ + {org = "ballerina", packageName = "parse_record_types_tests", moduleName = "parse_record_types_tests"} +] + +[[package]] +org = "ballerina" +name = "test" +version = "0.0.0" +scope = "testOnly" +dependencies = [ + {org = "ballerina", name = "jballerina.java"}, + {org = "ballerina", name = "lang.array"}, + {org = "ballerina", name = "lang.error"} +] +modules = [ + {org = "ballerina", packageName = "test", moduleName = "test"} +] + diff --git a/ballerina-tests/parse-record-types-tests/tests/parse_record_type_as_list_test.bal b/ballerina-tests/parse-record-types-tests/tests/parse_record_type_as_list_test.bal new file mode 100644 index 0000000..98f980c --- /dev/null +++ b/ballerina-tests/parse-record-types-tests/tests/parse_record_type_as_list_test.bal @@ -0,0 +1,540 @@ +import ballerina/csv_commons as common; +import ballerina/data.csv as csv; +import ballerina/test; + +@test:Config +function testFromCsvWithTypeForMapAndArrayAsExpectedType() { + BooleanArrayArray|csv:Error bm1ba = csv:parseRecordAsListType([bm1, bm1], ["b1", "b2"], {}, BooleanArrayArray); + test:assertEquals(bm1ba, [ + [true, false], + [true, false] + ]); + + bm1ba = csv:parseRecordAsListType([bm1, bm1], ["b2", "b1"], {}, BooleanArrayArray); + test:assertEquals(bm1ba, [ + [false, true], + [false, true] + ]); + + BooleanArrayArray|csv:Error bm2ba = csv:parseRecordAsListType([bm2, bm2], ["b1", "b2", "b3", "n1", "n3"], {}, BooleanArrayArray); + test:assertTrue(bm2ba is csv:Error); + test:assertEquals((bm2ba).message(), common:generateErrorMessageForInvalidValueForArrayType("null", "2", "boolean")); + + BooleanArrayArray|csv:Error bm3ba = csv:parseRecordAsListType([bm3, bm3], ["b1", "b2", "b3", "b4", "i1"], {}, BooleanArrayArray); + test:assertTrue(bm3ba is csv:Error); + test:assertEquals((bm3ba).message(), common:generateErrorMessageForInvalidValueForArrayType("null", "2", "boolean")); + + BooleanArrayArray|csv:Error bm4ba = csv:parseRecordAsListType([bm4, bm4], ["n1", "n3"], {}, BooleanArrayArray); + test:assertTrue(bm4ba is csv:Error); + test:assertEquals((bm4ba).message(), common:generateErrorMessageForInvalidValueForArrayType("null", "0", "boolean")); + + BooleanArrayArray|csv:Error bm5ba = csv:parseRecordAsListType([bm5, bm5], ["b1", "b2", "b3", "b4"], {}, BooleanArrayArray); + test:assertTrue(bm5ba is csv:Error); + test:assertEquals((bm5ba).message(), common:generateErrorMessageForInvalidValueForArrayType("null", "2", "boolean")); + + NillableBooleanArrayArray|csv:Error bm1nba = csv:parseRecordAsListType([bm1, bm1], ["b1", "b2"], {}, NillableBooleanArrayArray); + test:assertEquals(bm1nba, [ + [true, false], + [true, false] + ]); + + NillableBooleanArrayArray|csv:Error bm2nba = csv:parseRecordAsListType([bm2, bm2], ["b1", "b2", "b3", "n1", "n3"], {}, NillableBooleanArrayArray); + test:assertEquals(bm2nba, [ + [true, false, null, null, null], + [true, false, null, null, null] + ]); + + NillableBooleanArrayArray|csv:Error bm3nba = csv:parseRecordAsListType([bm3, bm3], ["b1", "b2", "b3", "b4", "i1"], {}, NillableBooleanArrayArray); + test:assertTrue(bm3nba is csv:Error); + test:assertEquals((bm3nba).message(), common:generateErrorMessageForInvalidValueForArrayType("1", "4", "boolean?")); + + NillableBooleanArrayArray|csv:Error bm4nba = csv:parseRecordAsListType([bm4, bm4], ["n1", "n3"], {}, NillableBooleanArrayArray); + test:assertEquals(bm4nba, [ + [(), ()], + [(), ()] + ]); + + NillableBooleanArrayArray|csv:Error bm5nba = csv:parseRecordAsListType([bm5, bm5], ["b1", "b2", "b3", "b4"], {}, NillableBooleanArrayArray); + test:assertEquals(bm5nba, [ + [true, false, (), true], + [true, false, (), true] + ]); + + bm5nba = csv:parseRecordAsListType([bm5, bm5], ["b1", "b3", "b2", "b4"], {}, NillableBooleanArrayArray); + test:assertEquals(bm5nba, [ + [true, (), false, true], + [true, (), false, true] + ]); + + bm5nba = csv:parseRecordAsListType([bm5, bm5], ["b4", "b3", "b2", "b1"], {}, NillableBooleanArrayArray); + test:assertEquals(bm5nba, [ + [true, (), false, true], + [true, (), false, true] + ]); + + NillableIntOrUnionBooleanArrayArray|csv:Error bm1niouba = csv:parseRecordAsListType([bm1, bm1], ["b1", "b2"], {}, NillableIntOrUnionBooleanArrayArray); + test:assertEquals(bm1niouba, [ + [true, false], + [true, false] + ]); + + NillableIntOrUnionBooleanArrayArray|csv:Error bm2niouba = csv:parseRecordAsListType([bm2, bm2], ["b1", "b2", "b3", "n1", "n3"], {}, NillableIntOrUnionBooleanArrayArray); + test:assertEquals(bm2niouba, [ + [true, false, null, null, null], + [true, false, null, null, null] + ]); + + NillableIntOrUnionBooleanArrayArray|csv:Error bm3niouba = csv:parseRecordAsListType([bm3, bm3], ["b1", "b2", "b3", "b4", "i1"], {}, NillableIntOrUnionBooleanArrayArray); + test:assertEquals(bm3niouba, [ + [true, false, null, false, 1], + [true, false, null, false, 1] + ]); + + NillableIntOrUnionBooleanArrayArray|csv:Error bm4niouba = csv:parseRecordAsListType([bm4, bm4], ["n1", "n3"], {}, NillableIntOrUnionBooleanArrayArray); + test:assertEquals(bm4niouba, [ + [(), ()], + [(), ()] + ]); + + NillableIntOrUnionBooleanArrayArray|csv:Error bm5niouba = csv:parseRecordAsListType([bm5, bm5], ["b1", "b2", "b3", "b4"], {}, NillableIntOrUnionBooleanArrayArray); + test:assertEquals(bm5niouba, [ + [true, false, (), true], + [true, false, (), true] + ]); + + JsonArray1Array|csv:Error bm1ja = csv:parseRecordAsListType([bm1, bm1], ["b1", "b2"], {}, JsonArray1Array); + test:assertEquals(bm1ja, [ + [true, false], + [true, false] + ]); +} + +@test:Config +function testFromCsvWithTypeForMapAndArrayAsExpectedType2() { + JsonArray1Array|csv:Error bm2ja = csv:parseRecordAsListType([bm2, bm2], ["b1", "b2", "b3", "n1", "n3"], {}, JsonArray1Array); + test:assertEquals(bm2ja, [ + [true, false, null, null, null], + [true, false, null, null, null] + ]); + + JsonArray1Array|csv:Error bm3ja = csv:parseRecordAsListType([bm3, bm3], ["b1", "b2", "b3", "b4", "i1"], {}, JsonArray1Array); + test:assertEquals(bm3ja, [ + [true, false, null, false, 1], + [true, false, null, false, 1] + ]); + + JsonArray1Array|csv:Error bm4ja = csv:parseRecordAsListType([bm4, bm4], ["n1", "n3"], {}, JsonArray1Array); + test:assertEquals(bm4ja, [ + [(), ()], + [(), ()] + ]); + + JsonArray1Array|csv:Error bm5ja = csv:parseRecordAsListType([bm5, bm5], ["b1", "b2", "b3", "b4"], {}, JsonArray1Array); + test:assertEquals(bm5ja, [ + [true, false, (), true], + [true, false, (), true] + ]); + + AnydataArray1Array|csv:Error bm1anyda = csv:parseRecordAsListType([bm1, bm1], ["b1", "b2"], {}, AnydataArray1Array); + test:assertEquals(bm1anyda, [ + [true, false], + [true, false] + ]); + + AnydataArray1Array|csv:Error bm2anyda = csv:parseRecordAsListType([bm2, bm2], ["b1", "b2", "b3", "n1", "n3"], {}, AnydataArray1Array); + test:assertEquals(bm2anyda, [ + [true, false, null, null, null], + [true, false, null, null, null] + ]); + + AnydataArray1Array|csv:Error bm3anyda = csv:parseRecordAsListType([bm3, bm3], ["b1", "b2", "b3", "b4", "i1"], {}, AnydataArray1Array); + test:assertEquals(bm3anyda, [ + [true, false, null, false, 1], + [true, false, null, false, 1] + ]); + + AnydataArray1Array|csv:Error bm4anyda = csv:parseRecordAsListType([bm4, bm4], ["n1", "n3"], {}, AnydataArray1Array); + test:assertEquals(bm4anyda, [ + [(), ()], + [(), ()] + ]); + + AnydataArray1Array|csv:Error bm5anyda = csv:parseRecordAsListType([bm5, bm5], ["b1", "b2", "b3", "b4"], {}, AnydataArray1Array); + test:assertEquals(bm5anyda, [ + [true, false, (), true], + [true, false, (), true] + ]); + + StringArray1Array|csv:Error bm1sa = csv:parseRecordAsListType([bm1, bm1], ["b1", "b2"], {}, StringArray1Array); + test:assertTrue(bm1sa is csv:Error); + test:assertEquals((bm1sa).message(), common:generateErrorMessageForInvalidValueForArrayType("true", "0", "string")); + + StringArray1Array|csv:Error bm2sa = csv:parseRecordAsListType([bm2, bm2], ["b1", "b2", "b3", "n1", "n3"], {}, StringArray1Array); + test:assertTrue(bm2sa is csv:Error); + test:assertEquals((bm2sa).message(), common:generateErrorMessageForInvalidValueForArrayType("true", "0", "string")); + + StringArray1Array|csv:Error bm3sa = csv:parseRecordAsListType([bm3, bm3], ["b1", "b2", "b3", "b4", "i1"], {}, StringArray1Array); + test:assertTrue(bm3sa is csv:Error); + test:assertEquals((bm3sa).message(), common:generateErrorMessageForInvalidValueForArrayType("true", "0", "string")); + + StringArray1Array|csv:Error bm4sa = csv:parseRecordAsListType([bm4, bm4], ["n1", "n3"], {}, StringArray1Array); + test:assertTrue(bm4sa is csv:Error); + test:assertEquals((bm4sa).message(), common:generateErrorMessageForInvalidValueForArrayType("null", "0", "string")); + + StringArray1Array|csv:Error bm5sa = csv:parseRecordAsListType([bm5, bm5], ["b1", "b2", "b3", "b4"], {}, StringArray1Array); + test:assertTrue(bm5sa is csv:Error); + test:assertEquals((bm5sa).message(), common:generateErrorMessageForInvalidValueForArrayType("true", "0", "string")); +} + +@test:Config +function testFromCsvWithTypeForMapAndTupleAsExpectedType() { + BooleanTuple1Array|csv:Error bm1bt = csv:parseRecordAsListType([bm1, bm1], ["b1", "b2"], {}, BooleanTuple1Array); + test:assertEquals(bm1bt, [ + [true, false, false, false], + [true, false, false, false] + ]); + + BooleanTuple1Array|csv:Error bm2bt = csv:parseRecordAsListType([bm2, bm2], ["b1", "b2", "b3", "n1", "n3"], {}, BooleanTuple1Array); + test:assertTrue(bm2bt is csv:Error); + test:assertEquals((bm2bt).message(), common:generateErrorMessageForInvalidValueForArrayType("null", "2", "boolean")); + + BooleanTuple1Array|csv:Error bm3bt = csv:parseRecordAsListType([bm3, bm3], ["b1", "b2", "b3", "b4", "i1"], {}, BooleanTuple1Array); + test:assertTrue(bm3bt is csv:Error); + test:assertEquals((bm3bt).message(), common:generateErrorMessageForInvalidValueForArrayType("null", "2", "boolean")); + + BooleanTuple1Array|csv:Error bm4bt = csv:parseRecordAsListType([bm4, bm4], ["n1", "n3"], {}, BooleanTuple1Array); + test:assertTrue(bm4bt is csv:Error); + test:assertEquals((bm4bt).message(), common:generateErrorMessageForInvalidValueForArrayType("null", "0", "boolean")); + + BooleanTuple1Array|csv:Error bm5bt = csv:parseRecordAsListType([bm5, bm5], ["b1", "b2", "b3", "b4"], {}, BooleanTuple1Array); + test:assertTrue(bm5bt is csv:Error); + test:assertEquals((bm5bt).message(), common:generateErrorMessageForInvalidValueForArrayType("null", "2", "boolean")); + + BooleanTuple2Array|csv:Error bm1b2t = csv:parseRecordAsListType([bm1, bm1], ["b1", "b2"], {}, BooleanTuple2Array); + test:assertEquals(bm1b2t, [ + [true, false], + [true, false] + ]); + + BooleanTuple2Array|csv:Error bm2b2t = csv:parseRecordAsListType([bm2, bm2], ["b1", "b2", "b3", "n1", "n3"], {}, BooleanTuple2Array); + test:assertEquals(bm2b2t, [ + [true, false], + [true, false] + ]); + + BooleanTuple2Array|csv:Error bm3b2t = csv:parseRecordAsListType([bm3, bm3], ["b1", "b2", "b3", "b4", "i1"], {}, BooleanTuple2Array); + test:assertEquals(bm3b2t, [ + [true, false], + [true, false] + ]); + + BooleanTuple2Array|csv:Error bm4b2t = csv:parseRecordAsListType([bm4, bm4], ["n1", "n3"], {}, BooleanTuple2Array); + test:assertTrue(bm4b2t is csv:Error); + test:assertEquals((bm4b2t).message(), common:generateErrorMessageForInvalidValueForArrayType("null", "0", "boolean")); + + BooleanTuple2Array|csv:Error bm5b2t = csv:parseRecordAsListType([bm5, bm5], ["b1", "b2", "b3", "b4"], {}, BooleanTuple2Array); + test:assertEquals(bm5b2t, [ + [true, false], + [true, false] + ]); + + BooleanTuple3Array|csv:Error bm1b3t = csv:parseRecordAsListType([bm1, bm1], ["b1", "b2"], {}, BooleanTuple3Array); + test:assertEquals(bm1b3t, [ + [true, false], + [true, false] + ]); + + BooleanTuple3Array|csv:Error bm2b3t = csv:parseRecordAsListType([bm2, bm2], ["b1", "b2", "b3", "n1", "n3"], {}, BooleanTuple3Array); + test:assertTrue(bm2b3t is csv:Error); + test:assertEquals((bm2b3t).message(), common:generateErrorMessageForInvalidValueForArrayType("null", "2", "boolean")); + + BooleanTuple3Array|csv:Error bm3b3t = csv:parseRecordAsListType([bm3, bm3], ["b1", "b2", "b3", "b4", "i1"], {}, BooleanTuple3Array); + test:assertTrue(bm3b3t is csv:Error); + test:assertEquals((bm3b3t).message(), common:generateErrorMessageForInvalidValueForArrayType("null", "2", "boolean")); + + BooleanTuple3Array|csv:Error bm4b3t = csv:parseRecordAsListType([bm4, bm4], ["n1", "n3"], {}, BooleanTuple3Array); + test:assertTrue(bm4b3t is csv:Error); + test:assertEquals((bm4b3t).message(), common:generateErrorMessageForInvalidValueForArrayType("null", "0", "boolean")); + + BooleanTuple3Array|csv:Error bm5b3t = csv:parseRecordAsListType([bm5, bm5], ["b1", "b2", "b3", "b4"], {}, BooleanTuple3Array); + test:assertTrue(bm5b3t is csv:Error); + test:assertEquals((bm5b3t).message(), common:generateErrorMessageForInvalidValueForArrayType("null", "2", "boolean")); + + BooleanTuple4Array|csv:Error bm1b4t = csv:parseRecordAsListType([bm1, bm1], ["b1", "b2"], {}, BooleanTuple4Array); + test:assertEquals(bm1b4t, [ + [true, false], + [true, false] + ]); + + BooleanTuple4Array|csv:Error bm2b4t = csv:parseRecordAsListType([bm2, bm2], ["b1", "b2", "b3", "n1", "n3"], {}, BooleanTuple4Array); + test:assertTrue(bm2b4t is csv:Error); + test:assertEquals((bm2b4t).message(), common:generateErrorMessageForInvalidValueForArrayType("null", "2", "boolean")); +} + +@test:Config +function testFromCsvWithTypeForMapAndTupleAsExpectedType2() { + BooleanTuple4Array|csv:Error bm3b4t = csv:parseRecordAsListType([bm3, bm3], ["b1", "b2", "b3", "b4", "i1"], {}, BooleanTuple4Array); + test:assertTrue(bm3b4t is csv:Error); + test:assertEquals((bm3b4t).message(), common:generateErrorMessageForInvalidValueForArrayType("null", "2", "boolean")); + + BooleanTuple4Array|csv:Error bm4b4t = csv:parseRecordAsListType([bm4, bm4], ["n1", "n3"], {}, BooleanTuple4Array); + test:assertTrue(bm4b4t is csv:Error); + test:assertEquals((bm4b4t).message(), common:generateErrorMessageForInvalidValueForArrayType("null", "0", "boolean")); + + BooleanTuple4Array|csv:Error bm5b4t = csv:parseRecordAsListType([bm5, bm5], ["b1", "b2", "b3", "b4"], {}, BooleanTuple4Array); + test:assertTrue(bm5b4t is csv:Error); + test:assertEquals((bm5b4t).message(), common:generateErrorMessageForInvalidValueForArrayType("null", "2", "boolean")); + + NillableBooleanTuple5Array|csv:Error bm1nbt = csv:parseRecordAsListType([bm1, bm1], ["b1", "b2"], {}, NillableBooleanTuple5Array); + test:assertEquals(bm1nbt, [ + [true, false, (), (), ()], + [true, false, (), (), ()] + ]); + + NillableBooleanTuple5Array|csv:Error bm2nbt = csv:parseRecordAsListType([bm2, bm2], ["b1", "b2", "b3", "n1", "n3"], {}, NillableBooleanTuple5Array); + test:assertEquals(bm2nbt, [ + [true, false, (), (), ()], + [true, false, (), (), ()] + ]); + + NillableBooleanTuple5Array|csv:Error bm3nbt = csv:parseRecordAsListType([bm3, bm3], ["b1", "b2", "b3", "b4", "i1"], {}, NillableBooleanTuple5Array); + test:assertTrue(bm3nbt is csv:Error); + test:assertEquals((bm3nbt).message(), common:generateErrorMessageForInvalidValueForArrayType("1", "4", "boolean?")); + + NillableBooleanTuple5Array|csv:Error bm4nbt = csv:parseRecordAsListType([bm4, bm4], ["n1", "n3"], {}, NillableBooleanTuple5Array); + test:assertEquals(bm4nbt, [ + [(), (), (), (), ()], + [(), (), (), (), ()] + ]); + + NillableBooleanTuple5Array|csv:Error bm5nbt = csv:parseRecordAsListType([bm5, bm5], ["b1", "b2", "b3", "b4"], {}, NillableBooleanTuple5Array); + test:assertEquals(bm5nbt, [ + [true, false, (), true, ()], + [true, false, (), true, ()] + ]); + + NillableBooleanTuple6Array|csv:Error bm1nb6t = csv:parseRecordAsListType([bm1, bm1], ["b1", "b2"], {}, NillableBooleanTuple6Array); + test:assertEquals(bm1nb6t, [ + [true, false], + [true, false] + ]); + + NillableBooleanTuple6Array|csv:Error bm2nb6t = csv:parseRecordAsListType([bm2, bm2], ["b1", "b2", "b3", "n1", "n3"], {}, NillableBooleanTuple6Array); + test:assertEquals(bm2nb6t, [ + [true, false], + [true, false] + ]); + + NillableBooleanTuple6Array|csv:Error bm3nb6t = csv:parseRecordAsListType([bm3, bm3], ["b1", "b2", "b3", "b4", "i1"], {}, NillableBooleanTuple6Array); + test:assertEquals(bm3nb6t, [ + [true, false], + [true, false] + ]); + + NillableBooleanTuple6Array|csv:Error bm4nb6t = csv:parseRecordAsListType([bm4, bm4], ["n1", "n3"], {}, NillableBooleanTuple6Array); + test:assertEquals(bm4nb6t, [ + [(), ()], + [(), ()] + ]); + + NillableBooleanTuple6Array|csv:Error bm5nb6t = csv:parseRecordAsListType([bm5, bm5], ["b1", "b2", "b3", "b4"], {}, NillableBooleanTuple6Array); + test:assertEquals(bm5nb6t, [ + [true, false], + [true, false] + ]); + + NillableBooleanTuple7Array|csv:Error bm1nb7t = csv:parseRecordAsListType([bm1, bm1], ["b1", "b2"], {}, NillableBooleanTuple7Array); + test:assertEquals(bm1nb7t, [ + [true, false], + [true, false] + ]); + + NillableBooleanTuple7Array|csv:Error bm2nb7t = csv:parseRecordAsListType([bm2, bm2], ["b1", "b2", "b3", "n1", "n3"], {}, NillableBooleanTuple7Array); + test:assertEquals(bm2nb7t, [ + [true, false, (), (), ()], + [true, false, (), (), ()] + ]); + + NillableBooleanTuple7Array|csv:Error bm3nb7t = csv:parseRecordAsListType([bm3, bm3], ["b1", "b2", "b3", "b4", "i1"], {}, NillableBooleanTuple7Array); + test:assertTrue(bm3nb7t is csv:Error); + test:assertEquals((bm3nb7t).message(), common:generateErrorMessageForInvalidValueForArrayType("1", "4", "boolean?")); + + NillableBooleanTuple7Array|csv:Error bm4nb7t = csv:parseRecordAsListType([bm4, bm4], ["n1", "n3"], {}, NillableBooleanTuple7Array); + test:assertEquals(bm4nb7t, [ + [(), ()], + [(), ()] + ]); + + NillableBooleanTuple7Array|csv:Error bm5nb7t = csv:parseRecordAsListType([bm5, bm5], ["b1", "b2", "b3", "b4"], {}, NillableBooleanTuple7Array); + test:assertEquals(bm5nb7t, [ + [true, false, (), true], + [true, false, (), true] + ]); +} + +@test:Config +function testFromCsvWithTypeForMapAndTupleAsExpectedType3() { + NillableBooleanTuple8Array|csv:Error bm1nb8t = csv:parseRecordAsListType([bm1, bm1], ["b1", "b2"], {}, NillableBooleanTuple8Array); + test:assertEquals(bm1nb8t, [ + [true, false], + [true, false] + ]); + + NillableBooleanTuple8Array|csv:Error bm2nb8t = csv:parseRecordAsListType([bm2, bm2], ["b1", "b2", "b3", "n1", "n3"], {}, NillableBooleanTuple8Array); + test:assertEquals(bm2nb8t, [ + [true, false, (), (), ()], + [true, false, (), (), ()] + ]); + + NillableBooleanTuple8Array|csv:Error bm3nb8t = csv:parseRecordAsListType([bm3, bm3], ["b1", "b2", "b3", "b4", "i1"], {}, NillableBooleanTuple8Array); + test:assertTrue(bm3nb8t is csv:Error); + test:assertEquals((bm3nb8t).message(), common:generateErrorMessageForInvalidValueForArrayType("1", "4", "boolean?")); + + NillableBooleanTuple8Array|csv:Error bm4nb8t = csv:parseRecordAsListType([bm4, bm4], ["n1", "n3"], {}, NillableBooleanTuple8Array); + test:assertEquals(bm4nb8t, [ + [(), ()], + [(), ()] + ]); + + NillableBooleanTuple8Array|csv:Error bm5nb8t = csv:parseRecordAsListType([bm5, bm5], ["b1", "b2", "b3", "b4"], {}, NillableBooleanTuple8Array); + test:assertEquals(bm5nb8t, [ + [true, false, (), true], + [true, false, (), true] + ]); + + NillableIntBooleanTuple9Array|csv:Error bm1nb9t = csv:parseRecordAsListType([bm1, bm1], ["b1", "b2"], {}, NillableIntBooleanTuple9Array); + test:assertEquals(bm1nb9t, [ + [true, false], + [true, false] + ]); + + NillableIntBooleanTuple9Array|csv:Error bm2nb9t = csv:parseRecordAsListType([bm2, bm2], ["b1", "b2", "b3", "n1", "n3"], {}, NillableIntBooleanTuple9Array); + test:assertEquals(bm2nb9t, [ + [true, false, (), (), ()], + [true, false, (), (), ()] + ]); + + NillableIntBooleanTuple9Array|csv:Error bm3nb9t = csv:parseRecordAsListType([bm3, bm3], ["b1", "b2", "b3", "b4", "i1"], {}, NillableIntBooleanTuple9Array); + test:assertEquals(bm3nb9t, [ + [true, false, (), false, 1], + [true, false, (), false, 1] + ]); + + NillableIntBooleanTuple9Array|csv:Error bm4nb9t = csv:parseRecordAsListType([bm4, bm4], ["n1", "n3"], {}, NillableIntBooleanTuple9Array); + test:assertEquals(bm4nb9t, [ + [(), ()], + [(), ()] + ]); + + NillableIntBooleanTuple9Array|csv:Error bm5nb9t = csv:parseRecordAsListType([bm5, bm5], ["b1", "b2", "b3", "b4"], {}, NillableIntBooleanTuple9Array); + test:assertEquals(bm5nb9t, [ + [true, false, (), true], + [true, false, (), true] + ]); + + NilTuple3Array|csv:Error bm1n3t = csv:parseRecordAsListType([bm1, bm1], ["b1", "b2"], {}, NilTuple3Array); + test:assertTrue(bm1n3t is csv:Error); + test:assertEquals((bm1n3t).message(), common:generateErrorMessageForInvalidValueForArrayType("true", "0", "()")); + + NilTuple3Array|csv:Error bm2n3t = csv:parseRecordAsListType([bm2, bm2], ["b1", "b2", "b3", "n1", "n3"], {}, NilTuple3Array); + test:assertTrue(bm2n3t is csv:Error); + test:assertEquals((bm2n3t).message(), common:generateErrorMessageForInvalidValueForArrayType("true", "0", "()")); + + NilTuple3Array|csv:Error bm3n3t = csv:parseRecordAsListType([bm3, bm3], ["b1", "b2", "b3", "b4", "i1"], {}, NilTuple3Array); + test:assertTrue(bm3n3t is csv:Error); + test:assertEquals((bm3n3t).message(), common:generateErrorMessageForInvalidValueForArrayType("true", "0", "()")); + + NilTuple3Array|csv:Error bm4n3t = csv:parseRecordAsListType([bm4, bm4], ["n1", "n3"], {}, NilTuple3Array); + test:assertEquals(bm4n3t, [ + [(), ()], + [(), ()] + ]); + + NilTuple3Array|csv:Error bm5n3t = csv:parseRecordAsListType([bm5, bm5], ["b1", "b2", "b3", "b4"], {}, NilTuple3Array); + test:assertTrue(bm5n3t is csv:Error); + test:assertEquals((bm5n3t).message(), common:generateErrorMessageForInvalidValueForArrayType("true", "0", "()")); +} + +@test:Config +function testFromCsvWithTypeForMapAndArrayAsExpectedType3() { + + AnydataTuple3Array|csv:Error bm1anyd3t = csv:parseRecordAsListType([bm1, bm1], ["b1", "b2"], {}, AnydataTuple3Array); + test:assertEquals(bm1anyd3t, [ + [true, false], + [true, false] + ]); + + AnydataTuple3Array|csv:Error bm2anyd3t = csv:parseRecordAsListType([bm2, bm2], ["b1", "b2", "b3", "n1", "n3"], {}, AnydataTuple3Array); + test:assertEquals(bm2anyd3t, [ + [true, false, (), (), ()], + [true, false, (), (), ()] + ]); + + AnydataTuple3Array|csv:Error bm3anyd3t = csv:parseRecordAsListType([bm3, bm3], ["b1", "b2", "b3", "b4", "i1"], {}, AnydataTuple3Array); + test:assertEquals(bm3anyd3t, [ + [true, false, (), false, 1], + [true, false, (), false, 1] + ]); + + AnydataTuple3Array|csv:Error bm4anyd3t = csv:parseRecordAsListType([bm4, bm4], ["n1", "n3"], {}, AnydataTuple3Array); + test:assertEquals(bm4anyd3t, [ + [(), ()], + [(), ()] + ]); + + AnydataTuple3Array|csv:Error bm5anyd3t = csv:parseRecordAsListType([bm5, bm5], ["b1", "b2", "b3", "b4"], {}, AnydataTuple3Array); + test:assertEquals(bm5anyd3t, [ + [true, false, (), true], + [true, false, (), true] + ]); + + JsonTuple3Array|csv:Error bm1j3t = csv:parseRecordAsListType([bm1, bm1], ["b1", "b2"], {}, JsonTuple3Array); + test:assertEquals(bm1j3t, [ + [true, false], + [true, false] + ]); + + JsonTuple3Array|csv:Error bm2j3t = csv:parseRecordAsListType([bm2, bm2], ["b1", "b2", "b3", "n1", "n3"], {}, JsonTuple3Array); + test:assertEquals(bm2j3t, [ + [true, false, (), (), ()], + [true, false, (), (), ()] + ]); + + JsonTuple3Array|csv:Error bm3j3t = csv:parseRecordAsListType([bm3, bm3], ["b1", "b2", "b3", "b4", "i1"], {}, JsonTuple3Array); + test:assertEquals(bm3j3t, [ + [true, false, (), false, 1], + [true, false, (), false, 1] + ]); + + JsonTuple3Array|csv:Error bm4j3t = csv:parseRecordAsListType([bm4, bm4], ["n1", "n3"], {}, JsonTuple3Array); + test:assertEquals(bm4j3t, [ + [(), ()], + [(), ()] + ]); + + JsonTuple3Array|csv:Error bm5j3t = csv:parseRecordAsListType([bm5, bm5], ["b1", "b2", "b3", "b4"], {}, JsonTuple3Array); + test:assertEquals(bm5j3t, [ + [true, false, (), true], + [true, false, (), true] + ]); + + StringTuple3Array|csv:Error bm1s3t = csv:parseRecordAsListType([bm1, bm1], ["b1", "b2"], {}, StringTuple3Array); + test:assertTrue(bm1s3t is csv:Error); + test:assertEquals((bm1s3t).message(), common:generateErrorMessageForInvalidValueForArrayType("true", "0", "string")); + + StringTuple3Array|csv:Error bm2s3t = csv:parseRecordAsListType([bm2, bm2], ["b1", "b2", "b3", "n1", "n3"], {}, StringTuple3Array); + test:assertTrue(bm2s3t is csv:Error); + test:assertEquals((bm2s3t).message(), common:generateErrorMessageForInvalidValueForArrayType("true", "0", "string")); + + StringTuple3Array|csv:Error bm3s3t = csv:parseRecordAsListType([bm3, bm3], ["b1", "b2", "b3", "b4", "i1"], {}, StringTuple3Array); + test:assertTrue(bm3s3t is csv:Error); + test:assertEquals((bm3s3t).message(), common:generateErrorMessageForInvalidValueForArrayType("true", "0", "string")); + + StringTuple3Array|csv:Error bm4s3t = csv:parseRecordAsListType([bm4, bm4], ["n1", "n3"], {}, StringTuple3Array); + test:assertTrue(bm4s3t is csv:Error); + test:assertEquals((bm4s3t).message(), common:generateErrorMessageForInvalidValueForArrayType("null", "0", "string")); + + StringTuple3Array|csv:Error bm5s3t = csv:parseRecordAsListType([bm5, bm5], ["b1", "b2", "b3", "b4"], {}, StringTuple3Array); + test:assertTrue(bm5s3t is csv:Error); + test:assertEquals((bm5s3t).message(), common:generateErrorMessageForInvalidValueForArrayType("true", "0", "string")); +} diff --git a/ballerina-tests/parse-record-types-tests/tests/parse_record_type_as_record_test.bal b/ballerina-tests/parse-record-types-tests/tests/parse_record_type_as_record_test.bal new file mode 100644 index 0000000..a1373ae --- /dev/null +++ b/ballerina-tests/parse-record-types-tests/tests/parse_record_type_as_record_test.bal @@ -0,0 +1,733 @@ +import ballerina/csv_commons as common; +import ballerina/data.csv as csv; +import ballerina/test; + +@test:Config +function testFromCsvWithTypeForMapAndRecordAsExpectedType() { + BooleanRecord1Array|csv:Error bm1br1 = csv:parseRecordAsRecordType([bm1, bm1], {}, BooleanRecord1Array); + test:assertTrue(bm1br1 is csv:Error); + test:assertEquals((bm1br1).message(), common:generateErrorMessageForMissingRequiredField("b3")); + + BooleanRecord1Array|csv:Error bm2br1 = csv:parseRecordAsRecordType([bm2, bm2], {}, BooleanRecord1Array); + test:assertTrue(bm2br1 is csv:Error); + test:assertEquals((bm2br1).message(), common:generateErrorMessageForMissingRequiredField("b4")); + + BooleanRecord1Array|csv:Error bm3br1 = csv:parseRecordAsRecordType([bm3, bm3], {}, BooleanRecord1Array); + test:assertEquals(bm3br1, [ + {b1: true, b2: false, b3: (), b4: false, i1: 1}, + {b1: true, b2: false, b3: (), b4: false, i1: 1} + ]); + + BooleanRecord1Array|csv:Error bm4br1 = csv:parseRecordAsRecordType([bm4, bm4], {}, BooleanRecord1Array); + test:assertTrue(bm4br1 is csv:Error); + test:assertEquals((bm4br1).message(), common:generateErrorMessageForMissingRequiredField("b2")); + + BooleanRecord1Array|csv:Error bm5br1 = csv:parseRecordAsRecordType([bm5, bm5], {}, BooleanRecord1Array); + test:assertEquals(bm5br1, [ + {b1: true, b2: false, b3: (), b4: true}, + {b1: true, b2: false, b3: (), b4: true} + ]); + + BooleanRecord2Array|csv:Error bm1br2 = csv:parseRecordAsRecordType([bm1, bm1], {}, BooleanRecord2Array); + test:assertTrue(bm1br2 is csv:Error); + test:assertEquals((bm1br2).message(), common:generateErrorMessageForMissingRequiredField("b3")); + + BooleanRecord2Array|csv:Error bm2br2 = csv:parseRecordAsRecordType([bm2, bm2], {}, BooleanRecord2Array); + test:assertTrue(bm2br2 is csv:Error); + test:assertEquals((bm2br2).message(), common:generateErrorMessageForMissingRequiredField("b4")); + + BooleanRecord2Array|csv:Error bm3br2 = csv:parseRecordAsRecordType([bm3, bm3], {}, BooleanRecord2Array); + test:assertEquals(bm3br2, [ + {b1: true, b2: false, b3: (), b4: false}, + {b1: true, b2: false, b3: (), b4: false} + ]); + + BooleanRecord2Array|csv:Error bm4br2 = csv:parseRecordAsRecordType([bm4, bm4], {}, BooleanRecord2Array); + test:assertTrue(bm4br2 is csv:Error); + test:assertEquals((bm4br2).message(), common:generateErrorMessageForMissingRequiredField("b2")); + + BooleanRecord2Array|csv:Error bm5br2 = csv:parseRecordAsRecordType([bm5, bm5], {}, BooleanRecord2Array); + test:assertEquals(bm5br2, [ + {b1: true, b2: false, b3: (), b4: true}, + {b1: true, b2: false, b3: (), b4: true} + ]); + + BooleanRecord3Array|csv:Error bm1br3 = csv:parseRecordAsRecordType([bm1, bm1], {}, BooleanRecord3Array); + test:assertTrue(bm1br3 is csv:Error); + test:assertEquals((bm1br3).message(), common:generateErrorMessageForMissingRequiredField("b3")); + + BooleanRecord3Array|csv:Error bm2br3 = csv:parseRecordAsRecordType([bm2, bm2], {}, BooleanRecord3Array); + test:assertEquals(bm2br3, [ + {b1: true, b3: ()}, + {b1: true, b3: ()} + ]); + + BooleanRecord3Array|csv:Error bm3br3 = csv:parseRecordAsRecordType([bm3, bm3], {}, BooleanRecord3Array); + test:assertEquals(bm3br3, [ + {b1: true, b3: ()}, + {b1: true, b3: ()} + ]); + + BooleanRecord3Array|csv:Error bm4br3 = csv:parseRecordAsRecordType([bm4, bm4], {}, BooleanRecord3Array); + test:assertTrue(bm4br3 is csv:Error); + test:assertEquals((bm4br3).message(), common:generateErrorMessageForMissingRequiredField("b3")); + + BooleanRecord3Array|csv:Error bm5br3 = csv:parseRecordAsRecordType([bm5, bm5], {}, BooleanRecord3Array); + test:assertEquals(bm5br3, [{b1: true, b3: ()}, {b1: true, b3: ()}]); + + BooleanRecord4Array|csv:Error bm1br4 = csv:parseRecordAsRecordType([bm1, bm1], {}, BooleanRecord4Array); + test:assertTrue(bm1br4 is csv:Error); + test:assertEquals((bm1br4).message(), common:generateErrorMessageForMissingRequiredField("b3")); + + BooleanRecord4Array|csv:Error bm2br4 = csv:parseRecordAsRecordType([bm2, bm2], {}, BooleanRecord4Array); + test:assertEquals(bm2br4, [ + {b1: true, b2: false, b3: (), n1: (), n3: ()}, + {b1: true, b2: false, b3: (), n1: (), n3: ()} + ]); + + BooleanRecord4Array|csv:Error bm3br4 = csv:parseRecordAsRecordType([bm3, bm3], {}, BooleanRecord4Array); + test:assertEquals(bm3br4, [ + {b1: true, b2: false, b3: (), b4: false, i1: 1}, + {b1: true, b2: false, b3: (), b4: false, i1: 1} + ]); + + BooleanRecord4Array|csv:Error bm4br4 = csv:parseRecordAsRecordType([bm4, bm4], {}, BooleanRecord4Array); + test:assertTrue(bm4br4 is csv:Error); + test:assertEquals((bm4br4).message(), common:generateErrorMessageForMissingRequiredField("b3")); + + BooleanRecord4Array|csv:Error bm5br4 = csv:parseRecordAsRecordType([bm5, bm5], {}, BooleanRecord4Array); + test:assertEquals(bm5br4, [ + {b1: true, b2: false, b3: (), b4: true}, + {b1: true, b2: false, b3: (), b4: true} + ]); + + BooleanRecord5Array|csv:Error bm1br5 = csv:parseRecordAsRecordType([bm1, bm1], {}, BooleanRecord5Array); + test:assertTrue(bm1br5 is csv:Error); + test:assertEquals((bm1br5).message(), common:generateErrorMessageForMissingRequiredField("b3")); + + BooleanRecord5Array|csv:Error bm2br5 = csv:parseRecordAsRecordType([bm2, bm2], {}, BooleanRecord5Array); + test:assertEquals(bm2br5, [ + {b1: true, b3: (), defaultableField: "", nillableField: (), b2: false, n1: (), n3: ()}, + {b1: true, b3: (), defaultableField: "", nillableField: (), b2: false, n1: (), n3: ()} + ]); +} + +@test:Config +function testFromCsvWithTypeForMapAndRecordAsExpectedType2() { + BooleanRecord5Array|csv:Error bm3br5 = csv:parseRecordAsRecordType([bm3, bm3], {}, BooleanRecord5Array); + test:assertEquals(bm3br5, [ + {b1: true, b3: (), defaultableField: "", nillableField: (), b2: false, i1: 1, b4: false}, + {b1: true, b3: (), defaultableField: "", nillableField: (), b2: false, i1: 1, b4: false} + ]); + + BooleanRecord5Array|csv:Error bm4br5 = csv:parseRecordAsRecordType([bm4, bm4], {}, BooleanRecord5Array); + test:assertTrue(bm4br5 is csv:Error); + test:assertEquals((bm4br5).message(), common:generateErrorMessageForMissingRequiredField("b3")); + + BooleanRecord5Array|csv:Error bm5br5 = csv:parseRecordAsRecordType([bm5, bm5], {}, BooleanRecord5Array); + test:assertEquals(bm5br5, [ + {b1: true, b2: false, b3: (), b4: true, defaultableField: "", nillableField: ()}, + {b1: true, b2: false, b3: (), b4: true, defaultableField: "", nillableField: ()} + ]); + + BooleanRecord6Array|csv:Error bm1br6 = csv:parseRecordAsRecordType([bm1, bm1], {}, BooleanRecord6Array); + test:assertTrue(bm1br6 is csv:Error); + test:assertEquals((bm1br6).message(), common:generateErrorMessageForMissingRequiredField("b3")); + + BooleanRecord6Array|csv:Error bm2br6 = csv:parseRecordAsRecordType([bm2, bm2], {}, BooleanRecord6Array); + test:assertEquals(bm2br6, [ + {b1: true, b3: (), defaultableField: "", nillableField: ()}, + {b1: true, b3: (), defaultableField: "", nillableField: ()} + ]); + + BooleanRecord6Array|csv:Error bm3br6 = csv:parseRecordAsRecordType([bm3, bm3], {}, BooleanRecord6Array); + test:assertEquals(bm3br6, [ + {b1: true, b3: (), defaultableField: "", nillableField: ()}, + {b1: true, b3: (), defaultableField: "", nillableField: ()} + ]); + + BooleanRecord6Array|csv:Error bm4br6 = csv:parseRecordAsRecordType([bm4, bm4], {}, BooleanRecord6Array); + test:assertTrue(bm4br6 is csv:Error); + test:assertEquals((bm4br6).message(), common:generateErrorMessageForMissingRequiredField("b3")); + + BooleanRecord6Array|csv:Error bm5br6 = csv:parseRecordAsRecordType([bm5, bm5], {}, BooleanRecord6Array); + test:assertEquals(bm5br6, [ + {b1: true, b3: (), defaultableField: "", nillableField: ()}, + {b1: true, b3: (), defaultableField: "", nillableField: ()} + ]); + + BooleanRecord7Array|csv:Error bm1br7 = csv:parseRecordAsRecordType([bm1, bm1], {}, BooleanRecord7Array); + test:assertTrue(bm1br7 is csv:Error); + test:assertEquals((bm1br7).message(), common:generateErrorMessageForMissingRequiredField("b3")); + + BooleanRecord7Array|csv:Error bm2br7 = csv:parseRecordAsRecordType([bm2, bm2], {}, BooleanRecord7Array); + test:assertTrue(bm2br7 is csv:Error); + test:assertEquals((bm2br7).message(), common:generateErrorMessageForMissingRequiredField("requiredField")); + + BooleanRecord7Array|csv:Error bm3br7 = csv:parseRecordAsRecordType([bm3, bm3], {}, BooleanRecord7Array); + test:assertTrue(bm3br7 is csv:Error); + test:assertEquals((bm3br7).message(), common:generateErrorMessageForMissingRequiredField("requiredField")); + + BooleanRecord7Array|csv:Error bm4br7 = csv:parseRecordAsRecordType([bm4, bm4], {}, BooleanRecord7Array); + test:assertTrue(bm4br7 is csv:Error); + test:assertEquals((bm4br7).message(), common:generateErrorMessageForMissingRequiredField("b3")); + + BooleanRecord7Array|csv:Error bm5br7 = csv:parseRecordAsRecordType([bm5, bm5], {}, BooleanRecord7Array); + test:assertTrue(bm5br7 is csv:Error); + test:assertEquals((bm5br7).message(), common:generateErrorMessageForMissingRequiredField("requiredField")); + + BooleanRecord8Array|csv:Error bm1br8 = csv:parseRecordAsRecordType([bm1, bm1], {}, BooleanRecord8Array); + test:assertTrue(bm1br8 is csv:Error); + test:assertEquals((bm1br8).message(), common:generateErrorMessageForMissingRequiredField("b3")); + + BooleanRecord8Array|csv:Error bm2br8 = csv:parseRecordAsRecordType([bm2, bm2], {}, BooleanRecord8Array); + test:assertTrue(bm2br8 is csv:Error); + test:assertEquals((bm2br8).message(), common:generateErrorMessageForMissingRequiredField("requiredField")); + + BooleanRecord8Array|csv:Error bm3br8 = csv:parseRecordAsRecordType([bm3, bm3], {}, BooleanRecord8Array); + test:assertTrue(bm3br8 is csv:Error); + test:assertEquals((bm3br8).message(), common:generateErrorMessageForMissingRequiredField("requiredField")); + + BooleanRecord8Array|csv:Error bm4br8 = csv:parseRecordAsRecordType([bm4, bm4], {}, BooleanRecord8Array); + test:assertTrue(bm4br8 is csv:Error); + test:assertEquals((bm4br8).message(), common:generateErrorMessageForMissingRequiredField("b3")); + + BooleanRecord8Array|csv:Error bm5br8 = csv:parseRecordAsRecordType([bm5, bm5], {}, BooleanRecord8Array); + test:assertTrue(bm5br8 is csv:Error); + test:assertEquals((bm5br8).message(), common:generateErrorMessageForMissingRequiredField("requiredField")); +} + +@test:Config +function testFromCsvWithTypeForMapAndRecordAsExpectedType3() { + BooleanRecord9Array|csv:Error bm1br9 = csv:parseRecordAsRecordType([bm1, bm1], {}, BooleanRecord9Array); + test:assertTrue(bm1br9 is csv:Error); + test:assertEquals((bm1br9).message(), common:generateErrorMessageForMissingRequiredField("b3")); + + BooleanRecord9Array|csv:Error bm2br9 = csv:parseRecordAsRecordType([bm2, bm2], {}, BooleanRecord9Array); + test:assertEquals(bm2br9, [ + {b1: true, b2: false, b3: (), n1: (), n3: ()}, + {b1: true, b2: false, b3: (), n1: (), n3: ()} + ]); + + BooleanRecord9Array|csv:Error bm3br9 = csv:parseRecordAsRecordType([bm3, bm3], {}, BooleanRecord9Array); + test:assertEquals(bm3br9, [ + {b1: true, b2: false, b3: (), b4: false}, + {b1: true, b2: false, b3: (), b4: false} + ]); + + BooleanRecord9Array|csv:Error bm4br9 = csv:parseRecordAsRecordType([bm4, bm4], {}, BooleanRecord9Array); + test:assertTrue(bm4br9 is csv:Error); + test:assertEquals((bm4br9).message(), common:generateErrorMessageForMissingRequiredField("b3")); + + BooleanRecord9Array|csv:Error bm5br9 = csv:parseRecordAsRecordType([bm5, bm5], {}, BooleanRecord9Array); + test:assertEquals(bm5br9, [ + {b1: true, b2: false, b3: (), b4: true}, + {b1: true, b2: false, b3: (), b4: true} + ]); + + BooleanRecord10Array|csv:Error bm1br10 = csv:parseRecordAsRecordType([bm1, bm1], {}, BooleanRecord10Array); + test:assertEquals(bm1br10, [ + {b1: true, b2: false}, + {b1: true, b2: false} + ]); + + BooleanRecord10Array|csv:Error bm2br10 = csv:parseRecordAsRecordType([bm2, bm2], {}, BooleanRecord10Array); + test:assertEquals(bm2br10, [ + {b1: true, b2: false}, + {b1: true, b2: false} + ]); + + BooleanRecord10Array|csv:Error bm3br10 = csv:parseRecordAsRecordType([bm3, bm3], {}, BooleanRecord10Array); + test:assertEquals(bm3br10, [ + {b1: true, b2: false, b4: false}, + {b1: true, b2: false, b4: false} + ]); + + BooleanRecord10Array|csv:Error bm4br10 = csv:parseRecordAsRecordType([bm4, bm4], {}, BooleanRecord10Array); + test:assertEquals(bm4br10, [ + {}, + {} + ]); + + BooleanRecord10Array|csv:Error bm5br10 = csv:parseRecordAsRecordType([bm5, bm5], {}, BooleanRecord10Array); + test:assertEquals(bm5br10, [ + {b1: true, b2: false, b4: true}, + {b1: true, b2: false, b4: true} + ]); + + BooleanRecord11Array|csv:Error bm1br11 = csv:parseRecordAsRecordType([bm1, bm1], {}, BooleanRecord11Array); + test:assertEquals(bm1br11, [ + {b1: true, b2: false, defaultableField: "", nillableField :null}, + {b1: true, b2: false, defaultableField: "", nillableField :null} + ]); + + BooleanRecord11Array|csv:Error bm2br11 = csv:parseRecordAsRecordType([bm2, bm2], {}, BooleanRecord11Array); + test:assertEquals(bm2br11, [ + {b1: true, b2: false, b3: (), n1: (), n3: (), defaultableField: "", nillableField :null}, + {b1: true, b2: false, b3: (), n1: (), n3: (), defaultableField: "", nillableField :null} + ]); + + BooleanRecord11Array|csv:Error bm3br11 = csv:parseRecordAsRecordType([bm3, bm3], {}, BooleanRecord11Array); + test:assertEquals(bm3br11, [ + {b1: true, b2: false, b3: (), b4: false, defaultableField: "", nillableField :null}, + {b1: true, b2: false, b3: (), b4: false, defaultableField: "", nillableField :null} + ]); + + BooleanRecord11Array|csv:Error bm4br11 = csv:parseRecordAsRecordType([bm4, bm4], {}, BooleanRecord11Array); + test:assertTrue(bm4br11 is csv:Error); + test:assertEquals((bm4br11).message(), common:generateErrorMessageForMissingRequiredField("b1")); + + BooleanRecord11Array|csv:Error bm5br11 = csv:parseRecordAsRecordType([bm5, bm5], {}, BooleanRecord11Array); + test:assertEquals(bm5br11, [ + {b1: true, b2: false, b3: (), b4: true, defaultableField: "", nillableField :null}, + {b1: true, b2: false, b3: (), b4: true, defaultableField: "", nillableField :null} + ]); + + BooleanRecord12Array|csv:Error bm1br12 = csv:parseRecordAsRecordType([bm1, bm1], {}, BooleanRecord12Array); + test:assertTrue(bm1br12 is csv:Error); + test:assertEquals((bm1br12).message(), common:generateErrorMessageForMissingRequiredField("requiredField")); + + BooleanRecord12Array|csv:Error bm2br12 = csv:parseRecordAsRecordType([bm2, bm2], {}, BooleanRecord12Array); + test:assertTrue(bm2br12 is csv:Error); + test:assertEquals((bm2br12).message(), common:generateErrorMessageForMissingRequiredField("requiredField")); + + BooleanRecord12Array|csv:Error bm3br12 = csv:parseRecordAsRecordType([bm3, bm3], {}, BooleanRecord12Array); + test:assertTrue(bm3br12 is csv:Error); + test:assertEquals((bm3br12).message(), common:generateErrorMessageForMissingRequiredField("requiredField")); + + BooleanRecord12Array|csv:Error bm4br12 = csv:parseRecordAsRecordType([bm4, bm4], {}, BooleanRecord12Array); + test:assertTrue(bm4br12 is csv:Error); + test:assertEquals((bm4br12).message(), common:generateErrorMessageForMissingRequiredField("requiredField")); + + BooleanRecord12Array|csv:Error bm5br12 = csv:parseRecordAsRecordType([bm5, bm5], {}, BooleanRecord12Array); + test:assertTrue(bm5br12 is csv:Error); + test:assertEquals((bm5br12).message(), common:generateErrorMessageForMissingRequiredField("requiredField")); + + BooleanRecord13Array|csv:Error bm1br13 = csv:parseRecordAsRecordType([bm1, bm1], {}, BooleanRecord13Array); + test:assertEquals(bm1br13, [ + {b1: true, b2: false, defaultableField: "", nillableField :null}, + {b1: true, b2: false, defaultableField: "", nillableField :null} + ]); + + BooleanRecord13Array|csv:Error bm2br13 = csv:parseRecordAsRecordType([bm2, bm2], {}, BooleanRecord13Array); + test:assertEquals(bm2br13, [ + {b1: true, b2: false, defaultableField: "", nillableField :null}, + {b1: true, b2: false, defaultableField: "", nillableField :null} + ]); + + BooleanRecord13Array|csv:Error bm3br13 = csv:parseRecordAsRecordType([bm3, bm3], {}, BooleanRecord13Array); + test:assertEquals(bm3br13, [ + {b1: true, b2: false, b4: false, defaultableField: "", nillableField :null}, + {b1: true, b2: false, b4: false, defaultableField: "", nillableField :null} + ]); + + BooleanRecord13Array|csv:Error bm4br13 = csv:parseRecordAsRecordType([bm4, bm4], {}, BooleanRecord13Array); + test:assertEquals(bm4br13, [ + {defaultableField: "", nillableField :null}, + {defaultableField: "", nillableField :null} + ]); +} + +@test:Config +function testFromCsvWithTypeForMapAndRecordAsExpectedType4() { + BooleanRecord13Array|csv:Error bm5br13 = csv:parseRecordAsRecordType([bm5, bm5], {}, BooleanRecord13Array); + test:assertEquals(bm5br13, [ + {b1: true, b2: false, b4: true, defaultableField: "", nillableField :null}, + {b1: true, b2: false, b4: true, defaultableField: "", nillableField :null} + ]); + + BooleanRecord14Array|csv:Error bm1br14 = csv:parseRecordAsRecordType([bm1, bm1], {}, BooleanRecord14Array); + test:assertTrue(bm1br14 is csv:Error); + test:assertEquals((bm1br14).message(), common:generateErrorMessageForMissingRequiredField("requiredField")); + + BooleanRecord14Array|csv:Error bm2br14 = csv:parseRecordAsRecordType([bm2, bm2], {}, BooleanRecord14Array); + test:assertTrue(bm2br14 is csv:Error); + test:assertEquals((bm2br14).message(), common:generateErrorMessageForMissingRequiredField("requiredField")); + + BooleanRecord14Array|csv:Error bm3br14 = csv:parseRecordAsRecordType([bm3, bm3], {}, BooleanRecord14Array); + test:assertTrue(bm3br14 is csv:Error); + test:assertEquals((bm3br14).message(), common:generateErrorMessageForMissingRequiredField("requiredField")); + + BooleanRecord14Array|csv:Error bm4br14 = csv:parseRecordAsRecordType([bm4, bm4], {}, BooleanRecord14Array); + test:assertTrue(bm4br14 is csv:Error); + test:assertEquals((bm4br14).message(), common:generateErrorMessageForMissingRequiredField("requiredField")); + + BooleanRecord14Array|csv:Error bm5br14 = csv:parseRecordAsRecordType([bm5, bm5], {}, BooleanRecord14Array); + test:assertTrue(bm5br14 is csv:Error); + test:assertEquals((bm5br14).message(), common:generateErrorMessageForMissingRequiredField("requiredField")); + + BooleanRecord15Array|csv:Error bm1br15 = csv:parseRecordAsRecordType([bm1, bm1], {}, BooleanRecord15Array); + test:assertTrue(bm1br15 is csv:Error); + test:assertEquals((bm1br15).message(), common:generateErrorMessageForInvalidFieldType("true", "b1")); + + BooleanRecord15Array|csv:Error bm3br15 = csv:parseRecordAsRecordType([bm3, bm3], {}, BooleanRecord15Array); + test:assertTrue(bm3br15 is csv:Error); + test:assertEquals((bm3br15).message(), common:generateErrorMessageForInvalidFieldType("true", "b1")); + + BooleanRecord15Array|csv:Error bm4br15 = csv:parseRecordAsRecordType([bm4, bm4], {}, BooleanRecord15Array); + test:assertTrue(bm4br15 is csv:Error); + test:assertEquals((bm4br15).message(), common:generateErrorMessageForMissingRequiredField("b1")); + + BooleanRecord16Array|csv:Error bm1br16 = csv:parseRecordAsRecordType([bm1, bm1], {}, BooleanRecord16Array); + test:assertEquals(bm1br16, [ + {b1: true, b2: false}, + {b1: true, b2: false} + ]); + + BooleanRecord16Array|csv:Error bm2br16 = csv:parseRecordAsRecordType([bm2, bm2], {}, BooleanRecord16Array); + test:assertEquals(bm2br16, [ + {b1: true, b2: false, b3: (), n1: (), n3: ()}, + {b1: true, b2: false, b3: (), n1: (), n3: ()} + ]); + + BooleanRecord16Array|csv:Error bm3br16 = csv:parseRecordAsRecordType([bm3, bm3], {}, BooleanRecord16Array); + test:assertEquals(bm3br16, [ + {b1: true, b2: false, b4: false, b3: ()}, + {b1: true, b2: false, b4: false, b3: ()} + ]); + + BooleanRecord16Array|csv:Error bm4br16 = csv:parseRecordAsRecordType([bm4, bm4], {}, BooleanRecord16Array); + test:assertEquals(bm4br16, [ + {n1: (), n3: ()}, + {n1: (), n3: ()} + ]); + + BooleanRecord16Array|csv:Error bm5br16 = csv:parseRecordAsRecordType([bm5, bm5], {}, BooleanRecord16Array); + test:assertEquals(bm5br16, [ + {b1: true, b2: false, b4: true, b3: ()}, + {b1: true, b2: false, b4: true, b3: ()} + ]); + + BooleanRecord17Array|csv:Error bm1br17 = csv:parseRecordAsRecordType([bm1, bm1], {}, BooleanRecord17Array); + test:assertEquals(bm1br17, [ + {}, + {} + ]); + + BooleanRecord17Array|csv:Error bm2br17 = csv:parseRecordAsRecordType([bm2, bm2], {}, BooleanRecord17Array); + test:assertEquals(bm2br17, [ + {}, + {} + ]); + + BooleanRecord17Array|csv:Error bm3br17 = csv:parseRecordAsRecordType([bm3, bm3], {}, BooleanRecord17Array); + test:assertEquals(bm3br17, [ + {i1: 1}, + {i1: 1} + ]); + + BooleanRecord17Array|csv:Error bm4br17 = csv:parseRecordAsRecordType([bm4, bm4], {}, BooleanRecord17Array); + test:assertEquals(bm4br17, [ + {}, + {} + ]); + + BooleanRecord17Array|csv:Error bm5br17 = csv:parseRecordAsRecordType([bm5, bm5], {}, BooleanRecord17Array); + test:assertEquals(bm5br17, [ + {}, + {} + ]); + + BooleanRecord18Array|csv:Error bm1br18 = csv:parseRecordAsRecordType([bm1, bm1], {}, BooleanRecord18Array); + test:assertEquals(bm1br18, [ + {b2: false}, + {b2: false} + ]); + + BooleanRecord18Array|csv:Error bm2br18 = csv:parseRecordAsRecordType([bm2, bm2], {}, BooleanRecord18Array); + test:assertEquals(bm2br18, [ + {b2: false, b3: (), n1: (), n3: ()}, + {b2: false, b3: (), n1: (), n3: ()} + ]); + + BooleanRecord18Array|csv:Error bm3br18 = csv:parseRecordAsRecordType([bm3, bm3], {}, BooleanRecord18Array); + test:assertEquals(bm3br18, [ + {b2: false, b3: (), i1: 1}, + {b2: false, b3: (), i1: 1} + ]); + + BooleanRecord18Array|csv:Error bm4br18 = csv:parseRecordAsRecordType([bm4, bm4], {}, BooleanRecord18Array); + test:assertTrue(bm4br18 is csv:Error); + test:assertEquals((bm4br18).message(), common:generateErrorMessageForMissingRequiredField("b2")); + + BooleanRecord18Array|csv:Error bm5br18 = csv:parseRecordAsRecordType([bm5, bm5], {}, BooleanRecord18Array); + test:assertEquals(bm5br18, [ + {b2: false, b3: ()}, + {b2: false, b3: ()} + ]); +} + +@test:Config +function testFromCsvWithTypeForMapAndMapAsExpectedType() { + BooleanMapArray|csv:Error bm1bma = csv:parseRecordAsRecordType([bm1, bm1], {}, BooleanMapArray); + test:assertEquals(bm1bma, [ + {b1: true, b2: false}, + {b1: true, b2: false} + ]); + + BooleanMapArray|csv:Error bm2bma = csv:parseRecordAsRecordType([bm2, bm2], {}, BooleanMapArray); + test:assertEquals(bm2bma, [ + {b1: true, b2: false}, + {b1: true, b2: false} + ]); + + BooleanMapArray|csv:Error bm3bma = csv:parseRecordAsRecordType([bm3, bm3], {}, BooleanMapArray); + test:assertEquals(bm3bma, [ + {b1: true, b2: false, b4: false}, + {b1: true, b2: false, b4: false} + ]); + + BooleanMapArray|csv:Error bm4bma = csv:parseRecordAsRecordType([bm4, bm4], {}, BooleanMapArray); + test:assertEquals(bm4bma, [ + {}, + {} + ]); + + BooleanMapArray|csv:Error bm5bma = csv:parseRecordAsRecordType([bm5, bm5], {}, BooleanMapArray); + test:assertEquals(bm5bma, [ + {b1: true, b2: false, b4: true}, + {b1: true, b2: false, b4: true} + ]); + + NillableBooleanMapArray|csv:Error bm1nbma = csv:parseRecordAsRecordType([bm1, bm1], {}, NillableBooleanMapArray); + test:assertEquals(bm1nbma, [ + {b1: true, b2: false}, + {b1: true, b2: false} + ]); + + NillableBooleanMapArray|csv:Error bm2nbma = csv:parseRecordAsRecordType([bm2, bm2], {}, NillableBooleanMapArray); + test:assertEquals(bm2nbma, [ + {b1: true, b2: false, b3:(), n1: (), n3: ()}, + {b1: true, b2: false, b3:(), n1: (), n3: ()} + ]); + + NillableBooleanMapArray|csv:Error bm3nbma = csv:parseRecordAsRecordType([bm3, bm3], {}, NillableBooleanMapArray); + test:assertEquals(bm3nbma, [ + {b1: true, b2: false, b3:(), b4: false}, + {b1: true, b2: false, b3:(), b4: false} + ]); + + NillableBooleanMapArray|csv:Error bm4nbma = csv:parseRecordAsRecordType([bm4, bm4], {}, NillableBooleanMapArray); + test:assertEquals(bm4nbma, [ + {n1: (), n3: ()}, + {n1: (), n3: ()} + ]); + + NillableBooleanMapArray|csv:Error bm5nbma = csv:parseRecordAsRecordType([bm5, bm5], {}, NillableBooleanMapArray); + test:assertEquals(bm5nbma, [ + {b1: true, b2: false, b3: (), b4: true}, + {b1: true, b2: false, b3: (), b4: true} + ]); + + NillableIntUnionBooleanMapArray|csv:Error bm1niubma = csv:parseRecordAsRecordType([bm1, bm1], {}, NillableIntUnionBooleanMapArray); + test:assertEquals(bm1niubma, [ + {b1: true, b2: false}, + {b1: true, b2: false} + ]); + + NillableIntUnionBooleanMapArray|csv:Error bm2niubma = csv:parseRecordAsRecordType([bm2, bm2], {}, NillableIntUnionBooleanMapArray); + test:assertEquals(bm2niubma, [ + {b1: true, b2: false, b3:(), n1: (), n3: ()}, + {b1: true, b2: false, b3:(), n1: (), n3: ()} + ]); + + NillableIntUnionBooleanMapArray|csv:Error bm3niubma = csv:parseRecordAsRecordType([bm3, bm3], {}, NillableIntUnionBooleanMapArray); + test:assertEquals(bm3niubma, [ + {b1: true, b2: false, b3:(), b4: false, i1: 1}, + {b1: true, b2: false, b3:(), b4: false, i1: 1} + ]); + + NillableIntUnionBooleanMapArray|csv:Error bm4niubma = csv:parseRecordAsRecordType([bm4, bm4], {}, NillableIntUnionBooleanMapArray); + test:assertEquals(bm4niubma, [ + {n1: (), n3: ()}, + {n1: (), n3: ()} + ]); + + NillableIntUnionBooleanMapArray|csv:Error bm5niubma = csv:parseRecordAsRecordType([bm5, bm5], {}, NillableIntUnionBooleanMapArray); + test:assertEquals(bm5niubma, [ + {b1: true, b2: false, b3: (), b4: true}, + {b1: true, b2: false, b3: (), b4: true} + ]); + + IntUnionBooleanMapArray|csv:Error bm1iubma = csv:parseRecordAsRecordType([bm1, bm1], {}, IntUnionBooleanMapArray); + test:assertEquals(bm1iubma, [ + {b1: true, b2: false}, + {b1: true, b2: false} + ]); + + IntUnionBooleanMapArray|csv:Error bm2iubma = csv:parseRecordAsRecordType([bm2, bm2], {}, IntUnionBooleanMapArray); + test:assertEquals(bm2iubma, [ + {b1: true, b2: false}, + {b1: true, b2: false} + ]); + + IntUnionBooleanMapArray|csv:Error bm3iubma = csv:parseRecordAsRecordType([bm3, bm3], {}, IntUnionBooleanMapArray); + test:assertEquals(bm3iubma, [ + {b1: true, b2: false, b4: false, i1: 1}, + {b1: true, b2: false, b4: false, i1: 1} + ]); + + IntUnionBooleanMapArray|csv:Error bm4iubma = csv:parseRecordAsRecordType([bm4, bm4], {}, IntUnionBooleanMapArray); + test:assertEquals(bm4iubma, [ + {}, + {} + ]); + + IntUnionBooleanMapArray|csv:Error bm5iubma = csv:parseRecordAsRecordType([bm5, bm5], {}, IntUnionBooleanMapArray); + test:assertEquals(bm5iubma, [ + {b1: true, b2: false, b4: true}, + {b1: true, b2: false, b4: true} + ]); + + NilMapArray|csv:Error bm1nma = csv:parseRecordAsRecordType([bm1, bm1], {}, NilMapArray); + test:assertEquals(bm1nma, [ + {}, + {} + ]); + + NilMapArray|csv:Error bm2nma = csv:parseRecordAsRecordType([bm2, bm2], {}, NilMapArray); + test:assertEquals(bm2nma, [ + {n1: (), n3: (), b3: ()}, + {n1: (), n3: (), b3: ()} + ]); +} + +@test:Config +function testFromCsvWithTypeForMapAndMapAsExpectedType2() { + NilMapArray|csv:Error bm3nma = csv:parseRecordAsRecordType([bm3, bm3], {}, NilMapArray); + test:assertEquals(bm3nma, [ + {b3: ()}, + {b3: ()} + ]); + + NilMapArray|csv:Error bm4nma = csv:parseRecordAsRecordType([bm4, bm4], {}, NilMapArray); + test:assertEquals(bm4nma, [ + {n1: (), n3: ()}, + {n1: (), n3: ()} + ]); + NilMapArray|csv:Error bm5nma = csv:parseRecordAsRecordType([bm5, bm5], {}, NilMapArray); + test:assertEquals(bm5nma, [ + {b3: ()}, + {b3: ()} + ]); + + JsonMapArray|csv:Error bm1jma = csv:parseRecordAsRecordType([bm1, bm1], {}, JsonMapArray); + test:assertEquals(bm1jma, [ + {b1: true, b2: false}, + {b1: true, b2: false} + ]); + + JsonMapArray|csv:Error bm2jma = csv:parseRecordAsRecordType([bm2, bm2], {}, JsonMapArray); + test:assertEquals(bm2jma, [ + {b1: true, b2: false, b3: (), n1: (), n3: ()}, + {b1: true, b2: false, b3: (), n1: (), n3: ()} + ]); + + JsonMapArray|csv:Error bm3jma = csv:parseRecordAsRecordType([bm3, bm3], {}, JsonMapArray); + test:assertEquals(bm3jma, [ + {b1: true, b2: false, b4: false, b3: (), i1: 1}, + {b1: true, b2: false, b4: false, b3: (), i1: 1} + ]); + + JsonMapArray|csv:Error bm4jma = csv:parseRecordAsRecordType([bm4, bm4], {}, JsonMapArray); + test:assertEquals(bm4jma, [ + {n1: (), n3: ()}, + {n1: (), n3: ()} + ]); + + JsonMapArray|csv:Error bm5jma = csv:parseRecordAsRecordType([bm5, bm5], {}, JsonMapArray); + test:assertEquals(bm5jma, [ + {b1: true, b2: false, b4: true, b3: ()}, + {b1: true, b2: false, b4: true, b3: ()} + ]); + + AnydataMapArray|csv:Error bm1anydma = csv:parseRecordAsRecordType([bm1, bm1], {}, AnydataMapArray); + test:assertEquals(bm1anydma, [ + {b1: true, b2: false}, + {b1: true, b2: false} + ]); + + AnydataMapArray|csv:Error bm2anydma = csv:parseRecordAsRecordType([bm2, bm2], {}, AnydataMapArray); + test:assertEquals(bm2anydma, [ + {b1: true, b2: false, b3: (), n1: (), n3: ()}, + {b1: true, b2: false, b3: (), n1: (), n3: ()} + ]); + + AnydataMapArray|csv:Error bm3anydma = csv:parseRecordAsRecordType([bm3, bm3], {}, AnydataMapArray); + test:assertEquals(bm3anydma, [ + {b1: true, b2: false, b4: false, b3: (), i1: 1}, + {b1: true, b2: false, b4: false, b3: (), i1: 1} + ]); + + AnydataMapArray|csv:Error bm4anydma = csv:parseRecordAsRecordType([bm4, bm4], {}, AnydataMapArray); + test:assertEquals(bm4anydma, [ + {n1: (), n3: ()}, + {n1: (), n3: ()} + ]); + + AnydataMapArray|csv:Error bm5anydma = csv:parseRecordAsRecordType([bm5, bm5], {}, AnydataMapArray); + test:assertEquals(bm5anydma, [ + {b1: true, b2: false, b4: true, b3: ()}, + {b1: true, b2: false, b4: true, b3: ()} + ]); + + CustomMapArray|csv:Error bm1cma = csv:parseRecordAsRecordType([bm1, bm1], {}, CustomMapArray); + test:assertEquals(bm1cma, [ + {}, + {} + ]); + + CustomMapArray|csv:Error bm2cma = csv:parseRecordAsRecordType([bm2, bm2], {}, CustomMapArray); + test:assertEquals(bm2cma, [ + {}, + {} + ]); + + CustomMapArray|csv:Error bm3cma = csv:parseRecordAsRecordType([bm3, bm3], {}, CustomMapArray); + test:assertEquals(bm3cma, [ + {i1: 1}, + {i1: 1} + ]); + + CustomMapArray|csv:Error bm4cma = csv:parseRecordAsRecordType([bm4, bm4], {}, CustomMapArray); + test:assertEquals(bm4cma, [ + {}, + {} + ]); + + CustomMapArray|csv:Error bm5cma = csv:parseRecordAsRecordType([bm5, bm5], {}, CustomMapArray); + test:assertEquals(bm5cma, [ + {}, + {} + ]); + + StringMapArray|csv:Error bm1sma = csv:parseRecordAsRecordType([bm1, bm1], {}, StringMapArray); + test:assertEquals(bm1sma, [ + {}, + {} + ]); + + StringMapArray|csv:Error bm2sma = csv:parseRecordAsRecordType([bm2, bm2], {}, StringMapArray); + test:assertEquals(bm2sma, [ + {}, + {} + ]); + + StringMapArray|csv:Error bm3sma = csv:parseRecordAsRecordType([bm3, bm3], {}, StringMapArray); + test:assertEquals(bm3sma, [ + {}, + {} + ]); + + StringMapArray|csv:Error bm4sma = csv:parseRecordAsRecordType([bm4, bm4], {}, StringMapArray); + test:assertEquals(bm4sma, [ + {}, + {} + ]); + + StringMapArray|csv:Error bm5sma = csv:parseRecordAsRecordType([bm5, bm5], {}, StringMapArray); + test:assertEquals(bm5sma, [ + {}, + {} + ]); +} diff --git a/ballerina-tests/parse-record-types-tests/tests/test_data_values.bal b/ballerina-tests/parse-record-types-tests/tests/test_data_values.bal new file mode 100644 index 0000000..360a493 --- /dev/null +++ b/ballerina-tests/parse-record-types-tests/tests/test_data_values.bal @@ -0,0 +1,256 @@ +boolean b1 = true; +false b2 = false; +boolean? b3 = (); +boolean|int b4 = false; + +() n1 = (); +int? n2 = (); +() n3 = null; + +int i1 = 1; +int i2 = -2; +int i3 = int:MAX_VALUE; +int i4 = int:MIN_VALUE; +int i5 = 0; +2 i6 = 2; +int? i7 = (); +int|string i8 = 100; + +float f1 = 2.234; +float f2 = -3.21f; +float f3 = 0; +float f4 = float:Infinity; +float f5 = -float:Infinity; +float f6 = float:NaN; +2.3f f7 = 2.3; +float? f8 = (); +float|decimal f9 = 1.21; + +decimal d1 = 2.234; +decimal d2 = -3.21d; +decimal d3 = 0; +2.3d d4 = 2.3; +decimal? d5 = (); +decimal|int d6 = 1.21; + +string s1 = "string"; +string s2 = ""; +string:Char s3 = "a"; + +map bm1 = {b1, b2}; +map bm2 = {b1, b2, b3, n1, n3}; +map bm3 = {b1, b2, b3, b4, i1}; +map<()> bm4 = {n1, n3}; +map bm5 = {b1, b2, b3, b4:true}; + +map m5 = {i1, i2, i3, i4, i5, i6}; +map m6 = {f1, f2, f3, f4, f5, f6, f7}; +map m7 = {d1, d2, d3, d4}; +map m8 = {d1, f1, f9, f10: 1.23}; +map m9 = {s1, s2, s3}; +map m10 = {b1, b2, b3, b4, n1, n2, n3, i1, i2, i3, i4, i5, i6, i7, i8, f1, f2, f3, f4, f5, f6, f7, f8}; +map m11 = {b1, b2, b3, b4, n1, n2, n3, i1, i2, i3, i4, i5, i6, i7, i8, f1, f2, f3, f4, f5, f6, f7, f8}; + +boolean[] arr1 = [b1, b2]; +boolean?[] arr2 = [b1, b2, b3, n1, n3]; +(boolean|int?)[] arr3 = [b1, b2, b3, b4, i1]; +()[] arr4 = [n1, n3]; +int[] arr5 = [i1, i2, i3, i4, i5, i6]; +float[] arr6 = [f1, f2, f3, f4, f5, f6, f7]; +decimal[] arr7 = [d1, d2, d3, d4]; +(decimal|float)[] arr8 = [d1, f1, f9, 1.23]; +string[] arr9 = [s1, s2, s3]; +anydata[] arr10 = [b1, b2, b3, b4, n1, n2, n3, i1, i2, i3, i4, i5, i6, i7, i8, f1, f2, f3, f4, f5, f6, f7, f8]; +json[] arr11 = [b1, b2, b3, b4, n1, n2, n3, i1, i2, i3, i4, i5, i6, i7, i8, f1, f2, f3, f4, f5, f6, f7, f8]; + +[boolean, boolean] bt1 = [b1, b2]; +[boolean, boolean, boolean, boolean] bt2 = [b1, b2, b1, b2]; +[boolean?, boolean?, boolean?, boolean?, boolean?] bt3 = [b1, b2, b3, n1, n3]; +[boolean|int?, boolean|int?, boolean|int?, boolean|int?, boolean|int?] bt4 = [b1, b2, b3, b4, i1]; +[boolean...] bt5 = [b1, b2]; + +[string, string] st1 = [s1, s2]; +[string, string, string, string] st2 = [s1, s2, s3, s2]; +[string...] st3 = [s1, s2]; +[string, string, string...] st4 = [s1, s2, s3, s2]; + +[string?, string?, string?, string?, string?] st5 = [s1, s2, s3, n1, n3]; +[string|int?, string|int?, string|int?, string|int?, string|int?] st6 = [s1, s2, s3, n1, i1]; +[string?...] st7 = [s1, s2]; +[string...] st8 = []; +[string, string, string] st9 = [s1, s2, s3]; + +[(), ()] tup4 = [n1, n3]; +[int, int, int, int, int, int] tup5 = [i1, i2, i3, i4, i5, i6]; +[float, float, float, float, float, float, float] tup6 = [f1, f2, f3, f4, f5, f6, f7]; +[decimal, decimal, decimal, decimal] tup7 = [d1, d2, d3, d4]; +[decimal|float, decimal|float, decimal|float, decimal|float] tup8 = [d1, f1, f9, 1.23]; +[string, string, string] tup9 = [s1, s2, s3]; +[anydata, anydata, anydata, anydata, anydata, anydata, anydata, anydata, + anydata, anydata, anydata, anydata, anydata, anydata, anydata, anydata, + anydata, anydata, anydata, anydata, anydata, anydata, anydata] tup10 = [b1, b2, b3, b4, + n1, n2, n3, i1, i2, i3, i4, i5, i6, i7, i8, f1, f2, f3, f4, f5, f6, f7, f8]; +[json, json, json, json, json, json, json, json, json, json, json, json, + json, json, json, json, json, json, json, json, json, json, json] tup11 = + [b1, b2, b3, b4, n1, n2, n3, i1, i2, i3, i4, i5, i6, i7, i8, f1, + f2, f3, f4, f5, f6, f7, f8]; +[string, string, int, int, boolean, boolean, (), (), decimal, decimal, float, float] tup12 = [ + s1, s2, i1, i2, b1, b2, n1, n3, d1, d2, f1, f2 +]; + +[boolean, boolean...] restTup1 = [b1, b2]; +[boolean?, boolean?, boolean?...] restTup2 = [b1, b2, b3, n1, n3]; +[boolean|int?...] restTup3 = [b1, b2, b3, b4, i1]; +[(), ()...] restTup4 = [n1, n3]; +[int...] restTup5 = [i1, i2, i3, i4, i5, i6]; +[float...] restTup6 = [f1, f2, f3, f4, f5, f6, f7]; +[decimal...] restTup7 = [d1, d2, d3, d4]; +[decimal|float, decimal|float...] restTup8 = [d1, f1, f9, 1.23]; +[string...] restTup9 = [s1, s2, s3]; +[anydata...] restTup10 = [b1, b2, b3, b4, n1, n2, n3, i1, i2, i3, i4, i5, i6, i7, i8, f1, f2, f3, f4, f5, f6, f7, f8]; +[json, json, json...] restTup11 = [b1, b2, b3, b4, n1, n2, n3, i1, i2, i3, i4, i5, i6, i7, i8, f1, f2, f3, f4, f5, f6, f7, f8]; +[string, string, int, int, boolean, boolean, (), (), decimal, decimal, float, float...] restTup12 = [ + s1, s2, i1, i2, b1, b2, n1, n3, d1, d2, f1, f2, f2, f2 +]; + +var booleanRecordArray = [ + {b1, b2, b3, b4}, {b1, b2, b3, b4} +]; + +var booleanRecordArray2 = [ + {},{} +]; + +string csvStringWithBooleanValues1 = string `b1,b2,b3,b4 +true,false,true,false +true,false, true,false +true,false,true,false +`; + +string csvStringWithBooleanValues2 = string `b1,b2,b3,b4,b5 +true,false, true,false,true +true,false, true,false,true`; + +string csvStringWithBooleanValues3 = string `b1,b2,b3 +${" "}${"\t"} +true, false,true +${" "} + TRUE, FALSE,() +${" "} + +true, true,FALSE + +`; + +string csvStringWithBooleanValues4 = string `b1,b2,b3,b4 + true,(), (),false + true,(), null,false + +`; + +string csvStringWithBooleanValues5 = string `b1,b2,b3,b4 + +true,false,true,2 + +true,false,true,3 +`; + +string csvStringWithBooleanValues6 = string `b2,b3 +(),() + +`; + +string csvStringWithBooleanValues7 = string `b1,b2,b3,b4 +${b1},${b2},(),${b4} +`; + +string csvStringData1 = string ` + a, b, c, d, e, f + 1, string1, true, 2.234, 2.234, () + 2, string2, false, 0, 0, null + 3, string3, false, 1.23, 1.23, () + 4, string4, true, -6.51, -6.51, () + 5, string5, true, 3, 3, ()`; + +string csvStringData2 = string ` + hello, hello, (), 12, true, 12.34 + // comment + + a, b, c, d, e, f + + + 1, string1, true, 2.234, 2.234, () + 2, string2, false, 0, 0, null + 3, string3, false, 1.23, 1.23, () + 4, string4, true, -6.51, -6.51, () + 5, string5, true, 3, 3, ()`; + +string csvStringData3 = string ` + a, b, c, d, e, f + + + + 1, string1, true, 2.234, 2.234, () + 2, string2, false, 0, 0, null + 3, string3, false, 1.23, 1.23, () + + 4, string4, true, -6.51, -6.51, () + 5, string5, true, 3, 3, ()`; + +string csvStringData4 = string ` + 1, string1, true, 2.234, 2.234, () + 2, string2, false, 0, 0, null + 3, string3, false, 1.23, 1.23, () + 4, string4, true, -6.51, -6.51, () + 5, string5, true, 3, 3, ()`; + +string csvStringData5 = string ` + + + + 1, string1, true, 2.234, 2.234, () + 2, string2, false, 0, 0, null + + 3, string3, false, 1.23, 1.23, () + 4, string4, true, -6.51, -6.51, () + + 5, string5, true, 3, 3, ()`; + +string csvStringData6 = string ` + + 1, string1, true, 2.234, 2.234, () + 2, string2, false, 0, 0, null + + 3, string3, false, 1.23, 1.23, () + 4, string4, true, -6.51, -6.51, () + + 5, string5, true, 3, 3, ()`; + +string csvStringData7 = string ` + a@ b@ c@ d@ e@ f + 1@ string@ true@ 2.234@ -3.21@ () + 2@ s,tring@ true@ 2.234@ -3.21@ null + 3@ stri,ng@ true@ 2.234@ -3.21@ () + 4@ string@ true@ 2.234@ -3.21@ () + 5@ string@ true@ 2.234@ -3.21@ ()`; +string csvStringData8 = string ` + a@ b@ c@ d@ e@ f + + + + 1@ stri,ng@ true@ 2.234@ -3.21@ () + 2@ string@ true@ 2.234@ ()@-3.21 + 3@ string@ true@ 2.234@ -3.21@ null + + 4@ s,tring@ true@ 2.234@ -3.21@ () + 5@ string@ true@ 2.234@ -3.21@ ()`; + +string csvStringData9 = string ` + + 1@ string@ true@ 2.234@ -3.21@ () + 2@ string@ true@ 2.234@ -3.21@ null + + 3@ string@ true@ 2.234@ -3.21@ () + 4@ string@ true@ 2.234@ ()@-3.21 + + 5@ string@ true@ 2.234@ -3.21@ null`; diff --git a/ballerina-tests/parse-record-types-tests/tests/types.bal b/ballerina-tests/parse-record-types-tests/tests/types.bal new file mode 100644 index 0000000..a2b4b2b --- /dev/null +++ b/ballerina-tests/parse-record-types-tests/tests/types.bal @@ -0,0 +1,2534 @@ +type BooleanRecord1 record { + boolean b1; + boolean|string b2; + boolean|string? b3; + boolean b4; +}; + +type BooleanRecord2 record {| + boolean b1; + boolean|string b2; + boolean|string? b3; + boolean b4; +|}; + +type BooleanRecord3 record {| + boolean b1; + boolean? b3; +|}; + +type BooleanRecord4 record { + boolean b1; + boolean? b3; +}; + +type BooleanRecord5 record { + boolean b1; + boolean? b3; + string defaultableField = ""; + string? nillableField = (); +}; + +type BooleanRecord6 record {| + boolean b1; + boolean? b3; + string defaultableField = ""; + string? nillableField = (); +|}; + +type BooleanRecord7 record { + boolean b1; + boolean? b3; + string defaultableField = ""; + string? nillableField = (); + string requiredField; +}; + +type BooleanRecord8 record {| + boolean b1; + boolean? b3; + string defaultableField = ""; + string? nillableField = (); + string requiredField; +|}; + +type BooleanRecord9 record {| + boolean b1; + boolean? b3; + boolean?...; +|}; + +type BooleanRecord10 record {| + boolean...; +|}; + +type BooleanRecord11 record {| + boolean b1; + string defaultableField = ""; + string? nillableField = (); + boolean?|string...; +|}; + +type BooleanRecord12 record {| + boolean b1; + string defaultableField = ""; + string? nillableField = (); + string requiredField; + boolean...; +|}; + +type BooleanRecord13 record {| + string defaultableField = ""; + string? nillableField = (); + string|boolean...; +|}; + +type BooleanRecord14 record {| + string defaultableField = ""; + string? nillableField = (); + string requiredField; + boolean...; +|}; + +type BooleanRecord15 record {| + int b1; + string defaultableField = ""; + string? nillableField = (); + boolean?...; +|}; + +type BooleanRecord16 record {| + boolean?...; +|}; + +type BooleanRecord17 record {| + int...; +|}; + +type BooleanRecord18 record {| + boolean b2; + int?...; +|}; + +type NilRecord1 record { + () n1; + () n2; + () n3; +}; + +type NilRecord2 record {| + () n1; + () n2; + () n3; +|}; + +type NilRecord3 record {| + () n1; + () n4; +|}; + +type NilRecord4 record { + () n1; + () n4; +}; + +type NilRecord5 record { + () n1; + () n4; + string defaultableField = ""; + string? nillableField = (); +}; + +type NilRecord6 record {| + () n1; + () n4; + string defaultableField = ""; + string? nillableField = (); +|}; + +type NilRecord7 record { + () n1; + () n4; + string defaultableField = ""; + string? nillableField = (); + string requiredField; +}; + +type NilRecord8 record {| + () n1; + () n4; + string defaultableField = ""; + string? nillableField = (); + string requiredField; +|}; + +type NilRecord9 record {| + () n1; + () n2; + ()...; +|}; + +type NilRecord10 record {| + ()...; +|}; + +type NilRecord11 record {| + () n1; + string defaultableField = ""; + string? nillableField = (); + ()...; +|}; + +type NilRecord12 record {| + () n1; + string defaultableField = ""; + string? nillableField = (); + string requiredField; + ()...; +|}; + +type NilRecord13 record {| + string defaultableField = ""; + string? nillableField = (); + ()...; +|}; + +type NilRecord14 record {| + string defaultableField = ""; + string? nillableField = (); + string requiredField; + ()...; +|}; + +type IntegerRecord1 record { + int i1; + int i2; + int i3; + int? i4; + int? i5; + int i6; + int i7; + int? i8; +}; + +type IntegerRecord2 record {| + int i1; + int? i2; + int i3; + int i4; + int? i5; + int i6; + int i7; + int? i8; +|}; + +type IntegerRecord3 record {| + int i1; + int i4; + int i6; +|}; + +type IntegerRecord4 record { + int i1; + int i4; + int i6; +}; + +type IntegerRecord5 record { + int i1; + int i4; + int i6; + string defaultableField = ""; + string? nillableField = (); +}; + +type IntegerRecord6 record {| + int i1; + int i4; + int i6; + string defaultableField = ""; + string? nillableField = (); +|}; + +type IntegerRecord7 record { + int i1; + int i4; + int i6; + string defaultableField = ""; + string? nillableField = (); + string requiredField; +}; + +type IntegerRecord8 record {| + int i1; + int i4; + int i6; + string defaultableField = ""; + string? nillableField = (); + string requiredField; +|}; + +type IntegerRecord9 record {| + int i1; + int i2; + int...; +|}; + +type IntegerRecord10 record {| + int...; +|}; + +type IntegerRecord11 record {| + int i1; + string defaultableField = ""; + string? nillableField = (); + int...; +|}; + +type IntegerRecord12 record {| + int i1; + string defaultableField = ""; + string? nillableField = (); + string requiredField; + int...; +|}; + +type IntegerRecord13 record {| + string defaultableField = ""; + string? nillableField = (); + int...; +|}; + +type IntegerRecord14 record {| + string defaultableField = ""; + string? nillableField = (); + string requiredField; + int...; +|}; + +type FloatRecord1 record { + float f1; + float f2; + float f3; + float f4; + float f5; + float f6; + float f7; + float f8; +}; + +type FloatRecord2 record {| + float f1; + float f2; + float f3; + float f4; + float f5; + float f6; + float f7; + float f8; +|}; + +type FloatRecord3 record {| + float f1; + float f4; + float f7; +|}; + +type FloatRecord4 record { + float f1; + float f4; + float f7; +}; + +type FloatRecord5 record { + float f1; + float f4; + float f7; + string defaultableField = ""; + string? nillableField = (); +}; + +type FloatRecord6 record {| + float f1; + float f4; + float f7; + string defaultableField = ""; + string? nillableField = (); +|}; + +type FloatRecord7 record { + float f1; + float f4; + float f7; + string defaultableField = ""; + string? nillableField = (); + string requiredField; +}; + +type FloatRecord8 record {| + float f1; + float f4; + float f7; + string defaultableField = ""; + string? nillableField = (); + string requiredField; +|}; + +type FloatRecord9 record {| + float f1; + float f2; + float...; +|}; + +type FloatRecord10 record {| + float...; +|}; + +type FloatRecord11 record {| + float f1; + string defaultableField = ""; + string? nillableField = (); + float...; +|}; + +type FloatRecord12 record {| + float f1; + string defaultableField = ""; + string? nillableField = (); + string requiredField; + float...; +|}; + +type FloatRecord13 record {| + string defaultableField = ""; + string? nillableField = (); + float...; +|}; + +type FloatRecord14 record {| + string defaultableField = ""; + string? nillableField = (); + string requiredField; + float...; +|}; + +type DecimalRecord1 record { + decimal d1; + decimal d2; + decimal d3; + decimal d4; + decimal d5; + decimal d6; + decimal d7; + decimal d8; +}; + +type DecimalRecord2 record {| + decimal d1; + decimal d2; + decimal d3; + decimal d4; + decimal d5; + decimal d6; + decimal d7; + decimal d8; +|}; + +type DecimalRecord3 record {| + decimal d1; + decimal d4; + decimal d7; +|}; + +type DecimalRecord4 record { + decimal d1; + decimal d4; + decimal d7; +}; + +type DecimalRecord5 record { + decimal d1; + decimal d4; + decimal d7; + string defaultableField = ""; + string? nillableField = (); +}; + +type DecimalRecord6 record {| + decimal d1; + decimal d4; + decimal d7; + string defaultableField = ""; + string? nillableField = (); +|}; + +type DecimalRecord7 record { + decimal d1; + decimal d4; + decimal d7; + string defaultableField = ""; + string? nillableField = (); + string requiredField; +}; + +type DecimalRecord8 record {| + decimal d1; + decimal d4; + decimal d7; + string defaultableField = ""; + string? nillableField = (); + string requiredField; +|}; + +type DecimalRecord9 record {| + decimal d1; + decimal d2; + decimal...; +|}; + +type DecimalRecord10 record {| + decimal...; +|}; + +type DecimalRecord11 record {| + decimal d1; + string defaultableField = ""; + string? nillableField = (); + decimal...; +|}; + +type DecimalRecord12 record {| + decimal d1; + string defaultableField = ""; + string? nillableField = (); + string requiredField; + decimal...; +|}; + +type DecimalRecord13 record {| + string defaultableField = ""; + string? nillableField = (); + decimal...; +|}; + +type DecimalRecord14 record {| + string defaultableField = ""; + string? nillableField = (); + string requiredField; + decimal...; +|}; + +type StringRecord1 record { + string s1; + string s2; + string s3; +}; + +type StringRecord2 record {| + string s1; + string s2; + string s3; +|}; + +type StringRecord3 record {| + string s1; + string s4; +|}; + +type StringRecord4 record { + string s1; + string s4; +}; + +type StringRecord5 record { + string s1; + string s4; + string defaultableField = ""; + string? nillableField = (); +}; + +type StringRecord6 record {| + string s1; + string s4; + string defaultableField = ""; + string? nillableField = (); +|}; + +type StringRecord7 record { + string s1; + string s4; + string defaultableField = ""; + string? nillableField = (); + string requiredField; +}; + +type StringRecord8 record {| + string s1; + string s4; + string defaultableField = ""; + string? nillableField = (); + string requiredField; +|}; + +type StringRecord9 record {| + string s1; + string s2; + string...; +|}; + +type StringRecord10 record {| + string...; +|}; + +type StringRecord11 record {| + string s1; + string defaultableField = ""; + string? nillableField = (); + string...; +|}; + +type StringRecord12 record {| + string d1; + string defaultableField = ""; + string? nillableField = (); + string requiredField; + string...; +|}; + +type StringRecord13 record {| + string defaultableField = ""; + string? nillableField = (); + string...; +|}; + +type StringRecord14 record {| + string defaultableField = ""; + string? nillableField = (); + string requiredField; + string...; +|}; + +type StringRecord15 record {| + string defaultableField = ""; + string? nillableField = (); + string requiredField; + string...; +|}; + +type StringRecord16 record {| + string?...; +|}; + +type StringRecord17 record {| + int...; +|}; + +type StringRecord18 record {| + string b2; + int?...; +|}; + +type StringRecord19 record { + string s1 = ""; + string s2 = ""; +}; + +type StringRecord20 record {| + string s1 = ""; + string s2 = ""; +|}; + +type StringRecord21 record { +}; + +type StringRecord22 record {| + string s1 = ""; + string s2 = ""; + json...; +|}; + +type StringRecord23 record {| + json...; +|}; + +type JsonRecord1 record { + json j1; + json j2; + json j3; +}; + +type JsonRecord2 record {| + json j1; + json j2; + json j3; +|}; + +type JsonRecord3 record {| + json j1; + json j4; +|}; + +type JsonRecord4 record { + json j1; + json j4; +}; + +type JsonRecord5 record { + json j1; + json j4; + json defaultableField = ""; + json? nillableField = (); +}; + +type JsonRecord6 record {| + json j1; + json j4; + json defaultableField = ""; + json? nillableField = (); +|}; + +type JsonRecord7 record { + json j1; + json j4; + json defaultableField = ""; + json? nillableField = (); + json requiredField; +}; + +type JsonRecord8 record {| + json j1; + json j4; + json defaultableField = ""; + json? nillableField = (); + json requiredField; +|}; + +type JsonRecord9 record {| + json j1; + json j2; + json...; +|}; + +type JsonRecord10 record {| + json...; +|}; + +type JsonRecord11 record {| + json j1; + json defaultableField = ""; + json? nillableField = (); + json...; +|}; + +type JsonRecord12 record {| + json j1; + json defaultableField = ""; + json? nillableField = (); + json requiredField; + json...; +|}; + +type JsonRecord13 record {| + json defaultableField = ""; + json? nillableField = (); + json...; +|}; + +type JsonRecord14 record {| + json defaultableField = ""; + json? nillableField = (); + json requiredField; + json...; +|}; + +type AnydataRecord1 record { + anydata anydata1; + anydata anydata2; + anydata anydata3; +}; + +type AnydataRecord2 record {| + anydata anydata1; + anydata anydata2; + anydata anydata3; +|}; + +type AnydataRecord3 record {| + anydata anydata1; + anydata anydata4; +|}; + +type AnydataRecord4 record { + anydata anydata1; + anydata anydata4; +}; + +type AnydataRecord5 record { + anydata anydata1; + anydata anydata4; + anydata defaultableField = ""; + anydata? nillableField = (); +}; + +type AnydataRecord6 record {| + anydata anydata1; + anydata anydata4; + anydata defaultableField = ""; + anydata? nillableField = (); +|}; + +type AnydataRecord7 record { + anydata anydata1; + anydata anydata4; + anydata defaultableField = ""; + anydata? nillableField = (); + anydata requiredField; +}; + +type AnydataRecord8 record {| + anydata anydata1; + anydata anydata4; + anydata defaultableField = ""; + anydata? nillableField = (); + anydata requiredField; +|}; + +type AnydataRecord9 record {| + anydata anydata1; + anydata anydata2; + anydata...; +|}; + +type AnydataRecord10 record {| + anydata...; +|}; + +type AnydataRecord11 record {| + anydata anydata1; + anydata defaultableField = ""; + anydata? nillableField = (); + anydata...; +|}; + +type AnydataRecord12 record {| + anydata anydata1; + anydata defaultableField = ""; + anydata? nillableField = (); + anydata requiredField; + anydata...; +|}; + +type AnydataRecord13 record {| + anydata defaultableField = ""; + anydata? nillableField = (); + anydata...; +|}; + +type AnydataRecord14 record {| + anydata defaultableField = ""; + anydata? nillableField = (); + anydata requiredField; + anydata...; +|}; + +type CustomRecord1 record { + int i1; + int i2; + string s1; + string s2; + boolean b1; + boolean b2; + () n1; + () n2; + float f1; + float f2; + decimal d1; + decimal d2; +}; + +type CustomRecord2 record {| + int i1; + int i2; + string s1; + string s2; + boolean b1; + boolean b2; + () n1; + () n2; + float f1; + float f2; + decimal d1; + decimal d2; +|}; + +type CustomRecord3 record {| + int i1; + string s1; + boolean b1; + () n1; + float f1; + decimal d1; +|}; + +type CustomRecord4 record { + int i1; + string s1; + boolean b1; + () n1; + float f1; + decimal d1; +}; + +type CustomRecord5 record { + int i1; + string s1; + boolean b1; + () n1; + float f1; + decimal d1; + string defaultableField = ""; + string? nillableField = (); +}; + +type CustomRecord6 record {| + int i1; + string s1; + boolean b1; + () n1; + float f1; + decimal d1; + anydata defaultableField = ""; + anydata? nillableField = (); +|}; + +type CustomRecord7 record { + int i1; + string s1; + boolean b1; + () n1; + float f1; + decimal d1; + anydata defaultableField = ""; + anydata? nillableField = (); + anydata requiredField; +}; + +type CustomRecord8 record {| + int i1; + string s1; + boolean b1; + () n1; + float f1; + decimal d1; + anydata defaultableField = ""; + anydata? nillableField = (); + anydata requiredField; +|}; + +type CustomRecord9 record {| + int i1; + string s1; + boolean b1; + () n1; + float f1; + decimal d1; + string...; +|}; + +type CustomRecord10 record {| + string...; +|}; + +type CustomRecord11 record {| + int i1; + string s1; + boolean b1; + () n1; + float f1; + decimal d1; + anydata defaultableField = ""; + anydata? nillableField = (); + string...; +|}; + +type CustomRecord12 record {| + int i1; + string s1; + boolean b1; + () n1; + float f1; + decimal d1; + anydata defaultableField = ""; + anydata? nillableField = (); + anydata requiredField; + string...; +|}; + +type CustomRecord13 record {| + anydata defaultableField = ""; + anydata? nillableField = (); + string...; +|}; + +type CustomRecord14 record {| + anydata defaultableField = ""; + anydata? nillableField = (); + anydata requiredField; + string...; +|}; + +type CustomRecord15 record {| + string '1; + string '2; +|}; + +type CustomRecord16 record {| + string '1; + string '2; + string '3; + string '4; +|}; + +type CustomRecord17 record { + string '1; + string '2; +}; + +type CustomRecord18 record { + string '1; + string '2; + string '3; + string '4; +}; + +type CustomRecord19 record { + string '1; + string '2; + string '3 = ""; + string '4 = ""; +}; + +type CustomRecord20 record { + string '1; +}; + +type CustomRecord21 record {| + string '1; + json...; +|}; + +type CustomRecord22 record {| + string '1; + string...; +|}; + +type CustomRecord23 record {| + string '1; + string a = ""; + string...; +|}; + +type CustomRecord24 record {| + string '1; + string '2 = ""; + string...; +|}; + +type CustomRecord25 record {| + int '1; + string...; +|}; + +type CustomRecord26 record {| + string '1; + int...; +|}; + +type CustomRecord27 record {| + int i1; + string s1; + boolean b1; + () n1; + float f1; + decimal d1; + anydata a1; + json j1; + anydata defaultableField = ""; + anydata? nillableField = (); + string...; +|}; + +type CustomRecord28 record { + string '1; +}; + +type CustomRecord29 record { + int '1; +}; + +type CustomRecord30 record {| + string '1; + string '2; + string '3; + string '4; + string '5; + string '6; +|}; + +type CustomRecord31 record {| + string '1; + string '6; +|}; + +type CustomRecord32 record {| + int '1; +|}; + +type CustomRecord33 record {| + string '1; + string '2; + string '3; + string '4; + string '5; + string '6; +|}; + +type CustomRecord34 record { + string '1; + string '6; + string '5 = ""; +}; + +type CustomRecord35 record { + string '1; + string '6; + string '9 = ""; +}; + +type CustomRecord36 record {| + string '1; + string '6; + string '9 = ""; +|}; + +type CustomRecord37 record {| + string '1; + string '6; + string '5 = ""; +|}; + +type CustomRecord38 record {| + string '1; + string '2; + string '3; + string '4; + string '5; + string '6; + string ...; +|}; + +type CustomRecord39 record {| + string '1; + string '2; + string '3; + string '4; + string '5; + string '6; + json ...; +|}; + +type CustomRecord40 record {| + string '5; + string '6; + json ...; +|}; + +type CustomRecord41 record {| + json ...; +|}; + +type CustomRecord42 record {| + int '1; + string '2; + boolean '3; + decimal '4; + float '5; + () '6; +|}; + +type CustomRecord43 record { + int '1; + string '2; + boolean '3; + decimal '4; + float '5; + () '6; +}; + +type CustomRecord44 record {| + int '1; + string '2; + boolean '3; + decimal '4; + float '5; + () '6; + string ...; +|}; + +type CustomRecord45 record {| + int H1; + string H2; + boolean H3; + decimal H4; + float H5; + () H6; +|}; + +type CustomRecord46 record { + int H1; + string H2; + boolean H3; + decimal H4; + float H5; + () H6; +}; + +type CustomRecord47 record {| + int H1; + string H2; + boolean H3; + decimal H4; + float H5; + () H6; + string ...; +|}; + +type CustomRecord48 record { + string H1; + string H2; + string H3; + string H4; + string H5; + string H6; +}; + +type CustomRecord49 record {| + string H1; + string H2; + string H3; + string H4; + string H5; + string H6; +|}; + +type CustomRecord50 record { + int H1; + float H4; +}; + +type CustomRecord51 record {| + int H1; + float H4; +|}; + +type CustomRecord52 record {| + string H1; + string H4; + string ...; +|}; + +type CustomRecord53 record {| + int H1; + float H4; + decimal ...; +|}; + +type CustomRecord54 record {| + string H1 = ""; + string H4; + string '1; +|}; + +type CustomRecord55 record {| + string H1 = ""; + string H4 = ""; + int '1 = 10; +|}; + +type CustomRecord56 record { + string H1 = ""; + string H4 = ""; + anydata '1 = 10; +}; + +type BooleanTuple1 [boolean, boolean, boolean, boolean]; + +type BooleanTuple2 [boolean, boolean]; + +type BooleanTuple3 [boolean, boolean...]; + +type BooleanTuple4 [boolean...]; + +type NillableBooleanTuple5 [boolean?, boolean?, boolean?, boolean?, boolean?]; + +type NillableBooleanTuple6 [boolean?, boolean?]; + +type NillableBooleanTuple7 [boolean?, boolean?, boolean?...]; + +type NillableBooleanTuple8 [boolean?...]; + +type NillableIntBooleanTuple9 [int|boolean?, int|boolean?...]; + +type NilTuple1 [(), (), ()]; + +type NilTuple2 [(), ()]; + +type NilTuple3 [(), ()...]; + +type NilTuple4 [()...]; + +type IntegerTuple1 [int, int, int, int, int, int]; + +type IntegerTuple2 [int, int]; + +type IntegerTuple3 [int, int...]; + +type IntegerTuple4 [int...]; + +type FloatTuple1 [float, float, float, float, float, float, float]; + +type FloatTuple2 [float, float]; + +type FloatTuple3 [float, float...]; + +type FloatTuple4 [float...]; + +type DecimalTuple1 [decimal, decimal, decimal, decimal]; + +type DecimalTuple2 [decimal, decimal]; + +type DecimalTuple3 [decimal, decimal...]; + +type DecimalTuple4 [decimal...]; + +type StringTuple1 [string, string, string, string]; + +type StringTuple2 [string, string]; + +type StringTuple3 [string, string...]; + +type StringTuple4 [string...]; + +type AnydataTuple1 [anydata, anydata, anydata, anydata, anydata, + anydata, anydata, anydata, anydata, anydata, anydata, anydata, + anydata, anydata, anydata, anydata, anydata, anydata, anydata, + anydata, anydata, anydata, anydata]; + +type AnydataTuple2 [anydata, anydata]; + +type AnydataTuple3 [anydata, anydata...]; + +type AnydataTuple4 [anydata...]; + +type JsonTuple1 [json, json, json, json, json, json, json, json, + json, json, json, json, json, json, json, json, json, json, + json, json, json, json, json]; + +type JsonTuple2 [json, json]; + +type JsonTuple3 [json, json...]; + +type JsonTuple4 [json...]; + +type CustomTuple1 [string, int, decimal, float, (), boolean, anydata, json, string, int, decimal, float, (), boolean, anydata, json]; + +type CustomTuple2 [string, int, decimal, float, (), boolean, anydata, json]; + +type CustomTuple3 [string, int, decimal, float, (), boolean, anydata, json, string...]; + +type CustomTuple4 [string...]; + +type CustomTuple5 [string, int, decimal, float, (), boolean, anydata, json, anydata...]; + +type CustomTuple6 [anydata...]; + +type CustomTuple7 [int, string, boolean, (), float, decimal, json, anydata, string...]; + +type CustomTuple8 [int, string, boolean, (), float, decimal, json, anydata, int...]; + +type IntegerArray1 int[]; + +type IntegerArray2 int[2]; + +type IntegerArray3 int[]; + +type IntegerArray4 int[2]; + +type IntegerArray5 int[3]; + +type IntegerArray6 int[4]; + +type StringArray string[]; + +type NillableStringArray string?[]; + +type NillableIntOrUnionStringArray (int|string?)[]; + +type StringArray1 string[]; + +type StringArray2 string[2]; + +type StringArray3 string[]; + +type StringArray4 string[2]; + +type StringArray5 string[3]; + +type StringArray6 string[4]; + +type FloatArray1 float[]; + +type FloatArray2 float[2]; + +type FloatArray3 float[]; + +type FloatArray4 float[2]; + +type FloatArray5 float[3]; + +type FloatArray6 float[4]; + +type DecimalArray1 decimal[]; + +type DecimalArray2 decimal[2]; + +type DecimalArray3 decimal[]; + +type DecimalArray4 decimal[2]; + +type DecimalArray5 decimal[3]; + +type DecimalArray6 decimal[4]; + +type BooleanArray boolean[]; + +type NillableBooleanArray boolean?[]; + +type NillableIntOrUnionBooleanArray (int|boolean?)[]; + +type BooleanArray2 boolean[2]; + +type BooleanArray3 boolean[3]; + +type BooleanArray4 boolean[]; + +type BooleanArray5 boolean[2]; + +type BooleanArray6 boolean[4]; + +type NilArray1 ()[]; + +type NilArray2 ()[2]; + +type NilArray3 ()[]; + +type NilArray4 ()[2]; + +type NilArray5 ()[3]; + +type NilArray6 ()[4]; + +type JsonArray1 json[]; + +type JsonArray2 json[2]; + +type JsonArray3 json[]; + +type JsonArray4 json[2]; + +type JsonArray5 json[3]; + +type JsonArray6 json[4]; + +type AnydataArray1 anydata[]; + +type AnydataArray2 anydata[2]; + +type AnydataArray3 anydata[]; + +type AnydataArray4 anydata[2]; + +type AnydataArray5 anydata[3]; + +type AnydataArray6 anydata[4]; + +type CustomArray1 CustomTuple2[]; + +type CustomArray2 CustomTuple2[2]; + +type CustomArray3 CustomTuple2[]; + +type CustomArray4 CustomTuple2[2]; + +type CustomArray5 CustomTuple2[3]; + +type CustomArray6 CustomTuple2[4]; + +type IntegerMap map; + +type StringMap map; + +type NillableIntUnionStringMap map; + +type IntUnionStringMap map; + +type DecimalMap map; + +type FloatMap map; + +type BooleanMap map; + +type NillableBooleanMap map; + +type NillableIntUnionBooleanMap map; + +type IntUnionBooleanMap map; + +type NilMap map<()>; + +type JsonMap map; + +type AnydataMap map; + +type CustomMap map; + +type BooleanRecord1Array BooleanRecord1[]; + +type ClosedBooleanRecord1Array BooleanRecord1[3]; + +type BooleanRecord2Array BooleanRecord2[]; + +type ClosedBooleanRecord2Array BooleanRecord2[3]; + +type BooleanRecord3Array BooleanRecord3[]; + +type ClosedBooleanRecord3Array BooleanRecord3[3]; + +type BooleanRecord4Array BooleanRecord4[]; + +type ClosedBooleanRecord4Array BooleanRecord4[3]; + +type BooleanRecord5Array BooleanRecord5[]; + +type ClosedBooleanRecord5Array BooleanRecord5[3]; + +type BooleanRecord6Array BooleanRecord6[]; + +type ClosedBooleanRecord6Array BooleanRecord6[3]; + +type BooleanRecord7Array BooleanRecord7[]; + +type ClosedBooleanRecord7Array BooleanRecord7[3]; + +type BooleanRecord8Array BooleanRecord8[]; + +type ClosedBooleanRecord8Array BooleanRecord8[3]; + +type BooleanRecord9Array BooleanRecord9[]; + +type ClosedBooleanRecord9Array BooleanRecord9[3]; + +type BooleanRecord10Array BooleanRecord10[]; + +type ClosedBooleanRecord10Array BooleanRecord10[3]; + +type BooleanRecord11Array BooleanRecord11[]; + +type ClosedBooleanRecord11Array BooleanRecord11[3]; + +type BooleanRecord12Array BooleanRecord12[]; + +type ClosedBooleanRecord12Array BooleanRecord12[3]; + +type BooleanRecord13Array BooleanRecord13[]; + +type ClosedBooleanRecord13Array BooleanRecord13[3]; + +type BooleanRecord14Array BooleanRecord14[]; + +type ClosedBooleanRecord14Array BooleanRecord14[3]; + +type BooleanRecord15Array BooleanRecord15[]; + +type ClosedBooleanRecord15Array BooleanRecord15[3]; + +type BooleanRecord16Array BooleanRecord16[]; + +type ClosedBooleanRecord16Array BooleanRecord16[3]; + +type BooleanRecord17Array BooleanRecord17[]; + +type ClosedBooleanRecord17Array BooleanRecord17[3]; + +type BooleanRecord18Array BooleanRecord18[]; + +type ClosedBooleanRecord18Array BooleanRecord18[3]; + +type NilRecord1Array NilRecord1[]; + +type ClosedNilRecord1Array NilRecord1[3]; + +type NilRecord2Array NilRecord2[]; + +type ClosedNilRecord2Array NilRecord2[3]; + +type NilRecord3Array NilRecord3[]; + +type ClosedNilRecord3Array NilRecord3[3]; + +type NilRecord4Array NilRecord4[]; + +type ClosedNilRecord4Array NilRecord4[3]; + +type NilRecord5Array NilRecord5[]; + +type ClosedNilRecord5Array NilRecord5[3]; + +type NilRecord6Array NilRecord6[]; + +type ClosedNilRecord6Array NilRecord6[3]; + +type NilRecord7Array NilRecord7[]; + +type ClosedNilRecord7Array NilRecord7[3]; + +type NilRecord8Array NilRecord8[]; + +type ClosedNilRecord8Array NilRecord8[3]; + +type NilRecord9Array NilRecord9[]; + +type ClosedNilRecord9Array NilRecord9[3]; + +type NilRecord10Array NilRecord10[]; + +type ClosedNilRecord10Array NilRecord10[3]; + +type NilRecord11Array NilRecord11[]; + +type ClosedNilRecord11Array NilRecord11[3]; + +type NilRecord12Array NilRecord12[]; + +type ClosedNilRecord12Array NilRecord12[3]; + +type NilRecord13Array NilRecord13[]; + +type ClosedNilRecord13Array NilRecord13[3]; + +type NilRecord14Array NilRecord14[]; + +type ClosedNilRecord14Array NilRecord14[3]; + +type IntegerRecord1Array IntegerRecord1[]; + +type ClosedIntegerRecord1Array IntegerRecord1[3]; + +type IntegerRecord2Array IntegerRecord2[]; + +type ClosedIntegerRecord2Array IntegerRecord2[3]; + +type IntegerRecord3Array IntegerRecord3[]; + +type ClosedIntegerRecord3Array IntegerRecord3[3]; + +type IntegerRecord4Array IntegerRecord4[]; + +type ClosedIntegerRecord4Array IntegerRecord4[3]; + +type IntegerRecord5Array IntegerRecord5[]; + +type ClosedIntegerRecord5Array IntegerRecord5[3]; + +type IntegerRecord6Array IntegerRecord6[]; + +type ClosedIntegerRecord6Array IntegerRecord6[3]; + +type IntegerRecord7Array IntegerRecord7[]; + +type ClosedIntegerRecord7Array IntegerRecord7[3]; + +type IntegerRecord8Array IntegerRecord8[]; + +type ClosedIntegerRecord8Array IntegerRecord8[3]; + +type IntegerRecord9Array IntegerRecord9[]; + +type ClosedIntegerRecord9Array IntegerRecord9[3]; + +type IntegerRecord10Array IntegerRecord10[]; + +type ClosedIntegerRecord10Array IntegerRecord10[3]; + +type IntegerRecord11Array IntegerRecord11[]; + +type ClosedIntegerRecord11Array IntegerRecord11[3]; + +type IntegerRecord12Array IntegerRecord12[]; + +type ClosedIntegerRecord12Array IntegerRecord12[3]; + +type IntegerRecord13Array IntegerRecord13[]; + +type ClosedIntegerRecord13Array IntegerRecord13[3]; + +type IntegerRecord14Array IntegerRecord14[]; + +type ClosedIntegerRecord14Array IntegerRecord14[3]; + +type FloatRecord1Array FloatRecord1[]; + +type ClosedFloatRecord1Array FloatRecord1[3]; + +type FloatRecord2Array FloatRecord2[]; + +type ClosedFloatRecord2Array FloatRecord2[3]; + +type FloatRecord3Array FloatRecord3[]; + +type ClosedFloatRecord3Array FloatRecord3[3]; + +type FloatRecord4Array FloatRecord4[]; + +type ClosedFloatRecord4Array FloatRecord4[3]; + +type FloatRecord5Array FloatRecord5[]; + +type ClosedFloatRecord5Array FloatRecord5[3]; + +type FloatRecord6Array FloatRecord6[]; + +type ClosedFloatRecord6Array FloatRecord6[3]; + +type FloatRecord7Array FloatRecord7[]; + +type ClosedFloatRecord7Array FloatRecord7[3]; + +type FloatRecord8Array FloatRecord8[]; + +type ClosedFloatRecord8Array FloatRecord8[3]; + +type FloatRecord9Array FloatRecord9[]; + +type ClosedFloatRecord9Array FloatRecord9[3]; + +type FloatRecord10Array FloatRecord10[]; + +type ClosedFloatRecord10Array FloatRecord10[3]; + +type FloatRecord11Array FloatRecord11[]; + +type ClosedFloatRecord11Array FloatRecord11[3]; + +type FloatRecord12Array FloatRecord12[]; + +type ClosedFloatRecord12Array FloatRecord12[3]; + +type FloatRecord13Array FloatRecord13[]; + +type ClosedFloatRecord13Array FloatRecord13[3]; + +type FloatRecord14Array FloatRecord14[]; + +type ClosedFloatRecord14Array FloatRecord14[3]; + +type DecimalRecord1Array DecimalRecord1[]; + +type ClosedDecimalRecord1Array DecimalRecord1[3]; + +type DecimalRecord2Array DecimalRecord2[]; + +type ClosedDecimalRecord2Array DecimalRecord2[3]; + +type DecimalRecord3Array DecimalRecord3[]; + +type ClosedDecimalRecord3Array DecimalRecord3[3]; + +type DecimalRecord4Array DecimalRecord4[]; + +type ClosedDecimalRecord4Array DecimalRecord4[3]; + +type DecimalRecord5Array DecimalRecord5[]; + +type ClosedDecimalRecord5Array DecimalRecord5[3]; + +type DecimalRecord6Array DecimalRecord6[]; + +type ClosedDecimalRecord6Array DecimalRecord6[3]; + +type DecimalRecord7Array DecimalRecord7[]; + +type ClosedDecimalRecord7Array DecimalRecord7[3]; + +type DecimalRecord8Array DecimalRecord8[]; + +type ClosedDecimalRecord8Array DecimalRecord8[3]; + +type DecimalRecord9Array DecimalRecord9[]; + +type ClosedDecimalRecord9Array DecimalRecord9[3]; + +type DecimalRecord10Array DecimalRecord10[]; + +type ClosedDecimalRecord10Array DecimalRecord10[3]; + +type DecimalRecord11Array DecimalRecord11[]; + +type ClosedDecimalRecord11Array DecimalRecord11[3]; + +type DecimalRecord12Array DecimalRecord12[]; + +type ClosedDecimalRecord12Array DecimalRecord12[3]; + +type DecimalRecord13Array DecimalRecord13[]; + +type ClosedDecimalRecord13Array DecimalRecord13[3]; + +type DecimalRecord14Array DecimalRecord14[]; + +type ClosedDecimalRecord14Array DecimalRecord14[3]; + +type StringRecord1Array StringRecord1[]; + +type ClosedStringRecord1Array StringRecord1[3]; + +type StringRecord2Array StringRecord2[]; + +type ClosedStringRecord2Array StringRecord2[3]; + +type StringRecord3Array StringRecord3[]; + +type ClosedStringRecord3Array StringRecord3[3]; + +type StringRecord4Array StringRecord4[]; + +type ClosedStringRecord4Array StringRecord4[3]; + +type StringRecord5Array StringRecord5[]; + +type ClosedStringRecord5Array StringRecord5[3]; + +type StringRecord6Array StringRecord6[]; + +type ClosedStringRecord6Array StringRecord6[3]; + +type StringRecord7Array StringRecord7[]; + +type ClosedStringRecord7Array StringRecord7[3]; + +type StringRecord8Array StringRecord8[]; + +type ClosedStringRecord8Array StringRecord8[3]; + +type StringRecord9Array StringRecord9[]; + +type ClosedStringRecord9Array StringRecord9[3]; + +type StringRecord10Array StringRecord10[]; + +type ClosedStringRecord10Array StringRecord10[3]; + +type StringRecord11Array StringRecord11[]; + +type ClosedStringRecord11Array StringRecord11[3]; + +type StringRecord12Array StringRecord12[]; + +type ClosedStringRecord12Array StringRecord12[3]; + +type StringRecord13Array StringRecord13[]; + +type ClosedStringRecord13Array StringRecord13[3]; + +type StringRecord14Array StringRecord14[]; + +type ClosedStringRecord14Array StringRecord14[3]; + +type StringRecord15Array StringRecord15[]; + +type StringRecord16Array StringRecord16[]; + +type StringRecord17Array StringRecord17[]; + +type StringRecord18Array StringRecord18[]; + +type StringRecord19Array StringRecord19[]; + +type StringRecord20Array StringRecord20[]; + +type StringRecord21Array StringRecord21[]; + +type StringRecord22Array StringRecord22[]; + +type StringRecord23Array StringRecord23[]; + +type JsonRecord1Array JsonRecord1[]; + +type ClosedJsonRecord1Array JsonRecord1[3]; + +type JsonRecord2Array JsonRecord2[]; + +type ClosedJsonRecord2Array JsonRecord2[3]; + +type JsonRecord3Array JsonRecord3[]; + +type ClosedJsonRecord3Array JsonRecord3[3]; + +type JsonRecord4Array JsonRecord4[]; + +type ClosedJsonRecord4Array JsonRecord4[3]; + +type JsonRecord5Array JsonRecord5[]; + +type ClosedJsonRecord5Array JsonRecord5[3]; + +type JsonRecord6Array JsonRecord6[]; + +type ClosedJsonRecord6Array JsonRecord6[3]; + +type JsonRecord7Array JsonRecord7[]; + +type ClosedJsonRecord7Array JsonRecord7[3]; + +type JsonRecord8Array JsonRecord8[]; + +type ClosedJsonRecord8Array JsonRecord8[3]; + +type JsonRecord9Array JsonRecord9[]; + +type ClosedJsonRecord9Array JsonRecord9[3]; + +type JsonRecord10Array JsonRecord10[]; + +type ClosedJsonRecord10Array JsonRecord10[3]; + +type JsonRecord11Array JsonRecord11[]; + +type ClosedJsonRecord11Array JsonRecord11[3]; + +type JsonRecord12Array JsonRecord12[]; + +type ClosedJsonRecord12Array JsonRecord12[3]; + +type JsonRecord13Array JsonRecord13[]; + +type ClosedJsonRecord13Array JsonRecord13[3]; + +type JsonRecord14Array JsonRecord14[]; + +type ClosedJsonRecord14Array JsonRecord14[3]; + +type AnydataRecord1Array AnydataRecord1[]; + +type ClosedAnydataRecord1Array AnydataRecord1[3]; + +type AnydataRecord2Array AnydataRecord2[]; + +type ClosedAnydataRecord2Array AnydataRecord2[3]; + +type AnydataRecord3Array AnydataRecord3[]; + +type ClosedAnydataRecord3Array AnydataRecord3[3]; + +type AnydataRecord4Array AnydataRecord4[]; + +type ClosedAnydataRecord4Array AnydataRecord4[3]; + +type AnydataRecord5Array AnydataRecord5[]; + +type ClosedAnydataRecord5Array AnydataRecord5[3]; + +type AnydataRecord6Array AnydataRecord6[]; + +type ClosedAnydataRecord6Array AnydataRecord6[3]; + +type AnydataRecord7Array AnydataRecord7[]; + +type ClosedAnydataRecord7Array AnydataRecord7[3]; + +type AnydataRecord8Array AnydataRecord8[]; + +type ClosedAnydataRecord8Array AnydataRecord8[3]; + +type AnydataRecord9Array AnydataRecord9[]; + +type ClosedAnydataRecord9Array AnydataRecord9[3]; + +type AnydataRecord10Array AnydataRecord10[]; + +type ClosedAnydataRecord10Array AnydataRecord10[3]; + +type AnydataRecord11Array AnydataRecord11[]; + +type ClosedAnydataRecord11Array AnydataRecord11[3]; + +type AnydataRecord12Array AnydataRecord12[]; + +type ClosedAnydataRecord12Array AnydataRecord12[3]; + +type AnydataRecord13Array AnydataRecord13[]; + +type ClosedAnydataRecord13Array AnydataRecord13[3]; + +type AnydataRecord14Array AnydataRecord14[]; + +type ClosedAnydataRecord14Array AnydataRecord14[3]; + +type CustomRecord1Array CustomRecord1[]; + +type ClosedCustomRecord1Array CustomRecord1[3]; + +type CustomRecord2Array CustomRecord2[]; + +type ClosedCustomRecord2Array CustomRecord2[3]; + +type CustomRecord3Array CustomRecord3[]; + +type ClosedCustomRecord3Array CustomRecord3[3]; + +type CustomRecord4Array CustomRecord4[]; + +type ClosedCustomRecord4Array CustomRecord4[3]; + +type CustomRecord5Array CustomRecord5[]; + +type ClosedCustomRecord5Array CustomRecord5[3]; + +type CustomRecord6Array CustomRecord6[]; + +type ClosedCustomRecord6Array CustomRecord6[3]; + +type CustomRecord7Array CustomRecord7[]; + +type ClosedCustomRecord7Array CustomRecord7[3]; + +type CustomRecord8Array CustomRecord8[]; + +type ClosedCustomRecord8Array CustomRecord8[3]; + +type CustomRecord9Array CustomRecord9[]; + +type ClosedCustomRecord9Array CustomRecord9[3]; + +type CustomRecord10Array CustomRecord10[]; + +type ClosedCustomRecord10Array CustomRecord10[3]; + +type CustomRecord11Array CustomRecord11[]; + +type ClosedCustomRecord11Array CustomRecord11[3]; + +type CustomRecord12Array CustomRecord12[]; + +type ClosedCustomRecord12Array CustomRecord12[3]; + +type CustomRecord13Array CustomRecord13[]; + +type ClosedCustomRecord13Array CustomRecord13[3]; + +type CustomRecord14Array CustomRecord14[]; + +type ClosedCustomRecord14Array CustomRecord14[3]; + +type CustomRecord15Array CustomRecord15[]; + +type CustomRecord16Array CustomRecord16[]; + +type CustomRecord17Array CustomRecord17[]; + +type CustomRecord18Array CustomRecord18[]; + +type CustomRecord19Array CustomRecord19[]; + +type CustomRecord20Array CustomRecord20[]; + +type CustomRecord21Array CustomRecord21[]; + +type CustomRecord22Array CustomRecord22[]; + +type CustomRecord23Array CustomRecord23[]; + +type CustomRecord24Array CustomRecord24[]; + +type CustomRecord25Array CustomRecord25[]; + +type CustomRecord26Array CustomRecord26[]; + +type CustomRecord27Array CustomRecord27[]; +type CustomRecord28Array CustomRecord28[]; +type CustomRecord29Array CustomRecord29[]; +type CustomRecord30Array CustomRecord30[]; +type CustomRecord31Array CustomRecord31[]; +type CustomRecord32Array CustomRecord32[]; +type CustomRecord33Array CustomRecord33[]; +type CustomRecord34Array CustomRecord34[]; +type CustomRecord35Array CustomRecord35[]; +type CustomRecord36Array CustomRecord36[]; +type CustomRecord37Array CustomRecord37[]; +type CustomRecord38Array CustomRecord38[]; +type CustomRecord39Array CustomRecord39[]; +type CustomRecord40Array CustomRecord40[]; +type CustomRecord41Array CustomRecord41[]; +type CustomRecord42Array CustomRecord42[]; +type CustomRecord43Array CustomRecord43[]; +type CustomRecord44Array CustomRecord44[]; +type CustomRecord45Array CustomRecord45[]; +type CustomRecord46Array CustomRecord46[]; +type CustomRecord47Array CustomRecord47[]; +type CustomRecord48Array CustomRecord48[]; +type CustomRecord49Array CustomRecord49[]; +type CustomRecord50Array CustomRecord50[]; +type CustomRecord51Array CustomRecord51[]; +type CustomRecord52Array CustomRecord52[]; +type CustomRecord53Array CustomRecord53[]; +type CustomRecord54Array CustomRecord54[]; +type CustomRecord55Array CustomRecord55[]; +type CustomRecord56Array CustomRecord56[]; + +type BooleanTuple1Array BooleanTuple1[]; + +type ClosedBooleanTuple1Array BooleanTuple1[3]; + +type BooleanTuple2Array BooleanTuple2[]; + +type ClosedBooleanTuple2Array BooleanTuple2[3]; + +type BooleanTuple3Array BooleanTuple3[]; + +type ClosedBooleanTuple3Array BooleanTuple3[3]; + +type BooleanTuple4Array BooleanTuple4[]; + +type ClosedBooleanTuple4Array BooleanTuple4[3]; + +type NillableBooleanTuple5Array NillableBooleanTuple5[]; + +type NillableBooleanTuple6Array NillableBooleanTuple6[]; + +type NillableBooleanTuple7Array NillableBooleanTuple7[]; + +type NillableBooleanTuple8Array NillableBooleanTuple8[]; + +type NillableIntBooleanTuple9Array NillableIntBooleanTuple9[]; + +type NilTuple1Array NilTuple1[]; + +type ClosedNilTuple1Array NilTuple1[3]; + +type NilTuple2Array NilTuple2[]; + +type ClosedNilTuple2Array NilTuple2[3]; + +type NilTuple3Array NilTuple3[]; + +type ClosedNilTuple3Array NilTuple3[3]; + +type NilTuple4Array NilTuple4[]; + +type ClosedNilTuple4Array NilTuple4[3]; + +type IntegerTuple1Array IntegerTuple1[]; + +type ClosedIntegerTuple1Array IntegerTuple1[3]; + +type IntegerTuple2Array IntegerTuple2[]; + +type ClosedIntegerTuple2Array IntegerTuple2[3]; + +type IntegerTuple3Array IntegerTuple3[]; + +type ClosedIntegerTuple3Array IntegerTuple3[3]; + +type IntegerTuple4Array IntegerTuple4[]; + +type ClosedIntegerTuple4Array IntegerTuple4[3]; + +type FloatTuple1Array FloatTuple1[]; + +type ClosedFloatTuple1Array FloatTuple1[3]; + +type FloatTuple2Array FloatTuple2[]; + +type ClosedFloatTuple2Array FloatTuple2[3]; + +type FloatTuple3Array FloatTuple3[]; + +type ClosedFloatTuple3Array FloatTuple3[3]; + +type FloatTuple4Array FloatTuple4[]; + +type ClosedFloatTuple4Array FloatTuple4[3]; + +type DecimalTuple1Array DecimalTuple1[]; + +type ClosedDecimalTuple1Array DecimalTuple1[3]; + +type DecimalTuple2Array DecimalTuple2[]; + +type ClosedDecimalTuple2Array DecimalTuple2[3]; + +type DecimalTuple3Array DecimalTuple3[]; + +type ClosedDecimalTuple3Array DecimalTuple3[3]; + +type DecimalTuple4Array DecimalTuple4[]; + +type ClosedDecimalTuple4Array DecimalTuple4[3]; + +type StringTuple1Array StringTuple1[]; + +type ClosedStringTuple1Array StringTuple1[3]; + +type StringTuple2Array StringTuple2[]; + +type ClosedStringTuple2Array StringTuple2[3]; + +type StringTuple3Array StringTuple3[]; + +type ClosedStringTuple3Array StringTuple3[3]; + +type StringTuple4Array StringTuple4[]; + +type ClosedStringTuple4Array StringTuple4[3]; + +type AnydataTuple1Array AnydataTuple1[]; + +type ClosedAnydataTuple1Array AnydataTuple1[3]; + +type AnydataTuple2Array AnydataTuple2[]; + +type ClosedAnydataTuple2Array AnydataTuple2[3]; + +type AnydataTuple3Array AnydataTuple3[]; + +type ClosedAnydataTuple3Array AnydataTuple3[3]; + +type AnydataTuple4Array AnydataTuple4[]; + +type ClosedAnydataTuple4Array AnydataTuple4[3]; + +type JsonTuple1Array JsonTuple1[]; + +type ClosedJsonTuple1Array JsonTuple1[3]; + +type JsonTuple2Array JsonTuple2[]; + +type ClosedJsonTuple2Array JsonTuple2[3]; + +type JsonTuple3Array JsonTuple3[]; + +type ClosedJsonTuple3Array JsonTuple3[3]; + +type JsonTuple4Array JsonTuple4[]; + +type ClosedJsonTuple4Array JsonTuple4[3]; + +type CustomTuple1Array CustomTuple1[]; + +type ClosedCustomTuple1Array CustomTuple1[3]; + +type CustomTuple2Array CustomTuple2[]; + +type ClosedCustomTuple2Array CustomTuple2[3]; + +type CustomTuple3Array CustomTuple3[]; + +type ClosedCustomTuple3Array CustomTuple3[3]; + +type CustomTuple4Array CustomTuple4[]; + +type ClosedCustomTuple4Array CustomTuple4[3]; + +type CustomTuple5Array CustomTuple5[]; + +type ClosedCustomTuple5Array CustomTuple5[3]; + +type CustomTuple6Array CustomTuple6[]; + +type CustomTuple7Array CustomTuple7[]; + +type CustomTuple8Array CustomTuple8[]; + +type ClosedCustomTuple6Array CustomTuple6[3]; + +type IntegerArray1Array IntegerArray1[]; + +type ClosedIntegerArray1Array IntegerArray1[3]; + +type IntegerArray2Array IntegerArray2[]; + +type ClosedIntegerArray2Array IntegerArray2[3]; + +type IntegerArray3Array IntegerArray3[]; + +type ClosedIntegerArray3Array IntegerArray3[3]; + +type IntegerArray4Array IntegerArray4[]; + +type ClosedIntegerArray4Array IntegerArray4[3]; + +type IntegerArray5Array IntegerArray5[]; + +type ClosedIntegerArray5Array IntegerArray5[3]; + +type IntegerArray6Array IntegerArray5[]; + +type ClosedIntegerArray6Array IntegerArray5[3]; + +type StringArray1Array StringArray1[]; + +type StringArrayArray StringArray[]; + +type NillableStringArrayArray NillableStringArray[]; + +type NillableIntOrUnionStringArrayArray NillableIntOrUnionStringArray[]; + +type ClosedStringArray1Array StringArray1[3]; + +type StringArray2Array StringArray2[]; + +type ClosedStringArray2Array StringArray2[3]; + +type StringArray3Array StringArray3[]; + +type ClosedStringArray3Array StringArray3[3]; + +type StringArray4Array StringArray4[]; + +type ClosedStringArray4Array StringArray4[3]; + +type StringArray5Array StringArray5[]; + +type ClosedStringArray5Array StringArray5[3]; + +type StringArray6Array StringArray5[]; + +type ClosedStringArray6Array StringArray5[3]; + +type FloatArray1Array FloatArray1[]; + +type ClosedFloatArray1Array FloatArray1[3]; + +type FloatArray2Array FloatArray2[]; + +type ClosedFloatArray2Array FloatArray2[3]; + +type FloatArray3Array FloatArray3[]; + +type ClosedFloatArray3Array FloatArray3[3]; + +type FloatArray4Array FloatArray4[]; + +type ClosedFloatArray4Array FloatArray4[3]; + +type FloatArray5Array FloatArray5[]; + +type ClosedFloatArray5Array FloatArray5[3]; + +type FloatArray6Array FloatArray5[]; + +type ClosedFloatArray6Array FloatArray5[3]; + +type DecimalArray1Array DecimalArray1[]; + +type ClosedDecimalArray1Array DecimalArray1[3]; + +type DecimalArray2Array DecimalArray2[]; + +type ClosedDecimalArray2Array DecimalArray2[3]; + +type DecimalArray3Array DecimalArray3[]; + +type ClosedDecimalArray3Array DecimalArray3[3]; + +type DecimalArray4Array DecimalArray4[]; + +type ClosedDecimalArray4Array DecimalArray4[3]; + +type DecimalArray5Array DecimalArray5[]; + +type ClosedDecimalArray5Array DecimalArray5[3]; + +type DecimalArray6Array DecimalArray5[]; + +type ClosedDecimalArray6Array DecimalArray5[3]; + +type BooleanArrayArray BooleanArray[]; + +type ClosedBooleanArrayArray BooleanArray[3]; + +type NillableBooleanArrayArray NillableBooleanArray[]; + +type NillableIntOrUnionBooleanArrayArray NillableIntOrUnionBooleanArray[]; + +type BooleanArray2Array BooleanArray2[]; + +type ClosedBooleanArray2Array BooleanArray2[3]; + +type BooleanArray3Array BooleanArray3[]; + +type ClosedBooleanArray3Array BooleanArray3[3]; + +type BooleanArray4Array BooleanArray4[]; + +type ClosedBooleanArray4Array BooleanArray4[3]; + +type BooleanArray5Array BooleanArray5[]; + +type ClosedBooleanArray5Array BooleanArray5[3]; + +type BooleanArray6Array BooleanArray5[]; + +type ClosedBooleanArray6Array BooleanArray5[3]; + +type NilArray1Array NilArray1[]; + +type ClosedNilArray1Array NilArray1[3]; + +type NilArray2Array NilArray2[]; + +type ClosedNilArray2Array NilArray2[3]; + +type NilArray3Array NilArray3[]; + +type ClosedNilArray3Array NilArray3[3]; + +type NilArray4Array NilArray4[]; + +type ClosedNilArray4Array NilArray4[3]; + +type NilArray5Array NilArray5[]; + +type ClosedNilArray5Array NilArray5[3]; + +type NilArray6Array NilArray5[]; + +type ClosedNilArray6Array NilArray5[3]; + +type JsonArray1Array JsonArray1[]; + +type ClosedJsonArray1Array JsonArray1[3]; + +type JsonArray2Array JsonArray2[]; + +type ClosedJsonArray2Array JsonArray2[3]; + +type JsonArray3Array JsonArray3[]; + +type ClosedJsonArray3Array JsonArray3[3]; + +type JsonArray4Array JsonArray4[]; + +type ClosedJsonArray4Array JsonArray4[3]; + +type JsonArray5Array JsonArray5[]; + +type ClosedJsonArray5Array JsonArray5[3]; + +type JsonArray6Array JsonArray5[]; + +type ClosedJsonArray6Array JsonArray5[3]; + +type AnydataArray1Array AnydataArray1[]; + +type ClosedAnydataArray1Array AnydataArray1[3]; + +type AnydataArray2Array AnydataArray2[]; + +type ClosedAnydataArray2Array AnydataArray2[3]; + +type AnydataArray3Array AnydataArray3[]; + +type ClosedAnydataArray3Array AnydataArray3[3]; + +type AnydataArray4Array AnydataArray4[]; + +type ClosedAnydataArray4Array AnydataArray4[3]; + +type AnydataArray5Array AnydataArray5[]; + +type ClosedAnydataArray5Array AnydataArray5[3]; + +type AnydataArray6Array AnydataArray5[]; + +type ClosedAnydataArray6Array AnydataArray5[3]; + +type CustomArray1Array CustomArray1[]; + +type ClosedCustomArray1Array CustomArray1[3]; + +type CustomArray2Array CustomArray2[]; + +type ClosedCustomArray2Array CustomArray2[3]; + +type CustomArray3Array CustomArray3[]; + +type ClosedCustomArray3Array CustomArray3[3]; + +type CustomArray4Array CustomArray4[]; + +type ClosedCustomArray4Array CustomArray4[3]; + +type CustomArray5Array CustomArray5[]; + +type ClosedCustomArray5Array CustomArray5[3]; + +type CustomArray6Array CustomArray5[]; + +type ClosedCustomArray6Array CustomArray5[3]; + +type IntegerMapArray IntegerMap[]; + +type ClosedIntegerMapArray IntegerMap[3]; + +type StringMapArray StringMap[]; + +type NillableIntUnionStringMapArray NillableIntUnionStringMap[]; + +type IntUnionStringMapArray IntUnionStringMap[]; + +type ClosedStringMapArray StringMap[3]; + +type DecimalMapArray DecimalMap[]; + +type ClosedDecimalMapArray DecimalMap[3]; + +type FloatMapArray FloatMap[]; + +type ClosedFloatMapArray FloatMap[3]; + +type BooleanMapArray BooleanMap[]; + +type NillableBooleanMapArray NillableBooleanMap[]; + +type NillableIntUnionBooleanMapArray NillableIntUnionBooleanMap[]; + +type IntUnionBooleanMapArray IntUnionBooleanMap[]; + +type ClosedBooleanMapArray BooleanMap[3]; + +type NilMapArray NilMap[]; + +type ClosedNilMapArray NilMap[3]; + +type JsonMapArray JsonMap[]; + +type ClosedJsonMapArray JsonMap[3]; + +type AnydataMapArray AnydataMap[]; + +type ClosedAnydataMapArray AnydataMap[3]; + +type CustomMapArray CustomMap[]; + +type ClosedCustomMapArray CustomMap[3]; diff --git a/ballerina-tests/parse-string-array-types-tests/.gitignore b/ballerina-tests/parse-string-array-types-tests/.gitignore new file mode 100644 index 0000000..d5fc29a --- /dev/null +++ b/ballerina-tests/parse-string-array-types-tests/.gitignore @@ -0,0 +1,11 @@ +# Ballerina generates this directory during the compilation of a package. +# It contains compiler-generated artifacts and the final executable if this is an application package. +target/ + +# Ballerina maintains the compiler-generated source code here. +# Remove this if you want to commit generated sources. +generated/ + +# Contains configuration values used during development time. +# See https://ballerina.io/learn/provide-values-to-configurable-variables/ for more details. +Config.toml diff --git a/ballerina-tests/parse-string-array-types-tests/Ballerina.toml b/ballerina-tests/parse-string-array-types-tests/Ballerina.toml new file mode 100644 index 0000000..256e0d0 --- /dev/null +++ b/ballerina-tests/parse-string-array-types-tests/Ballerina.toml @@ -0,0 +1,13 @@ +[package] +org = "ballerina" +name = "parse_string_array_types_tests" +version = "0.1.0" + +[[dependency]] +org = "ballerina" +name = "csv_commons" +repository = "local" +version = "0.1.0" + +[platform.java17] +graalvmCompatible = true diff --git a/ballerina-tests/parse-string-array-types-tests/Dependencies.toml b/ballerina-tests/parse-string-array-types-tests/Dependencies.toml new file mode 100644 index 0000000..81c0d40 --- /dev/null +++ b/ballerina-tests/parse-string-array-types-tests/Dependencies.toml @@ -0,0 +1,98 @@ +# AUTO-GENERATED FILE. DO NOT MODIFY. + +# This file is auto-generated by Ballerina for managing dependency versions. +# It should not be modified by hand. + +[ballerina] +dependencies-toml-version = "2" +distribution-version = "2201.9.0" + +[[package]] +org = "ballerina" +name = "csv_commons" +version = "0.1.0" +scope = "testOnly" +modules = [ + {org = "ballerina", packageName = "csv_commons", moduleName = "csv_commons"} +] + +[[package]] +org = "ballerina" +name = "data.csv" +version = "0.1.0" +scope = "testOnly" +dependencies = [ + {org = "ballerina", name = "jballerina.java"} +] +modules = [ + {org = "ballerina", packageName = "data.csv", moduleName = "data.csv"} +] + +[[package]] +org = "ballerina" +name = "jballerina.java" +version = "0.0.0" +scope = "testOnly" + +[[package]] +org = "ballerina" +name = "lang.__internal" +version = "0.0.0" +scope = "testOnly" +dependencies = [ + {org = "ballerina", name = "jballerina.java"}, + {org = "ballerina", name = "lang.object"} +] + +[[package]] +org = "ballerina" +name = "lang.array" +version = "0.0.0" +scope = "testOnly" +dependencies = [ + {org = "ballerina", name = "jballerina.java"}, + {org = "ballerina", name = "lang.__internal"} +] + +[[package]] +org = "ballerina" +name = "lang.error" +version = "0.0.0" +scope = "testOnly" +dependencies = [ + {org = "ballerina", name = "jballerina.java"} +] + +[[package]] +org = "ballerina" +name = "lang.object" +version = "0.0.0" +scope = "testOnly" + +[[package]] +org = "ballerina" +name = "parse_string_array_types_tests" +version = "0.1.0" +dependencies = [ + {org = "ballerina", name = "csv_commons"}, + {org = "ballerina", name = "data.csv"}, + {org = "ballerina", name = "test"} +] +modules = [ + {org = "ballerina", packageName = "parse_string_array_types_tests", moduleName = "parse_string_array_types_tests"} +] + +[[package]] +org = "ballerina" +name = "test" +version = "0.0.0" +scope = "testOnly" +dependencies = [ + {org = "ballerina", name = "jballerina.java"}, + {org = "ballerina", name = "lang.array"}, + {org = "ballerina", name = "lang.error"} +] +modules = [ + {org = "ballerina", packageName = "test", moduleName = "test"} +] + diff --git a/ballerina-tests/parse-string-array-types-tests/tests/parse_string_to_array_test.bal b/ballerina-tests/parse-string-array-types-tests/tests/parse_string_to_array_test.bal new file mode 100644 index 0000000..ce7d4c5 --- /dev/null +++ b/ballerina-tests/parse-string-array-types-tests/tests/parse_string_to_array_test.bal @@ -0,0 +1,436 @@ +import ballerina/csv_commons as common; +import ballerina/data.csv as csv; +import ballerina/test; + +@test:Config +function testFromCsvStringWithTypeForStringAndArrayAsExpectedType() { + BooleanArrayArray|csv:Error cv1baa = csv:parseStringToList(csvStringWithBooleanValues1); + test:assertEquals(cv1baa, [ + [true, false, true, false], + [true, false, true, false], + [true, false, true, false] + ]); + + BooleanArrayArray|csv:Error cv2baa = csv:parseStringToList(csvStringWithBooleanValues2); + test:assertEquals(cv2baa, [ + [true, false, true, false, true], + [true, false, true, false, true] + ]); + + BooleanArrayArray|csv:Error cv3baa = csv:parseStringToList(csvStringWithBooleanValues3); + test:assertTrue(cv3baa is csv:Error); + test:assertEquals((cv3baa).message(), common:generateErrorMessageForInvalidCast("()", "boolean")); + + BooleanArrayArray|csv:Error cv4baa = csv:parseStringToList(csvStringWithBooleanValues4); + test:assertTrue(cv4baa is csv:Error); + test:assertEquals((cv4baa).message(), common:generateErrorMessageForInvalidCast("()", "boolean")); + + BooleanArrayArray|csv:Error cv5baa = csv:parseStringToList(csvStringWithBooleanValues5); + test:assertTrue(cv5baa is csv:Error); + test:assertEquals((cv5baa).message(), common:generateErrorMessageForInvalidCast("2", "boolean")); + + BooleanArrayArray|csv:Error cv6baa = csv:parseStringToList(csvStringWithBooleanValues6); + test:assertTrue(cv6baa is csv:Error); + test:assertEquals((cv6baa).message(), common:generateErrorMessageForInvalidCast("()", "boolean")); + + BooleanArrayArray|csv:Error cv7baa = csv:parseStringToList(csvStringWithBooleanValues7); + test:assertTrue(cv7baa is csv:Error); + test:assertEquals((cv7baa).message(), common:generateErrorMessageForInvalidCast("()", "boolean")); + + NillableBooleanArrayArray|csv:Error cv1nbaa = csv:parseStringToList(csvStringWithBooleanValues1); + test:assertEquals(cv1nbaa, [ + [true, false, true, false], + [true, false, true, false], + [true, false, true, false] + ]); + + NillableBooleanArrayArray|csv:Error cv2nbaa = csv:parseStringToList(csvStringWithBooleanValues2); + test:assertEquals(cv2nbaa, [ + [true, false, true, false, true], + [true, false, true, false, true] + ]); + + NillableBooleanArrayArray|csv:Error cv3nbaa = csv:parseStringToList(csvStringWithBooleanValues3); + test:assertEquals(cv3nbaa, [ + [true, false, true], + [true, false, ()], + [true, true, false] + ]); + + NillableBooleanArrayArray|csv:Error cv4nbaa = csv:parseStringToList(csvStringWithBooleanValues4); + test:assertEquals(cv4nbaa, [ + [true, (), (), false], + [true, (), (), false] + ]); + + NillableBooleanArrayArray|csv:Error cv5nbaa = csv:parseStringToList(csvStringWithBooleanValues5); + test:assertTrue(cv5nbaa is csv:Error); + test:assertEquals((cv5nbaa).message(), common:generateErrorMessageForInvalidCast("2", "boolean?")); + + NillableBooleanArrayArray|csv:Error cv6nbaa = csv:parseStringToList(csvStringWithBooleanValues6); + test:assertEquals(cv6nbaa, [ + [(), ()] + ]); + + NillableBooleanArrayArray|csv:Error cv7nbaa = csv:parseStringToList(csvStringWithBooleanValues7); + test:assertEquals(cv7nbaa, [ + [b1, b2, (), b4] + ]); + + NillableIntOrUnionBooleanArrayArray|csv:Error cv1niubaa = csv:parseStringToList(csvStringWithBooleanValues1); + test:assertEquals(cv1niubaa, [ + [true, false, true, false], + [true, false, true, false], + [true, false, true, false] + ]); + + NillableIntOrUnionBooleanArrayArray|csv:Error cv2niubaa = csv:parseStringToList(csvStringWithBooleanValues2); + test:assertEquals(cv2niubaa, [ + [true, false, true, false, true], + [true, false, true, false, true] + ]); + + NillableIntOrUnionBooleanArrayArray|csv:Error cv3niubaa = csv:parseStringToList(csvStringWithBooleanValues3); + test:assertEquals(cv3niubaa, [ + [true, false, true], + [true, false, ()], + [true, true, false] + ]); + + NillableIntOrUnionBooleanArrayArray|csv:Error cv4niubaa = csv:parseStringToList(csvStringWithBooleanValues4); + test:assertEquals(cv4niubaa, [ + [true, (), (), false], + [true, (), (), false] + ]); + + NillableIntOrUnionBooleanArrayArray|csv:Error cv5niubaa = csv:parseStringToList(csvStringWithBooleanValues5); + test:assertEquals(cv5niubaa, [ + [true, false, true, 2], + [true, false, true, 3] + ]); +} + +@test:Config +function testFromCsvStringWithTypeForStringAndArrayAsExpectedType2() { + NillableIntOrUnionBooleanArrayArray|csv:Error cv6niubaa = csv:parseStringToList(csvStringWithBooleanValues6); + test:assertEquals(cv6niubaa, [ + [(), ()] + ]); + + NillableIntOrUnionBooleanArrayArray|csv:Error cv7niubaa = csv:parseStringToList(csvStringWithBooleanValues7); + test:assertEquals(cv7niubaa, [ + [b1, b2, (), b4] + ]); + + StringArray1Array|csv:Error cv1saa = csv:parseStringToList(csvStringWithBooleanValues1); + test:assertEquals(cv1saa, [ + ["true", "false", "true", "false"], + ["true", "false", "true", "false"], + ["true", "false", "true", "false"] + ]); + + StringArray1Array|csv:Error cv2saa = csv:parseStringToList(csvStringWithBooleanValues2); + test:assertEquals(cv2saa, [ + ["true", "false", "true", "false", "true"], + ["true", "false", "true", "false", "true"] + ]); + + StringArray1Array|csv:Error cv3saa = csv:parseStringToList(csvStringWithBooleanValues3); + test:assertEquals(cv3saa, [ + ["true", "false", "true"], + ["TRUE", "FALSE", "()"], + ["true", "true", "FALSE"] + ]); + + StringArray1Array|csv:Error cv4saa = csv:parseStringToList(csvStringWithBooleanValues4); + test:assertEquals(cv4saa, [ + ["true", "()", "()", "false"], + ["true", "()", "null", "false"] + ]); + + StringArray1Array|csv:Error cv5saa = csv:parseStringToList(csvStringWithBooleanValues5); + test:assertEquals(cv5saa, [ + ["true", "false", "true", "2"], + ["true", "false", "true", "3"] + ]); + + StringArray1Array|csv:Error cv6saa = csv:parseStringToList(csvStringWithBooleanValues6); + test:assertEquals(cv6saa, [ + ["()", "()"] + ]); + + StringArray1Array|csv:Error cv7saa = csv:parseStringToList(csvStringWithBooleanValues7); + test:assertEquals(cv7saa, [ + ["true", "false", "()", "false"] + ]); + + StringArray2Array|csv:Error cv1s2aa = csv:parseStringToList(csvStringWithBooleanValues1); + test:assertEquals(cv1s2aa, [ + ["true", "false"], + ["true", "false"], + ["true", "false"] + ]); + + StringArray2Array|csv:Error cv2s2aa = csv:parseStringToList(csvStringWithBooleanValues2); + test:assertEquals(cv2s2aa, [ + ["true", "false"], + ["true", "false"] + ]); + + StringArray2Array|csv:Error cv3s2aa = csv:parseStringToList(csvStringWithBooleanValues3); + test:assertEquals(cv3s2aa, [ + ["true", "false"], + ["TRUE", "FALSE"], + ["true", "true"] + ]); + + StringArray2Array|csv:Error cv4s2aa = csv:parseStringToList(csvStringWithBooleanValues4); + test:assertEquals(cv4s2aa, [ + ["true", "()"], + ["true", "()"] + ]); + + StringArray2Array|csv:Error cv5s2aa = csv:parseStringToList(csvStringWithBooleanValues5); + test:assertEquals(cv5s2aa, [ + ["true", "false"], + ["true", "false"] + ]); + + StringArray2Array|csv:Error cv6s2aa = csv:parseStringToList(csvStringWithBooleanValues6); + test:assertEquals(cv6s2aa, [ + ["()", "()"] + ]); + + StringArray2Array|csv:Error cv7s2aa = csv:parseStringToList(csvStringWithBooleanValues7); + test:assertEquals(cv7s2aa, [ + ["true", "false"] + ]); + + JsonArray1Array|csv:Error cv1jaa = csv:parseStringToList(csvStringWithBooleanValues1); + test:assertEquals(cv1jaa, [ + [true, false, true, false], + [true, false, true, false], + [true, false, true, false] + ]); +} + +@test:Config +function testFromCsvStringWithTypeForStringAndArrayAsExpectedType3() { + JsonArray1Array|csv:Error cv2jaa = csv:parseStringToList(csvStringWithBooleanValues2); + test:assertEquals(cv2jaa, [ + [true, false, true, false, true], + [true, false, true, false, true] + ]); + + JsonArray1Array|csv:Error cv3jaa = csv:parseStringToList(csvStringWithBooleanValues3); + test:assertEquals(cv3jaa, [ + [true, false, true], + [true, false, ()], + [true, true, false] + ]); + + JsonArray1Array|csv:Error cv4jaa = csv:parseStringToList(csvStringWithBooleanValues4); + test:assertEquals(cv4jaa, [ + [true, (), (), false], + [true, (), (), false] + ]); + + JsonArray1Array|csv:Error cv5jaa = csv:parseStringToList(csvStringWithBooleanValues5); + test:assertEquals(cv5jaa, [ + [true, false, true, 2], + [true, false, true, 3] + ]); + + JsonArray1Array|csv:Error cv6jaa = csv:parseStringToList(csvStringWithBooleanValues6); + test:assertEquals(cv6jaa, [ + [(), ()] + ]); + + JsonArray1Array|csv:Error cv7jaa = csv:parseStringToList(csvStringWithBooleanValues7); + test:assertEquals(cv7jaa, [ + [b1, b2, (), b4] + ]); + + AnydataArray1Array|csv:Error cv1anydaa = csv:parseStringToList(csvStringWithBooleanValues1); + test:assertEquals(cv1anydaa, [ + [true, false, true, false], + [true, false, true, false], + [true, false, true, false] + ]); + + AnydataArray1Array|csv:Error cv2anydaa = csv:parseStringToList(csvStringWithBooleanValues2); + test:assertEquals(cv2anydaa, [ + [true, false, true, false, true], + [true, false, true, false, true] + ]); + + AnydataArray1Array|csv:Error cv3anydaa = csv:parseStringToList(csvStringWithBooleanValues3); + test:assertEquals(cv3anydaa, [ + [true, false, true], + [true, false, ()], + [true, true, false] + ]); + + AnydataArray1Array|csv:Error cv4anydaa = csv:parseStringToList(csvStringWithBooleanValues4); + test:assertEquals(cv4anydaa, [ + [true, (), (), false], + [true, (), (), false] + ]); + + AnydataArray1Array|csv:Error cv5anydaa = csv:parseStringToList(csvStringWithBooleanValues5); + test:assertEquals(cv5anydaa, [ + [true, false, true, 2], + [true, false, true, 3] + ]); + + AnydataArray1Array|csv:Error cv6anydaa = csv:parseStringToList(csvStringWithBooleanValues6); + test:assertEquals(cv6anydaa, [ + [(), ()] + ]); + + AnydataArray1Array|csv:Error cv7anydaa = csv:parseStringToList(csvStringWithBooleanValues7); + test:assertEquals(cv7anydaa, [ + [b1, b2, (), b4] + ]); + + DecimalArray1Array|csv:Error cv1daa = csv:parseStringToList(csvStringWithBooleanValues1); + test:assertTrue(cv1daa is csv:Error); + test:assertEquals((cv1daa).message(), common:generateErrorMessageForInvalidCast("true", "decimal")); + + DecimalArray1Array|csv:Error cv3daa = csv:parseStringToList(csvStringWithBooleanValues3); + test:assertTrue(cv3daa is csv:Error); + test:assertEquals((cv3daa).message(), common:generateErrorMessageForInvalidCast("true", "decimal")); + + DecimalArray1Array|csv:Error cv6daa = csv:parseStringToList(csvStringWithBooleanValues6); + test:assertTrue(cv6daa is csv:Error); + test:assertEquals((cv6daa).message(), common:generateErrorMessageForInvalidCast("()", "decimal")); + + DecimalArray1Array|csv:Error cv7daa = csv:parseStringToList(csvStringWithBooleanValues7); + test:assertTrue(cv7daa is csv:Error); + test:assertEquals((cv7daa).message(), common:generateErrorMessageForInvalidCast("true", "decimal")); +} + +@test:Config +function testArrayIndexes() { + string csv = string `a, b + 1, 2 + 3, 4 + 5, 6 + 7, 8`; + + string csv2 = string `a, b + 1, 2, 3 + 3, 4, 5 + 5, 6, 7 + 7, 8, 9`; + + record {}[2]|error rec = csv:parseStringToRecord(csv); + test:assertEquals(rec, [ + {a: 1, b: 2}, + {a: 3, b: 4} + ]); + + map[2]|error rec_2 = csv:parseStringToRecord(csv); + test:assertEquals(rec_2, [ + {a: 1, b: 2}, + {a: 3, b: 4} + ]); + + record {|int a;|}[2]|error rec2 = csv:parseStringToRecord(csv, {skipLines: [2]}); + test:assertEquals(rec2, [ + {a: 1}, + {a: 5} + ]); + + record {|int a;|}[5]|error rec2_2 = csv:parseStringToRecord(csv, {skipLines: [2]}); + test:assertTrue(rec2_2 is csv:Error); + + int[][2]|error rec3 = csv:parseStringToList(csv2); + test:assertEquals(rec3, [ + [1, 2], + [3, 4], + [5, 6], + [7, 8] + ]); + + [int, int][2]|error rec3_2 = csv:parseStringToList(csv2); + test:assertEquals(rec3_2, [ + [1, 2], + [3, 4] + ]); + + [int...][2]|error rec3_3 = csv:parseStringToList(csv2); + test:assertEquals(rec3_3, [ + [1, 2, 3], + [3, 4, 5] + ]); + + int[1][2]|error rec4 = csv:parseStringToList(csv2, {skipLines: [2]}); + test:assertEquals(rec4, [ + [1, 2] + ]); + + int[2][]|error rec5 = csv:parseStringToList(csv2); + test:assertEquals(rec5, [ + [1, 2, 3], + [3, 4, 5] + ]); +} + +@test:Config +function testArrayIndexes2() { + map[] csv = [{a: 1, b: 2}, {a: 3, b: 4}, {a: 5, b: 6}, {a: 7, b: 8}]; + string[][] csv2 = [["1", "2", "3"], ["3", "4", "5"], ["5", "6", "7"], ["7", "8", "9"]]; + + record {}[2]|error rec = csv:parseRecordAsRecordType(csv); + test:assertEquals(rec, [ + {a: 1, b: 2}, + {a: 3, b: 4} + ]); + + map[2]|error rec_2 = csv:parseListAsRecordType(csv2, ["a", "b", "c"]); + test:assertEquals(rec_2, [ + {a: 1, b: 2, c: 3}, + {a: 3, b: 4, c: 5} + ]); + + record {|int a;|}[2]|error rec2 = csv:parseRecordAsRecordType(csv, {skipLines: [2]}); + test:assertEquals(rec2, [ + {a: 1}, + {a: 5} + ]); + + record {|int a;|}[5]|error rec2_2 = csv:parseRecordAsRecordType(csv, {skipLines: [2]}); + test:assertTrue(rec2_2 is csv:Error); + + int[][2]|error rec3 = csv:parseRecordAsListType(csv, ["a", "b"]); + test:assertEquals(rec3, [ + [1, 2], + [3, 4], + [5, 6], + [7, 8] + ]); + + [int, int][2]|error rec3_2 = csv:parseListAsListType(csv2); + test:assertEquals(rec3_2, [ + [1, 2], + [3, 4] + ]); + + [int...][2]|error rec3_3 = csv:parseRecordAsListType(csv, ["a", "b"], {skipLines: [1]}); + test:assertEquals(rec3_3, [ + [3, 4], + [5, 6] + ]); + + int[1][2]|error rec4 = csv:parseRecordAsListType(csv, ["a", "b"], {skipLines: [2]}); + test:assertEquals(rec4, [ + [1, 2] + ]); + + int[2][]|error rec5 = csv:parseListAsListType(csv2); + test:assertEquals(rec5, [ + [1, 2, 3], + [3, 4, 5] + ]); +} diff --git a/ballerina-tests/parse-string-array-types-tests/tests/parse_string_to_tuple_test.bal b/ballerina-tests/parse-string-array-types-tests/tests/parse_string_to_tuple_test.bal new file mode 100644 index 0000000..7cc5087 --- /dev/null +++ b/ballerina-tests/parse-string-array-types-tests/tests/parse_string_to_tuple_test.bal @@ -0,0 +1,472 @@ +import ballerina/csv_commons as common; +import ballerina/data.csv as csv; +import ballerina/test; + +@test:Config +function testFromCsvStringWithTypeForStringAndTupleAsExpectedType() { + BooleanTuple1Array|csv:Error cbv1bt1 = csv:parseStringToList(csvStringWithBooleanValues1); + test:assertEquals(cbv1bt1, [ + [true, false, true, false], + [true, false, true, false], + [true, false, true, false] + ]); + + BooleanTuple1Array|csv:Error cbv2bt1 = csv:parseStringToList(csvStringWithBooleanValues2); + test:assertEquals(cbv2bt1, [ + [true, false, true, false], + [true, false, true, false] + ]); + + BooleanTuple1Array|csv:Error cbv3bt1 = csv:parseStringToList(csvStringWithBooleanValues3); + test:assertTrue(cbv3bt1 is csv:Error); + test:assertEquals((cbv3bt1).message(), common:generateErrorMessageForInvalidCast("()", "boolean")); + + BooleanTuple1Array|csv:Error cbv5bt1 = csv:parseStringToList(csvStringWithBooleanValues5); + test:assertTrue(cbv5bt1 is csv:Error); + test:assertEquals((cbv5bt1).message(), common:generateErrorMessageForInvalidCast("2", "boolean")); + + BooleanTuple1Array|csv:Error cbv7bt1 = csv:parseStringToList(csvStringWithBooleanValues7); + test:assertTrue(cbv7bt1 is csv:Error); + test:assertEquals((cbv7bt1).message(), common:generateErrorMessageForInvalidCast("()", "boolean")); + + BooleanTuple2Array|csv:Error cbv1bt2 = csv:parseStringToList(csvStringWithBooleanValues1); + test:assertEquals(cbv1bt2, [ + [true, false], + [true, false], + [true, false] + ]); + + BooleanTuple2Array|csv:Error cbv2bt2 = csv:parseStringToList(csvStringWithBooleanValues2); + test:assertEquals(cbv2bt2, [ + [true, false], + [true, false] + ]); + + BooleanTuple2Array|csv:Error cbv3bt2 = csv:parseStringToList(csvStringWithBooleanValues3); + test:assertEquals(cbv3bt2, [ + [true, false], + [true, false], + [true, true] + ]); + + BooleanTuple2Array|csv:Error cbv4bt2 = csv:parseStringToList(csvStringWithBooleanValues4); + test:assertTrue(cbv4bt2 is csv:Error); + test:assertEquals((cbv4bt2).message(), common:generateErrorMessageForInvalidCast("()", "boolean")); + + BooleanTuple3Array|csv:Error cbv1bt3 = csv:parseStringToList(csvStringWithBooleanValues1); + test:assertEquals(cbv1bt3, [ + [true, false, true, false], + [true, false, true, false], + [true, false, true, false] + ]); + + BooleanTuple3Array|csv:Error cbv2bt3 = csv:parseStringToList(csvStringWithBooleanValues2); + test:assertEquals(cbv2bt3, [ + [true, false, true, false, true], + [true, false, true, false, true] + ]); + + BooleanTuple3Array|csv:Error cbv3bt3 = csv:parseStringToList(csvStringWithBooleanValues3); + test:assertTrue(cbv3bt3 is csv:Error); + test:assertEquals((cbv3bt3).message(), common:generateErrorMessageForInvalidCast("()", "boolean")); + + BooleanTuple3Array|csv:Error cbv5bt3 = csv:parseStringToList(csvStringWithBooleanValues5); + test:assertTrue(cbv5bt3 is csv:Error); + test:assertEquals((cbv5bt3).message(), common:generateErrorMessageForInvalidCast("2", "boolean")); + + BooleanTuple3Array|csv:Error cbv7bt3 = csv:parseStringToList(csvStringWithBooleanValues7); + test:assertTrue(cbv7bt3 is csv:Error); + test:assertEquals((cbv7bt3).message(), common:generateErrorMessageForInvalidCast("()", "boolean")); + + BooleanTuple4Array|csv:Error cbv1bt4 = csv:parseStringToList(csvStringWithBooleanValues1); + test:assertEquals(cbv1bt4, [ + [true, false, true, false], + [true, false, true, false], + [true, false, true, false] + ]); + + BooleanTuple4Array|csv:Error cbv2bt4 = csv:parseStringToList(csvStringWithBooleanValues2); + test:assertEquals(cbv2bt4, [ + [true, false, true, false, true], + [true, false, true, false, true] + ]); + + BooleanTuple4Array|csv:Error cbv3bt4 = csv:parseStringToList(csvStringWithBooleanValues3); + test:assertTrue(cbv3bt4 is csv:Error); + test:assertEquals((cbv3bt4).message(), common:generateErrorMessageForInvalidCast("()", "boolean")); + + BooleanTuple4Array|csv:Error cbv4bt4 = csv:parseStringToList(csvStringWithBooleanValues4); + test:assertTrue(cbv4bt4 is csv:Error); + test:assertEquals((cbv4bt4).message(), common:generateErrorMessageForInvalidCast("()", "boolean")); + + BooleanTuple4Array|csv:Error cbv5bt4 = csv:parseStringToList(csvStringWithBooleanValues5); + test:assertTrue(cbv5bt4 is csv:Error); + test:assertEquals((cbv5bt4).message(), common:generateErrorMessageForInvalidCast("2", "boolean")); + + BooleanTuple4Array|csv:Error cbv6bt4 = csv:parseStringToList(csvStringWithBooleanValues6); + test:assertTrue(cbv6bt4 is csv:Error); + test:assertEquals((cbv6bt4).message(), common:generateErrorMessageForInvalidCast("()", "boolean")); + +} + +@test:Config +function testFromCsvStringWithTypeForStringAndTupleAsExpectedType2() { + BooleanTuple4Array|csv:Error cbv7bt4 = csv:parseStringToList(csvStringWithBooleanValues7); + test:assertTrue(cbv7bt4 is csv:Error); + test:assertEquals((cbv7bt4).message(), common:generateErrorMessageForInvalidCast("()", "boolean")); + + NillableBooleanTuple5Array|csv:Error cbv1bt5 = csv:parseStringToList(csvStringWithBooleanValues1); + test:assertEquals(cbv1bt5, [ + [true, false, true, false, null], + [true, false, true, false, null], + [true, false, true, false, null] + ]); + + NillableBooleanTuple5Array|csv:Error cbv2bt5 = csv:parseStringToList(csvStringWithBooleanValues2); + test:assertEquals(cbv2bt5, [ + [true, false, true, false, true], + [true, false, true, false, true] + ]); + + NillableBooleanTuple5Array|csv:Error cbv3bt5 = csv:parseStringToList(csvStringWithBooleanValues3); + test:assertEquals(cbv3bt5, [ + [true, false, true, null, null], + [true, false, (), null, null], + [true, true, false, null, null] + ]); + + NillableBooleanTuple5Array|csv:Error cbv4bt5 = csv:parseStringToList(csvStringWithBooleanValues4); + test:assertEquals(cbv4bt5, [ + [true, (), (), false, null], + [true, (), (), false, null] + ]); + + NillableBooleanTuple5Array|csv:Error cbv5bt5 = csv:parseStringToList(csvStringWithBooleanValues5); + test:assertTrue(cbv5bt5 is csv:Error); + test:assertEquals((cbv5bt5).message(), common:generateErrorMessageForInvalidCast("2", "boolean?")); + + NillableBooleanTuple5Array|csv:Error cbv6bt5 = csv:parseStringToList(csvStringWithBooleanValues6); + test:assertEquals(cbv6bt5, [ + [(), (), null, null, null] + ]); + + NillableBooleanTuple5Array|csv:Error cbv7bt5 = csv:parseStringToList(csvStringWithBooleanValues7); + test:assertEquals(cbv7bt5, [ + [b1, b2, (), b4, null] + ]); + + NillableBooleanTuple6Array|csv:Error cbv1bt6 = csv:parseStringToList(csvStringWithBooleanValues1); + test:assertEquals(cbv1bt6, [ + [true, false], + [true, false], + [true, false] + ]); + + NillableBooleanTuple6Array|csv:Error cbv2bt6 = csv:parseStringToList(csvStringWithBooleanValues2); + test:assertEquals(cbv2bt6, [ + [true, false], + [true, false] + ]); + + NillableBooleanTuple6Array|csv:Error cbv3bt6 = csv:parseStringToList(csvStringWithBooleanValues3); + test:assertEquals(cbv3bt6, [ + [true, false], + [true, false], + [true, true] + ]); + + NillableBooleanTuple6Array|csv:Error cbv4bt6 = csv:parseStringToList(csvStringWithBooleanValues4); + test:assertEquals(cbv4bt6, [ + [true, ()], + [true, ()] + ]); + + NillableBooleanTuple6Array|csv:Error cbv6bt6 = csv:parseStringToList(csvStringWithBooleanValues6); + test:assertEquals(cbv6bt6, [ + [(), null] + ]); + + NillableBooleanTuple6Array|csv:Error cbv7bt6 = csv:parseStringToList(csvStringWithBooleanValues7); + test:assertEquals(cbv7bt6, [ + [b1, b2] + ]); + + NillableBooleanTuple7Array|csv:Error cbv1bt7 = csv:parseStringToList(csvStringWithBooleanValues1); + test:assertEquals(cbv1bt7, [ + [true, false, true, false], + [true, false, true, false], + [true, false, true, false] + ]); + + NillableBooleanTuple7Array|csv:Error cbv2bt7 = csv:parseStringToList(csvStringWithBooleanValues2); + test:assertEquals(cbv2bt7, [ + [true, false, true, false, true], + [true, false, true, false, true] + ]); + + NillableBooleanTuple7Array|csv:Error cbv3bt7 = csv:parseStringToList(csvStringWithBooleanValues3); + test:assertEquals(cbv3bt7, [ + [true, false, true], + [true, false, ()], + [true, true, false] + ]); + + NillableBooleanTuple7Array|csv:Error cbv4bt7 = csv:parseStringToList(csvStringWithBooleanValues4); + test:assertEquals(cbv4bt7, [ + [true, (), (), false], + [true, (), (), false] + ]); + +} +@test:Config +function testFromCsvStringWithTypeForStringAndTupleAsExpectedType3() { + NillableBooleanTuple7Array|csv:Error cbv5bt7 = csv:parseStringToList(csvStringWithBooleanValues5); + test:assertTrue(cbv5bt7 is csv:Error); + test:assertEquals((cbv5bt7).message(), common:generateErrorMessageForInvalidCast("2", "boolean?")); + + NillableBooleanTuple7Array|csv:Error cbv6bt7 = csv:parseStringToList(csvStringWithBooleanValues6); + test:assertEquals(cbv6bt7, [ + [(), ()] + ]); + + NillableBooleanTuple7Array|csv:Error cbv7bt7 = csv:parseStringToList(csvStringWithBooleanValues7); + test:assertEquals(cbv7bt7, [ + [b1, b2, (), false] + ]); + + NillableBooleanTuple8Array|csv:Error cbv1bt8 = csv:parseStringToList(csvStringWithBooleanValues1); + test:assertEquals(cbv1bt8, [ + [true, false, true, false], + [true, false, true, false], + [true, false, true, false] + ]); + + NillableBooleanTuple8Array|csv:Error cbv2bt8 = csv:parseStringToList(csvStringWithBooleanValues2); + test:assertEquals(cbv2bt8, [ + [true, false, true, false, true], + [true, false, true, false, true] + ]); + + NillableBooleanTuple8Array|csv:Error cbv3bt8 = csv:parseStringToList(csvStringWithBooleanValues3); + test:assertEquals(cbv3bt8, [ + [true, false, true], + [true, false, ()], + [true, true, false] + ]); + + NillableBooleanTuple8Array|csv:Error cbv4bt8 = csv:parseStringToList(csvStringWithBooleanValues4); + test:assertEquals(cbv4bt8, [ + [true, (), (), false], + [true, (), (), false] + ]); + + NillableBooleanTuple8Array|csv:Error cbv5bt8 = csv:parseStringToList(csvStringWithBooleanValues5); + test:assertTrue(cbv5bt8 is csv:Error); + test:assertEquals((cbv5bt8).message(), common:generateErrorMessageForInvalidCast("2", "boolean?")); + + NillableBooleanTuple8Array|csv:Error cbv6bt8 = csv:parseStringToList(csvStringWithBooleanValues6); + test:assertEquals(cbv6bt8, [ + [(), ()] + ]); + + NillableBooleanTuple8Array|csv:Error cbv7bt8 = csv:parseStringToList(csvStringWithBooleanValues7); + test:assertEquals(cbv7bt8, [ + [b1, b2, (), false] + ]); + + NillableIntBooleanTuple9Array|csv:Error cbv1bt9 = csv:parseStringToList(csvStringWithBooleanValues1); + test:assertEquals(cbv1bt9, [ + [true, false, true, false], + [true, false, true, false], + [true, false, true, false] + ]); + + NillableIntBooleanTuple9Array|csv:Error cbv2bt9 = csv:parseStringToList(csvStringWithBooleanValues2); + test:assertEquals(cbv2bt9, [ + [true, false, true, false, true], + [true, false, true, false, true] + ]); + + NillableIntBooleanTuple9Array|csv:Error cbv3bt9 = csv:parseStringToList(csvStringWithBooleanValues3); + test:assertEquals(cbv3bt9, [ + [true, false, true], + [true, false, ()], + [true, true, false] + ]); + + NillableIntBooleanTuple9Array|csv:Error cbv4bt9 = csv:parseStringToList(csvStringWithBooleanValues4); + test:assertEquals(cbv4bt9, [ + [true, (), (), false], + [true, (), (), false] + ]); + + NillableIntBooleanTuple9Array|csv:Error cbv5bt9 = csv:parseStringToList(csvStringWithBooleanValues5); + test:assertEquals(cbv5bt9, [ + [true, false, true, 2], + [true, false, true, 3] + ]); + + NillableIntBooleanTuple9Array|csv:Error cbv6bt9 = csv:parseStringToList(csvStringWithBooleanValues6); + test:assertEquals(cbv6bt9, [ + [(), ()] + ]); + + NillableIntBooleanTuple9Array|csv:Error cbv7bt9 = csv:parseStringToList(csvStringWithBooleanValues7); + test:assertEquals(cbv7bt9, [ + [b1, b2, (), false] + ]); + + NilTuple3Array|csv:Error cbv1nt3 = csv:parseStringToList(csvStringWithBooleanValues1); + test:assertTrue(cbv1nt3 is csv:Error); + test:assertEquals((cbv1nt3).message(), common:generateErrorMessageForInvalidCast("true", "()")); + + NilTuple3Array|csv:Error cbv3nt3 = csv:parseStringToList(csvStringWithBooleanValues3); + test:assertTrue(cbv3nt3 is csv:Error); + test:assertEquals((cbv3nt3).message(), common:generateErrorMessageForInvalidCast("true", "()")); + + NilTuple3Array|csv:Error cbv6nt3 = csv:parseStringToList(csvStringWithBooleanValues6); + test:assertEquals(cbv6nt3, [ + [(), ()] + ]); + + AnydataTuple3Array|csv:Error cbv1anyd3 = csv:parseStringToList(csvStringWithBooleanValues1); + test:assertEquals(cbv1anyd3, [ + [true, false, true, false], + [true, false, true, false], + [true, false, true, false] + ]); + + AnydataTuple3Array|csv:Error cbv2anyd3 = csv:parseStringToList(csvStringWithBooleanValues2); + test:assertEquals(cbv2anyd3, [ + [true, false, true, false, true], + [true, false, true, false, true] + ]); + + AnydataTuple3Array|csv:Error cbv3anyd3 = csv:parseStringToList(csvStringWithBooleanValues3); + test:assertEquals(cbv3anyd3, [ + [true, false, true], + [true, false, ()], + [true, true, false] + ]); + + AnydataTuple3Array|csv:Error cbv4anyd3 = csv:parseStringToList(csvStringWithBooleanValues4); + test:assertEquals(cbv4anyd3, [ + [true, (), (), false], + [true, (), (), false] + ]); + + AnydataTuple3Array|csv:Error cbv5anyd3 = csv:parseStringToList(csvStringWithBooleanValues5); + test:assertEquals(cbv5anyd3, [ + [true, false, true, 2], + [true, false, true, 3] + ]); + + AnydataTuple3Array|csv:Error cbv6anyd3 = csv:parseStringToList(csvStringWithBooleanValues6); + test:assertEquals(cbv6anyd3, [ + [(), ()] + ]); + + AnydataTuple3Array|csv:Error cbv7anyd3 = csv:parseStringToList(csvStringWithBooleanValues7); + test:assertEquals(cbv7anyd3, [ + [b1, b2, (), false] + ]); +} + +@test:Config +function testFromCsvStringWithTypeForStringAndTupleAsExpectedType4() { + JsonTuple3Array|csv:Error cbv1j3 = csv:parseStringToList(csvStringWithBooleanValues1); + test:assertEquals(cbv1j3, [ + [true, false, true, false], + [true, false, true, false], + [true, false, true, false] + ]); + + JsonTuple3Array|csv:Error cbv2j3 = csv:parseStringToList(csvStringWithBooleanValues2); + test:assertEquals(cbv2j3, [ + [true, false, true, false, true], + [true, false, true, false, true] + ]); + + JsonTuple3Array|csv:Error cbv3j3 = csv:parseStringToList(csvStringWithBooleanValues3); + test:assertEquals(cbv3j3, [ + [true, false, true], + [true, false, ()], + [true, true, false] + ]); + + JsonTuple3Array|csv:Error cbv4j3 = csv:parseStringToList(csvStringWithBooleanValues4); + test:assertEquals(cbv4j3, [ + [true, (), (), false], + [true, (), (), false] + ]); + + JsonTuple3Array|csv:Error cbv5j3 = csv:parseStringToList(csvStringWithBooleanValues5); + test:assertEquals(cbv5j3, [ + [true, false, true, 2], + [true, false, true, 3] + ]); + + JsonTuple3Array|csv:Error cbv6j3 = csv:parseStringToList(csvStringWithBooleanValues6); + test:assertEquals(cbv6j3, [ + [(), ()] + ]); + + JsonTuple3Array|csv:Error cbv7j3 = csv:parseStringToList(csvStringWithBooleanValues7); + test:assertEquals(cbv7j3, [ + [b1, b2, (), false] + ]); + + StringTuple3Array|csv:Error cbv1s3 = csv:parseStringToList(csvStringWithBooleanValues1); + test:assertEquals(cbv1s3, [ + ["true", "false", "true", "false"], + ["true", "false", "true", "false"], + ["true", "false", "true", "false"] + ]); + + StringTuple3Array|csv:Error cbv2s3 = csv:parseStringToList(csvStringWithBooleanValues2); + test:assertEquals(cbv2s3, [ + ["true", "false", "true", "false", "true"], + ["true", "false", "true", "false", "true"] + ]); + + StringTuple3Array|csv:Error cbv3s3 = csv:parseStringToList(csvStringWithBooleanValues3); + test:assertEquals(cbv3s3, [ + ["true", "false", "true"], + ["TRUE", "FALSE", "()"], + ["true", "true", "FALSE"] + ]); + + StringTuple3Array|csv:Error cbv4s3 = csv:parseStringToList(csvStringWithBooleanValues4); + test:assertEquals(cbv4s3, [ + ["true", "()", "()", "false"], + ["true", "()", "null", "false"] + ]); + + StringTuple3Array|csv:Error cbv5s3 = csv:parseStringToList(csvStringWithBooleanValues5); + test:assertEquals(cbv5s3, [ + ["true", "false", "true", "2"], + ["true", "false", "true", "3"] + ]); + + StringTuple3Array|csv:Error cbv6s3 = csv:parseStringToList(csvStringWithBooleanValues6); + test:assertEquals(cbv6s3, [ + ["()", "()"] + ]); + + StringTuple3Array|csv:Error cbv7s3 = csv:parseStringToList(csvStringWithBooleanValues7); + test:assertEquals(cbv7s3, [ + ["true", "false", "()", "false"] + ]); + + DecimalTuple3Array|csv:Error cbv1dt3 = csv:parseStringToList(csvStringWithBooleanValues1); + test:assertTrue(cbv1dt3 is csv:Error); + test:assertEquals((cbv1dt3).message(), common:generateErrorMessageForInvalidCast("true", "decimal")); + + DecimalTuple3Array|csv:Error cbv3dt3 = csv:parseStringToList(csvStringWithBooleanValues3); + test:assertTrue(cbv3dt3 is csv:Error); + test:assertEquals((cbv3dt3).message(), common:generateErrorMessageForInvalidCast("true", "decimal")); + + DecimalTuple3Array|csv:Error cbv6dt3 = csv:parseStringToList(csvStringWithBooleanValues6); + test:assertTrue(cbv6dt3 is csv:Error); + test:assertEquals((cbv6dt3).message(), common:generateErrorMessageForInvalidCast("()", "decimal")); +} diff --git a/ballerina-tests/parse-string-array-types-tests/tests/test_data_values.bal b/ballerina-tests/parse-string-array-types-tests/tests/test_data_values.bal new file mode 100644 index 0000000..360a493 --- /dev/null +++ b/ballerina-tests/parse-string-array-types-tests/tests/test_data_values.bal @@ -0,0 +1,256 @@ +boolean b1 = true; +false b2 = false; +boolean? b3 = (); +boolean|int b4 = false; + +() n1 = (); +int? n2 = (); +() n3 = null; + +int i1 = 1; +int i2 = -2; +int i3 = int:MAX_VALUE; +int i4 = int:MIN_VALUE; +int i5 = 0; +2 i6 = 2; +int? i7 = (); +int|string i8 = 100; + +float f1 = 2.234; +float f2 = -3.21f; +float f3 = 0; +float f4 = float:Infinity; +float f5 = -float:Infinity; +float f6 = float:NaN; +2.3f f7 = 2.3; +float? f8 = (); +float|decimal f9 = 1.21; + +decimal d1 = 2.234; +decimal d2 = -3.21d; +decimal d3 = 0; +2.3d d4 = 2.3; +decimal? d5 = (); +decimal|int d6 = 1.21; + +string s1 = "string"; +string s2 = ""; +string:Char s3 = "a"; + +map bm1 = {b1, b2}; +map bm2 = {b1, b2, b3, n1, n3}; +map bm3 = {b1, b2, b3, b4, i1}; +map<()> bm4 = {n1, n3}; +map bm5 = {b1, b2, b3, b4:true}; + +map m5 = {i1, i2, i3, i4, i5, i6}; +map m6 = {f1, f2, f3, f4, f5, f6, f7}; +map m7 = {d1, d2, d3, d4}; +map m8 = {d1, f1, f9, f10: 1.23}; +map m9 = {s1, s2, s3}; +map m10 = {b1, b2, b3, b4, n1, n2, n3, i1, i2, i3, i4, i5, i6, i7, i8, f1, f2, f3, f4, f5, f6, f7, f8}; +map m11 = {b1, b2, b3, b4, n1, n2, n3, i1, i2, i3, i4, i5, i6, i7, i8, f1, f2, f3, f4, f5, f6, f7, f8}; + +boolean[] arr1 = [b1, b2]; +boolean?[] arr2 = [b1, b2, b3, n1, n3]; +(boolean|int?)[] arr3 = [b1, b2, b3, b4, i1]; +()[] arr4 = [n1, n3]; +int[] arr5 = [i1, i2, i3, i4, i5, i6]; +float[] arr6 = [f1, f2, f3, f4, f5, f6, f7]; +decimal[] arr7 = [d1, d2, d3, d4]; +(decimal|float)[] arr8 = [d1, f1, f9, 1.23]; +string[] arr9 = [s1, s2, s3]; +anydata[] arr10 = [b1, b2, b3, b4, n1, n2, n3, i1, i2, i3, i4, i5, i6, i7, i8, f1, f2, f3, f4, f5, f6, f7, f8]; +json[] arr11 = [b1, b2, b3, b4, n1, n2, n3, i1, i2, i3, i4, i5, i6, i7, i8, f1, f2, f3, f4, f5, f6, f7, f8]; + +[boolean, boolean] bt1 = [b1, b2]; +[boolean, boolean, boolean, boolean] bt2 = [b1, b2, b1, b2]; +[boolean?, boolean?, boolean?, boolean?, boolean?] bt3 = [b1, b2, b3, n1, n3]; +[boolean|int?, boolean|int?, boolean|int?, boolean|int?, boolean|int?] bt4 = [b1, b2, b3, b4, i1]; +[boolean...] bt5 = [b1, b2]; + +[string, string] st1 = [s1, s2]; +[string, string, string, string] st2 = [s1, s2, s3, s2]; +[string...] st3 = [s1, s2]; +[string, string, string...] st4 = [s1, s2, s3, s2]; + +[string?, string?, string?, string?, string?] st5 = [s1, s2, s3, n1, n3]; +[string|int?, string|int?, string|int?, string|int?, string|int?] st6 = [s1, s2, s3, n1, i1]; +[string?...] st7 = [s1, s2]; +[string...] st8 = []; +[string, string, string] st9 = [s1, s2, s3]; + +[(), ()] tup4 = [n1, n3]; +[int, int, int, int, int, int] tup5 = [i1, i2, i3, i4, i5, i6]; +[float, float, float, float, float, float, float] tup6 = [f1, f2, f3, f4, f5, f6, f7]; +[decimal, decimal, decimal, decimal] tup7 = [d1, d2, d3, d4]; +[decimal|float, decimal|float, decimal|float, decimal|float] tup8 = [d1, f1, f9, 1.23]; +[string, string, string] tup9 = [s1, s2, s3]; +[anydata, anydata, anydata, anydata, anydata, anydata, anydata, anydata, + anydata, anydata, anydata, anydata, anydata, anydata, anydata, anydata, + anydata, anydata, anydata, anydata, anydata, anydata, anydata] tup10 = [b1, b2, b3, b4, + n1, n2, n3, i1, i2, i3, i4, i5, i6, i7, i8, f1, f2, f3, f4, f5, f6, f7, f8]; +[json, json, json, json, json, json, json, json, json, json, json, json, + json, json, json, json, json, json, json, json, json, json, json] tup11 = + [b1, b2, b3, b4, n1, n2, n3, i1, i2, i3, i4, i5, i6, i7, i8, f1, + f2, f3, f4, f5, f6, f7, f8]; +[string, string, int, int, boolean, boolean, (), (), decimal, decimal, float, float] tup12 = [ + s1, s2, i1, i2, b1, b2, n1, n3, d1, d2, f1, f2 +]; + +[boolean, boolean...] restTup1 = [b1, b2]; +[boolean?, boolean?, boolean?...] restTup2 = [b1, b2, b3, n1, n3]; +[boolean|int?...] restTup3 = [b1, b2, b3, b4, i1]; +[(), ()...] restTup4 = [n1, n3]; +[int...] restTup5 = [i1, i2, i3, i4, i5, i6]; +[float...] restTup6 = [f1, f2, f3, f4, f5, f6, f7]; +[decimal...] restTup7 = [d1, d2, d3, d4]; +[decimal|float, decimal|float...] restTup8 = [d1, f1, f9, 1.23]; +[string...] restTup9 = [s1, s2, s3]; +[anydata...] restTup10 = [b1, b2, b3, b4, n1, n2, n3, i1, i2, i3, i4, i5, i6, i7, i8, f1, f2, f3, f4, f5, f6, f7, f8]; +[json, json, json...] restTup11 = [b1, b2, b3, b4, n1, n2, n3, i1, i2, i3, i4, i5, i6, i7, i8, f1, f2, f3, f4, f5, f6, f7, f8]; +[string, string, int, int, boolean, boolean, (), (), decimal, decimal, float, float...] restTup12 = [ + s1, s2, i1, i2, b1, b2, n1, n3, d1, d2, f1, f2, f2, f2 +]; + +var booleanRecordArray = [ + {b1, b2, b3, b4}, {b1, b2, b3, b4} +]; + +var booleanRecordArray2 = [ + {},{} +]; + +string csvStringWithBooleanValues1 = string `b1,b2,b3,b4 +true,false,true,false +true,false, true,false +true,false,true,false +`; + +string csvStringWithBooleanValues2 = string `b1,b2,b3,b4,b5 +true,false, true,false,true +true,false, true,false,true`; + +string csvStringWithBooleanValues3 = string `b1,b2,b3 +${" "}${"\t"} +true, false,true +${" "} + TRUE, FALSE,() +${" "} + +true, true,FALSE + +`; + +string csvStringWithBooleanValues4 = string `b1,b2,b3,b4 + true,(), (),false + true,(), null,false + +`; + +string csvStringWithBooleanValues5 = string `b1,b2,b3,b4 + +true,false,true,2 + +true,false,true,3 +`; + +string csvStringWithBooleanValues6 = string `b2,b3 +(),() + +`; + +string csvStringWithBooleanValues7 = string `b1,b2,b3,b4 +${b1},${b2},(),${b4} +`; + +string csvStringData1 = string ` + a, b, c, d, e, f + 1, string1, true, 2.234, 2.234, () + 2, string2, false, 0, 0, null + 3, string3, false, 1.23, 1.23, () + 4, string4, true, -6.51, -6.51, () + 5, string5, true, 3, 3, ()`; + +string csvStringData2 = string ` + hello, hello, (), 12, true, 12.34 + // comment + + a, b, c, d, e, f + + + 1, string1, true, 2.234, 2.234, () + 2, string2, false, 0, 0, null + 3, string3, false, 1.23, 1.23, () + 4, string4, true, -6.51, -6.51, () + 5, string5, true, 3, 3, ()`; + +string csvStringData3 = string ` + a, b, c, d, e, f + + + + 1, string1, true, 2.234, 2.234, () + 2, string2, false, 0, 0, null + 3, string3, false, 1.23, 1.23, () + + 4, string4, true, -6.51, -6.51, () + 5, string5, true, 3, 3, ()`; + +string csvStringData4 = string ` + 1, string1, true, 2.234, 2.234, () + 2, string2, false, 0, 0, null + 3, string3, false, 1.23, 1.23, () + 4, string4, true, -6.51, -6.51, () + 5, string5, true, 3, 3, ()`; + +string csvStringData5 = string ` + + + + 1, string1, true, 2.234, 2.234, () + 2, string2, false, 0, 0, null + + 3, string3, false, 1.23, 1.23, () + 4, string4, true, -6.51, -6.51, () + + 5, string5, true, 3, 3, ()`; + +string csvStringData6 = string ` + + 1, string1, true, 2.234, 2.234, () + 2, string2, false, 0, 0, null + + 3, string3, false, 1.23, 1.23, () + 4, string4, true, -6.51, -6.51, () + + 5, string5, true, 3, 3, ()`; + +string csvStringData7 = string ` + a@ b@ c@ d@ e@ f + 1@ string@ true@ 2.234@ -3.21@ () + 2@ s,tring@ true@ 2.234@ -3.21@ null + 3@ stri,ng@ true@ 2.234@ -3.21@ () + 4@ string@ true@ 2.234@ -3.21@ () + 5@ string@ true@ 2.234@ -3.21@ ()`; +string csvStringData8 = string ` + a@ b@ c@ d@ e@ f + + + + 1@ stri,ng@ true@ 2.234@ -3.21@ () + 2@ string@ true@ 2.234@ ()@-3.21 + 3@ string@ true@ 2.234@ -3.21@ null + + 4@ s,tring@ true@ 2.234@ -3.21@ () + 5@ string@ true@ 2.234@ -3.21@ ()`; + +string csvStringData9 = string ` + + 1@ string@ true@ 2.234@ -3.21@ () + 2@ string@ true@ 2.234@ -3.21@ null + + 3@ string@ true@ 2.234@ -3.21@ () + 4@ string@ true@ 2.234@ ()@-3.21 + + 5@ string@ true@ 2.234@ -3.21@ null`; diff --git a/ballerina-tests/parse-string-array-types-tests/tests/types.bal b/ballerina-tests/parse-string-array-types-tests/tests/types.bal new file mode 100644 index 0000000..a2b4b2b --- /dev/null +++ b/ballerina-tests/parse-string-array-types-tests/tests/types.bal @@ -0,0 +1,2534 @@ +type BooleanRecord1 record { + boolean b1; + boolean|string b2; + boolean|string? b3; + boolean b4; +}; + +type BooleanRecord2 record {| + boolean b1; + boolean|string b2; + boolean|string? b3; + boolean b4; +|}; + +type BooleanRecord3 record {| + boolean b1; + boolean? b3; +|}; + +type BooleanRecord4 record { + boolean b1; + boolean? b3; +}; + +type BooleanRecord5 record { + boolean b1; + boolean? b3; + string defaultableField = ""; + string? nillableField = (); +}; + +type BooleanRecord6 record {| + boolean b1; + boolean? b3; + string defaultableField = ""; + string? nillableField = (); +|}; + +type BooleanRecord7 record { + boolean b1; + boolean? b3; + string defaultableField = ""; + string? nillableField = (); + string requiredField; +}; + +type BooleanRecord8 record {| + boolean b1; + boolean? b3; + string defaultableField = ""; + string? nillableField = (); + string requiredField; +|}; + +type BooleanRecord9 record {| + boolean b1; + boolean? b3; + boolean?...; +|}; + +type BooleanRecord10 record {| + boolean...; +|}; + +type BooleanRecord11 record {| + boolean b1; + string defaultableField = ""; + string? nillableField = (); + boolean?|string...; +|}; + +type BooleanRecord12 record {| + boolean b1; + string defaultableField = ""; + string? nillableField = (); + string requiredField; + boolean...; +|}; + +type BooleanRecord13 record {| + string defaultableField = ""; + string? nillableField = (); + string|boolean...; +|}; + +type BooleanRecord14 record {| + string defaultableField = ""; + string? nillableField = (); + string requiredField; + boolean...; +|}; + +type BooleanRecord15 record {| + int b1; + string defaultableField = ""; + string? nillableField = (); + boolean?...; +|}; + +type BooleanRecord16 record {| + boolean?...; +|}; + +type BooleanRecord17 record {| + int...; +|}; + +type BooleanRecord18 record {| + boolean b2; + int?...; +|}; + +type NilRecord1 record { + () n1; + () n2; + () n3; +}; + +type NilRecord2 record {| + () n1; + () n2; + () n3; +|}; + +type NilRecord3 record {| + () n1; + () n4; +|}; + +type NilRecord4 record { + () n1; + () n4; +}; + +type NilRecord5 record { + () n1; + () n4; + string defaultableField = ""; + string? nillableField = (); +}; + +type NilRecord6 record {| + () n1; + () n4; + string defaultableField = ""; + string? nillableField = (); +|}; + +type NilRecord7 record { + () n1; + () n4; + string defaultableField = ""; + string? nillableField = (); + string requiredField; +}; + +type NilRecord8 record {| + () n1; + () n4; + string defaultableField = ""; + string? nillableField = (); + string requiredField; +|}; + +type NilRecord9 record {| + () n1; + () n2; + ()...; +|}; + +type NilRecord10 record {| + ()...; +|}; + +type NilRecord11 record {| + () n1; + string defaultableField = ""; + string? nillableField = (); + ()...; +|}; + +type NilRecord12 record {| + () n1; + string defaultableField = ""; + string? nillableField = (); + string requiredField; + ()...; +|}; + +type NilRecord13 record {| + string defaultableField = ""; + string? nillableField = (); + ()...; +|}; + +type NilRecord14 record {| + string defaultableField = ""; + string? nillableField = (); + string requiredField; + ()...; +|}; + +type IntegerRecord1 record { + int i1; + int i2; + int i3; + int? i4; + int? i5; + int i6; + int i7; + int? i8; +}; + +type IntegerRecord2 record {| + int i1; + int? i2; + int i3; + int i4; + int? i5; + int i6; + int i7; + int? i8; +|}; + +type IntegerRecord3 record {| + int i1; + int i4; + int i6; +|}; + +type IntegerRecord4 record { + int i1; + int i4; + int i6; +}; + +type IntegerRecord5 record { + int i1; + int i4; + int i6; + string defaultableField = ""; + string? nillableField = (); +}; + +type IntegerRecord6 record {| + int i1; + int i4; + int i6; + string defaultableField = ""; + string? nillableField = (); +|}; + +type IntegerRecord7 record { + int i1; + int i4; + int i6; + string defaultableField = ""; + string? nillableField = (); + string requiredField; +}; + +type IntegerRecord8 record {| + int i1; + int i4; + int i6; + string defaultableField = ""; + string? nillableField = (); + string requiredField; +|}; + +type IntegerRecord9 record {| + int i1; + int i2; + int...; +|}; + +type IntegerRecord10 record {| + int...; +|}; + +type IntegerRecord11 record {| + int i1; + string defaultableField = ""; + string? nillableField = (); + int...; +|}; + +type IntegerRecord12 record {| + int i1; + string defaultableField = ""; + string? nillableField = (); + string requiredField; + int...; +|}; + +type IntegerRecord13 record {| + string defaultableField = ""; + string? nillableField = (); + int...; +|}; + +type IntegerRecord14 record {| + string defaultableField = ""; + string? nillableField = (); + string requiredField; + int...; +|}; + +type FloatRecord1 record { + float f1; + float f2; + float f3; + float f4; + float f5; + float f6; + float f7; + float f8; +}; + +type FloatRecord2 record {| + float f1; + float f2; + float f3; + float f4; + float f5; + float f6; + float f7; + float f8; +|}; + +type FloatRecord3 record {| + float f1; + float f4; + float f7; +|}; + +type FloatRecord4 record { + float f1; + float f4; + float f7; +}; + +type FloatRecord5 record { + float f1; + float f4; + float f7; + string defaultableField = ""; + string? nillableField = (); +}; + +type FloatRecord6 record {| + float f1; + float f4; + float f7; + string defaultableField = ""; + string? nillableField = (); +|}; + +type FloatRecord7 record { + float f1; + float f4; + float f7; + string defaultableField = ""; + string? nillableField = (); + string requiredField; +}; + +type FloatRecord8 record {| + float f1; + float f4; + float f7; + string defaultableField = ""; + string? nillableField = (); + string requiredField; +|}; + +type FloatRecord9 record {| + float f1; + float f2; + float...; +|}; + +type FloatRecord10 record {| + float...; +|}; + +type FloatRecord11 record {| + float f1; + string defaultableField = ""; + string? nillableField = (); + float...; +|}; + +type FloatRecord12 record {| + float f1; + string defaultableField = ""; + string? nillableField = (); + string requiredField; + float...; +|}; + +type FloatRecord13 record {| + string defaultableField = ""; + string? nillableField = (); + float...; +|}; + +type FloatRecord14 record {| + string defaultableField = ""; + string? nillableField = (); + string requiredField; + float...; +|}; + +type DecimalRecord1 record { + decimal d1; + decimal d2; + decimal d3; + decimal d4; + decimal d5; + decimal d6; + decimal d7; + decimal d8; +}; + +type DecimalRecord2 record {| + decimal d1; + decimal d2; + decimal d3; + decimal d4; + decimal d5; + decimal d6; + decimal d7; + decimal d8; +|}; + +type DecimalRecord3 record {| + decimal d1; + decimal d4; + decimal d7; +|}; + +type DecimalRecord4 record { + decimal d1; + decimal d4; + decimal d7; +}; + +type DecimalRecord5 record { + decimal d1; + decimal d4; + decimal d7; + string defaultableField = ""; + string? nillableField = (); +}; + +type DecimalRecord6 record {| + decimal d1; + decimal d4; + decimal d7; + string defaultableField = ""; + string? nillableField = (); +|}; + +type DecimalRecord7 record { + decimal d1; + decimal d4; + decimal d7; + string defaultableField = ""; + string? nillableField = (); + string requiredField; +}; + +type DecimalRecord8 record {| + decimal d1; + decimal d4; + decimal d7; + string defaultableField = ""; + string? nillableField = (); + string requiredField; +|}; + +type DecimalRecord9 record {| + decimal d1; + decimal d2; + decimal...; +|}; + +type DecimalRecord10 record {| + decimal...; +|}; + +type DecimalRecord11 record {| + decimal d1; + string defaultableField = ""; + string? nillableField = (); + decimal...; +|}; + +type DecimalRecord12 record {| + decimal d1; + string defaultableField = ""; + string? nillableField = (); + string requiredField; + decimal...; +|}; + +type DecimalRecord13 record {| + string defaultableField = ""; + string? nillableField = (); + decimal...; +|}; + +type DecimalRecord14 record {| + string defaultableField = ""; + string? nillableField = (); + string requiredField; + decimal...; +|}; + +type StringRecord1 record { + string s1; + string s2; + string s3; +}; + +type StringRecord2 record {| + string s1; + string s2; + string s3; +|}; + +type StringRecord3 record {| + string s1; + string s4; +|}; + +type StringRecord4 record { + string s1; + string s4; +}; + +type StringRecord5 record { + string s1; + string s4; + string defaultableField = ""; + string? nillableField = (); +}; + +type StringRecord6 record {| + string s1; + string s4; + string defaultableField = ""; + string? nillableField = (); +|}; + +type StringRecord7 record { + string s1; + string s4; + string defaultableField = ""; + string? nillableField = (); + string requiredField; +}; + +type StringRecord8 record {| + string s1; + string s4; + string defaultableField = ""; + string? nillableField = (); + string requiredField; +|}; + +type StringRecord9 record {| + string s1; + string s2; + string...; +|}; + +type StringRecord10 record {| + string...; +|}; + +type StringRecord11 record {| + string s1; + string defaultableField = ""; + string? nillableField = (); + string...; +|}; + +type StringRecord12 record {| + string d1; + string defaultableField = ""; + string? nillableField = (); + string requiredField; + string...; +|}; + +type StringRecord13 record {| + string defaultableField = ""; + string? nillableField = (); + string...; +|}; + +type StringRecord14 record {| + string defaultableField = ""; + string? nillableField = (); + string requiredField; + string...; +|}; + +type StringRecord15 record {| + string defaultableField = ""; + string? nillableField = (); + string requiredField; + string...; +|}; + +type StringRecord16 record {| + string?...; +|}; + +type StringRecord17 record {| + int...; +|}; + +type StringRecord18 record {| + string b2; + int?...; +|}; + +type StringRecord19 record { + string s1 = ""; + string s2 = ""; +}; + +type StringRecord20 record {| + string s1 = ""; + string s2 = ""; +|}; + +type StringRecord21 record { +}; + +type StringRecord22 record {| + string s1 = ""; + string s2 = ""; + json...; +|}; + +type StringRecord23 record {| + json...; +|}; + +type JsonRecord1 record { + json j1; + json j2; + json j3; +}; + +type JsonRecord2 record {| + json j1; + json j2; + json j3; +|}; + +type JsonRecord3 record {| + json j1; + json j4; +|}; + +type JsonRecord4 record { + json j1; + json j4; +}; + +type JsonRecord5 record { + json j1; + json j4; + json defaultableField = ""; + json? nillableField = (); +}; + +type JsonRecord6 record {| + json j1; + json j4; + json defaultableField = ""; + json? nillableField = (); +|}; + +type JsonRecord7 record { + json j1; + json j4; + json defaultableField = ""; + json? nillableField = (); + json requiredField; +}; + +type JsonRecord8 record {| + json j1; + json j4; + json defaultableField = ""; + json? nillableField = (); + json requiredField; +|}; + +type JsonRecord9 record {| + json j1; + json j2; + json...; +|}; + +type JsonRecord10 record {| + json...; +|}; + +type JsonRecord11 record {| + json j1; + json defaultableField = ""; + json? nillableField = (); + json...; +|}; + +type JsonRecord12 record {| + json j1; + json defaultableField = ""; + json? nillableField = (); + json requiredField; + json...; +|}; + +type JsonRecord13 record {| + json defaultableField = ""; + json? nillableField = (); + json...; +|}; + +type JsonRecord14 record {| + json defaultableField = ""; + json? nillableField = (); + json requiredField; + json...; +|}; + +type AnydataRecord1 record { + anydata anydata1; + anydata anydata2; + anydata anydata3; +}; + +type AnydataRecord2 record {| + anydata anydata1; + anydata anydata2; + anydata anydata3; +|}; + +type AnydataRecord3 record {| + anydata anydata1; + anydata anydata4; +|}; + +type AnydataRecord4 record { + anydata anydata1; + anydata anydata4; +}; + +type AnydataRecord5 record { + anydata anydata1; + anydata anydata4; + anydata defaultableField = ""; + anydata? nillableField = (); +}; + +type AnydataRecord6 record {| + anydata anydata1; + anydata anydata4; + anydata defaultableField = ""; + anydata? nillableField = (); +|}; + +type AnydataRecord7 record { + anydata anydata1; + anydata anydata4; + anydata defaultableField = ""; + anydata? nillableField = (); + anydata requiredField; +}; + +type AnydataRecord8 record {| + anydata anydata1; + anydata anydata4; + anydata defaultableField = ""; + anydata? nillableField = (); + anydata requiredField; +|}; + +type AnydataRecord9 record {| + anydata anydata1; + anydata anydata2; + anydata...; +|}; + +type AnydataRecord10 record {| + anydata...; +|}; + +type AnydataRecord11 record {| + anydata anydata1; + anydata defaultableField = ""; + anydata? nillableField = (); + anydata...; +|}; + +type AnydataRecord12 record {| + anydata anydata1; + anydata defaultableField = ""; + anydata? nillableField = (); + anydata requiredField; + anydata...; +|}; + +type AnydataRecord13 record {| + anydata defaultableField = ""; + anydata? nillableField = (); + anydata...; +|}; + +type AnydataRecord14 record {| + anydata defaultableField = ""; + anydata? nillableField = (); + anydata requiredField; + anydata...; +|}; + +type CustomRecord1 record { + int i1; + int i2; + string s1; + string s2; + boolean b1; + boolean b2; + () n1; + () n2; + float f1; + float f2; + decimal d1; + decimal d2; +}; + +type CustomRecord2 record {| + int i1; + int i2; + string s1; + string s2; + boolean b1; + boolean b2; + () n1; + () n2; + float f1; + float f2; + decimal d1; + decimal d2; +|}; + +type CustomRecord3 record {| + int i1; + string s1; + boolean b1; + () n1; + float f1; + decimal d1; +|}; + +type CustomRecord4 record { + int i1; + string s1; + boolean b1; + () n1; + float f1; + decimal d1; +}; + +type CustomRecord5 record { + int i1; + string s1; + boolean b1; + () n1; + float f1; + decimal d1; + string defaultableField = ""; + string? nillableField = (); +}; + +type CustomRecord6 record {| + int i1; + string s1; + boolean b1; + () n1; + float f1; + decimal d1; + anydata defaultableField = ""; + anydata? nillableField = (); +|}; + +type CustomRecord7 record { + int i1; + string s1; + boolean b1; + () n1; + float f1; + decimal d1; + anydata defaultableField = ""; + anydata? nillableField = (); + anydata requiredField; +}; + +type CustomRecord8 record {| + int i1; + string s1; + boolean b1; + () n1; + float f1; + decimal d1; + anydata defaultableField = ""; + anydata? nillableField = (); + anydata requiredField; +|}; + +type CustomRecord9 record {| + int i1; + string s1; + boolean b1; + () n1; + float f1; + decimal d1; + string...; +|}; + +type CustomRecord10 record {| + string...; +|}; + +type CustomRecord11 record {| + int i1; + string s1; + boolean b1; + () n1; + float f1; + decimal d1; + anydata defaultableField = ""; + anydata? nillableField = (); + string...; +|}; + +type CustomRecord12 record {| + int i1; + string s1; + boolean b1; + () n1; + float f1; + decimal d1; + anydata defaultableField = ""; + anydata? nillableField = (); + anydata requiredField; + string...; +|}; + +type CustomRecord13 record {| + anydata defaultableField = ""; + anydata? nillableField = (); + string...; +|}; + +type CustomRecord14 record {| + anydata defaultableField = ""; + anydata? nillableField = (); + anydata requiredField; + string...; +|}; + +type CustomRecord15 record {| + string '1; + string '2; +|}; + +type CustomRecord16 record {| + string '1; + string '2; + string '3; + string '4; +|}; + +type CustomRecord17 record { + string '1; + string '2; +}; + +type CustomRecord18 record { + string '1; + string '2; + string '3; + string '4; +}; + +type CustomRecord19 record { + string '1; + string '2; + string '3 = ""; + string '4 = ""; +}; + +type CustomRecord20 record { + string '1; +}; + +type CustomRecord21 record {| + string '1; + json...; +|}; + +type CustomRecord22 record {| + string '1; + string...; +|}; + +type CustomRecord23 record {| + string '1; + string a = ""; + string...; +|}; + +type CustomRecord24 record {| + string '1; + string '2 = ""; + string...; +|}; + +type CustomRecord25 record {| + int '1; + string...; +|}; + +type CustomRecord26 record {| + string '1; + int...; +|}; + +type CustomRecord27 record {| + int i1; + string s1; + boolean b1; + () n1; + float f1; + decimal d1; + anydata a1; + json j1; + anydata defaultableField = ""; + anydata? nillableField = (); + string...; +|}; + +type CustomRecord28 record { + string '1; +}; + +type CustomRecord29 record { + int '1; +}; + +type CustomRecord30 record {| + string '1; + string '2; + string '3; + string '4; + string '5; + string '6; +|}; + +type CustomRecord31 record {| + string '1; + string '6; +|}; + +type CustomRecord32 record {| + int '1; +|}; + +type CustomRecord33 record {| + string '1; + string '2; + string '3; + string '4; + string '5; + string '6; +|}; + +type CustomRecord34 record { + string '1; + string '6; + string '5 = ""; +}; + +type CustomRecord35 record { + string '1; + string '6; + string '9 = ""; +}; + +type CustomRecord36 record {| + string '1; + string '6; + string '9 = ""; +|}; + +type CustomRecord37 record {| + string '1; + string '6; + string '5 = ""; +|}; + +type CustomRecord38 record {| + string '1; + string '2; + string '3; + string '4; + string '5; + string '6; + string ...; +|}; + +type CustomRecord39 record {| + string '1; + string '2; + string '3; + string '4; + string '5; + string '6; + json ...; +|}; + +type CustomRecord40 record {| + string '5; + string '6; + json ...; +|}; + +type CustomRecord41 record {| + json ...; +|}; + +type CustomRecord42 record {| + int '1; + string '2; + boolean '3; + decimal '4; + float '5; + () '6; +|}; + +type CustomRecord43 record { + int '1; + string '2; + boolean '3; + decimal '4; + float '5; + () '6; +}; + +type CustomRecord44 record {| + int '1; + string '2; + boolean '3; + decimal '4; + float '5; + () '6; + string ...; +|}; + +type CustomRecord45 record {| + int H1; + string H2; + boolean H3; + decimal H4; + float H5; + () H6; +|}; + +type CustomRecord46 record { + int H1; + string H2; + boolean H3; + decimal H4; + float H5; + () H6; +}; + +type CustomRecord47 record {| + int H1; + string H2; + boolean H3; + decimal H4; + float H5; + () H6; + string ...; +|}; + +type CustomRecord48 record { + string H1; + string H2; + string H3; + string H4; + string H5; + string H6; +}; + +type CustomRecord49 record {| + string H1; + string H2; + string H3; + string H4; + string H5; + string H6; +|}; + +type CustomRecord50 record { + int H1; + float H4; +}; + +type CustomRecord51 record {| + int H1; + float H4; +|}; + +type CustomRecord52 record {| + string H1; + string H4; + string ...; +|}; + +type CustomRecord53 record {| + int H1; + float H4; + decimal ...; +|}; + +type CustomRecord54 record {| + string H1 = ""; + string H4; + string '1; +|}; + +type CustomRecord55 record {| + string H1 = ""; + string H4 = ""; + int '1 = 10; +|}; + +type CustomRecord56 record { + string H1 = ""; + string H4 = ""; + anydata '1 = 10; +}; + +type BooleanTuple1 [boolean, boolean, boolean, boolean]; + +type BooleanTuple2 [boolean, boolean]; + +type BooleanTuple3 [boolean, boolean...]; + +type BooleanTuple4 [boolean...]; + +type NillableBooleanTuple5 [boolean?, boolean?, boolean?, boolean?, boolean?]; + +type NillableBooleanTuple6 [boolean?, boolean?]; + +type NillableBooleanTuple7 [boolean?, boolean?, boolean?...]; + +type NillableBooleanTuple8 [boolean?...]; + +type NillableIntBooleanTuple9 [int|boolean?, int|boolean?...]; + +type NilTuple1 [(), (), ()]; + +type NilTuple2 [(), ()]; + +type NilTuple3 [(), ()...]; + +type NilTuple4 [()...]; + +type IntegerTuple1 [int, int, int, int, int, int]; + +type IntegerTuple2 [int, int]; + +type IntegerTuple3 [int, int...]; + +type IntegerTuple4 [int...]; + +type FloatTuple1 [float, float, float, float, float, float, float]; + +type FloatTuple2 [float, float]; + +type FloatTuple3 [float, float...]; + +type FloatTuple4 [float...]; + +type DecimalTuple1 [decimal, decimal, decimal, decimal]; + +type DecimalTuple2 [decimal, decimal]; + +type DecimalTuple3 [decimal, decimal...]; + +type DecimalTuple4 [decimal...]; + +type StringTuple1 [string, string, string, string]; + +type StringTuple2 [string, string]; + +type StringTuple3 [string, string...]; + +type StringTuple4 [string...]; + +type AnydataTuple1 [anydata, anydata, anydata, anydata, anydata, + anydata, anydata, anydata, anydata, anydata, anydata, anydata, + anydata, anydata, anydata, anydata, anydata, anydata, anydata, + anydata, anydata, anydata, anydata]; + +type AnydataTuple2 [anydata, anydata]; + +type AnydataTuple3 [anydata, anydata...]; + +type AnydataTuple4 [anydata...]; + +type JsonTuple1 [json, json, json, json, json, json, json, json, + json, json, json, json, json, json, json, json, json, json, + json, json, json, json, json]; + +type JsonTuple2 [json, json]; + +type JsonTuple3 [json, json...]; + +type JsonTuple4 [json...]; + +type CustomTuple1 [string, int, decimal, float, (), boolean, anydata, json, string, int, decimal, float, (), boolean, anydata, json]; + +type CustomTuple2 [string, int, decimal, float, (), boolean, anydata, json]; + +type CustomTuple3 [string, int, decimal, float, (), boolean, anydata, json, string...]; + +type CustomTuple4 [string...]; + +type CustomTuple5 [string, int, decimal, float, (), boolean, anydata, json, anydata...]; + +type CustomTuple6 [anydata...]; + +type CustomTuple7 [int, string, boolean, (), float, decimal, json, anydata, string...]; + +type CustomTuple8 [int, string, boolean, (), float, decimal, json, anydata, int...]; + +type IntegerArray1 int[]; + +type IntegerArray2 int[2]; + +type IntegerArray3 int[]; + +type IntegerArray4 int[2]; + +type IntegerArray5 int[3]; + +type IntegerArray6 int[4]; + +type StringArray string[]; + +type NillableStringArray string?[]; + +type NillableIntOrUnionStringArray (int|string?)[]; + +type StringArray1 string[]; + +type StringArray2 string[2]; + +type StringArray3 string[]; + +type StringArray4 string[2]; + +type StringArray5 string[3]; + +type StringArray6 string[4]; + +type FloatArray1 float[]; + +type FloatArray2 float[2]; + +type FloatArray3 float[]; + +type FloatArray4 float[2]; + +type FloatArray5 float[3]; + +type FloatArray6 float[4]; + +type DecimalArray1 decimal[]; + +type DecimalArray2 decimal[2]; + +type DecimalArray3 decimal[]; + +type DecimalArray4 decimal[2]; + +type DecimalArray5 decimal[3]; + +type DecimalArray6 decimal[4]; + +type BooleanArray boolean[]; + +type NillableBooleanArray boolean?[]; + +type NillableIntOrUnionBooleanArray (int|boolean?)[]; + +type BooleanArray2 boolean[2]; + +type BooleanArray3 boolean[3]; + +type BooleanArray4 boolean[]; + +type BooleanArray5 boolean[2]; + +type BooleanArray6 boolean[4]; + +type NilArray1 ()[]; + +type NilArray2 ()[2]; + +type NilArray3 ()[]; + +type NilArray4 ()[2]; + +type NilArray5 ()[3]; + +type NilArray6 ()[4]; + +type JsonArray1 json[]; + +type JsonArray2 json[2]; + +type JsonArray3 json[]; + +type JsonArray4 json[2]; + +type JsonArray5 json[3]; + +type JsonArray6 json[4]; + +type AnydataArray1 anydata[]; + +type AnydataArray2 anydata[2]; + +type AnydataArray3 anydata[]; + +type AnydataArray4 anydata[2]; + +type AnydataArray5 anydata[3]; + +type AnydataArray6 anydata[4]; + +type CustomArray1 CustomTuple2[]; + +type CustomArray2 CustomTuple2[2]; + +type CustomArray3 CustomTuple2[]; + +type CustomArray4 CustomTuple2[2]; + +type CustomArray5 CustomTuple2[3]; + +type CustomArray6 CustomTuple2[4]; + +type IntegerMap map; + +type StringMap map; + +type NillableIntUnionStringMap map; + +type IntUnionStringMap map; + +type DecimalMap map; + +type FloatMap map; + +type BooleanMap map; + +type NillableBooleanMap map; + +type NillableIntUnionBooleanMap map; + +type IntUnionBooleanMap map; + +type NilMap map<()>; + +type JsonMap map; + +type AnydataMap map; + +type CustomMap map; + +type BooleanRecord1Array BooleanRecord1[]; + +type ClosedBooleanRecord1Array BooleanRecord1[3]; + +type BooleanRecord2Array BooleanRecord2[]; + +type ClosedBooleanRecord2Array BooleanRecord2[3]; + +type BooleanRecord3Array BooleanRecord3[]; + +type ClosedBooleanRecord3Array BooleanRecord3[3]; + +type BooleanRecord4Array BooleanRecord4[]; + +type ClosedBooleanRecord4Array BooleanRecord4[3]; + +type BooleanRecord5Array BooleanRecord5[]; + +type ClosedBooleanRecord5Array BooleanRecord5[3]; + +type BooleanRecord6Array BooleanRecord6[]; + +type ClosedBooleanRecord6Array BooleanRecord6[3]; + +type BooleanRecord7Array BooleanRecord7[]; + +type ClosedBooleanRecord7Array BooleanRecord7[3]; + +type BooleanRecord8Array BooleanRecord8[]; + +type ClosedBooleanRecord8Array BooleanRecord8[3]; + +type BooleanRecord9Array BooleanRecord9[]; + +type ClosedBooleanRecord9Array BooleanRecord9[3]; + +type BooleanRecord10Array BooleanRecord10[]; + +type ClosedBooleanRecord10Array BooleanRecord10[3]; + +type BooleanRecord11Array BooleanRecord11[]; + +type ClosedBooleanRecord11Array BooleanRecord11[3]; + +type BooleanRecord12Array BooleanRecord12[]; + +type ClosedBooleanRecord12Array BooleanRecord12[3]; + +type BooleanRecord13Array BooleanRecord13[]; + +type ClosedBooleanRecord13Array BooleanRecord13[3]; + +type BooleanRecord14Array BooleanRecord14[]; + +type ClosedBooleanRecord14Array BooleanRecord14[3]; + +type BooleanRecord15Array BooleanRecord15[]; + +type ClosedBooleanRecord15Array BooleanRecord15[3]; + +type BooleanRecord16Array BooleanRecord16[]; + +type ClosedBooleanRecord16Array BooleanRecord16[3]; + +type BooleanRecord17Array BooleanRecord17[]; + +type ClosedBooleanRecord17Array BooleanRecord17[3]; + +type BooleanRecord18Array BooleanRecord18[]; + +type ClosedBooleanRecord18Array BooleanRecord18[3]; + +type NilRecord1Array NilRecord1[]; + +type ClosedNilRecord1Array NilRecord1[3]; + +type NilRecord2Array NilRecord2[]; + +type ClosedNilRecord2Array NilRecord2[3]; + +type NilRecord3Array NilRecord3[]; + +type ClosedNilRecord3Array NilRecord3[3]; + +type NilRecord4Array NilRecord4[]; + +type ClosedNilRecord4Array NilRecord4[3]; + +type NilRecord5Array NilRecord5[]; + +type ClosedNilRecord5Array NilRecord5[3]; + +type NilRecord6Array NilRecord6[]; + +type ClosedNilRecord6Array NilRecord6[3]; + +type NilRecord7Array NilRecord7[]; + +type ClosedNilRecord7Array NilRecord7[3]; + +type NilRecord8Array NilRecord8[]; + +type ClosedNilRecord8Array NilRecord8[3]; + +type NilRecord9Array NilRecord9[]; + +type ClosedNilRecord9Array NilRecord9[3]; + +type NilRecord10Array NilRecord10[]; + +type ClosedNilRecord10Array NilRecord10[3]; + +type NilRecord11Array NilRecord11[]; + +type ClosedNilRecord11Array NilRecord11[3]; + +type NilRecord12Array NilRecord12[]; + +type ClosedNilRecord12Array NilRecord12[3]; + +type NilRecord13Array NilRecord13[]; + +type ClosedNilRecord13Array NilRecord13[3]; + +type NilRecord14Array NilRecord14[]; + +type ClosedNilRecord14Array NilRecord14[3]; + +type IntegerRecord1Array IntegerRecord1[]; + +type ClosedIntegerRecord1Array IntegerRecord1[3]; + +type IntegerRecord2Array IntegerRecord2[]; + +type ClosedIntegerRecord2Array IntegerRecord2[3]; + +type IntegerRecord3Array IntegerRecord3[]; + +type ClosedIntegerRecord3Array IntegerRecord3[3]; + +type IntegerRecord4Array IntegerRecord4[]; + +type ClosedIntegerRecord4Array IntegerRecord4[3]; + +type IntegerRecord5Array IntegerRecord5[]; + +type ClosedIntegerRecord5Array IntegerRecord5[3]; + +type IntegerRecord6Array IntegerRecord6[]; + +type ClosedIntegerRecord6Array IntegerRecord6[3]; + +type IntegerRecord7Array IntegerRecord7[]; + +type ClosedIntegerRecord7Array IntegerRecord7[3]; + +type IntegerRecord8Array IntegerRecord8[]; + +type ClosedIntegerRecord8Array IntegerRecord8[3]; + +type IntegerRecord9Array IntegerRecord9[]; + +type ClosedIntegerRecord9Array IntegerRecord9[3]; + +type IntegerRecord10Array IntegerRecord10[]; + +type ClosedIntegerRecord10Array IntegerRecord10[3]; + +type IntegerRecord11Array IntegerRecord11[]; + +type ClosedIntegerRecord11Array IntegerRecord11[3]; + +type IntegerRecord12Array IntegerRecord12[]; + +type ClosedIntegerRecord12Array IntegerRecord12[3]; + +type IntegerRecord13Array IntegerRecord13[]; + +type ClosedIntegerRecord13Array IntegerRecord13[3]; + +type IntegerRecord14Array IntegerRecord14[]; + +type ClosedIntegerRecord14Array IntegerRecord14[3]; + +type FloatRecord1Array FloatRecord1[]; + +type ClosedFloatRecord1Array FloatRecord1[3]; + +type FloatRecord2Array FloatRecord2[]; + +type ClosedFloatRecord2Array FloatRecord2[3]; + +type FloatRecord3Array FloatRecord3[]; + +type ClosedFloatRecord3Array FloatRecord3[3]; + +type FloatRecord4Array FloatRecord4[]; + +type ClosedFloatRecord4Array FloatRecord4[3]; + +type FloatRecord5Array FloatRecord5[]; + +type ClosedFloatRecord5Array FloatRecord5[3]; + +type FloatRecord6Array FloatRecord6[]; + +type ClosedFloatRecord6Array FloatRecord6[3]; + +type FloatRecord7Array FloatRecord7[]; + +type ClosedFloatRecord7Array FloatRecord7[3]; + +type FloatRecord8Array FloatRecord8[]; + +type ClosedFloatRecord8Array FloatRecord8[3]; + +type FloatRecord9Array FloatRecord9[]; + +type ClosedFloatRecord9Array FloatRecord9[3]; + +type FloatRecord10Array FloatRecord10[]; + +type ClosedFloatRecord10Array FloatRecord10[3]; + +type FloatRecord11Array FloatRecord11[]; + +type ClosedFloatRecord11Array FloatRecord11[3]; + +type FloatRecord12Array FloatRecord12[]; + +type ClosedFloatRecord12Array FloatRecord12[3]; + +type FloatRecord13Array FloatRecord13[]; + +type ClosedFloatRecord13Array FloatRecord13[3]; + +type FloatRecord14Array FloatRecord14[]; + +type ClosedFloatRecord14Array FloatRecord14[3]; + +type DecimalRecord1Array DecimalRecord1[]; + +type ClosedDecimalRecord1Array DecimalRecord1[3]; + +type DecimalRecord2Array DecimalRecord2[]; + +type ClosedDecimalRecord2Array DecimalRecord2[3]; + +type DecimalRecord3Array DecimalRecord3[]; + +type ClosedDecimalRecord3Array DecimalRecord3[3]; + +type DecimalRecord4Array DecimalRecord4[]; + +type ClosedDecimalRecord4Array DecimalRecord4[3]; + +type DecimalRecord5Array DecimalRecord5[]; + +type ClosedDecimalRecord5Array DecimalRecord5[3]; + +type DecimalRecord6Array DecimalRecord6[]; + +type ClosedDecimalRecord6Array DecimalRecord6[3]; + +type DecimalRecord7Array DecimalRecord7[]; + +type ClosedDecimalRecord7Array DecimalRecord7[3]; + +type DecimalRecord8Array DecimalRecord8[]; + +type ClosedDecimalRecord8Array DecimalRecord8[3]; + +type DecimalRecord9Array DecimalRecord9[]; + +type ClosedDecimalRecord9Array DecimalRecord9[3]; + +type DecimalRecord10Array DecimalRecord10[]; + +type ClosedDecimalRecord10Array DecimalRecord10[3]; + +type DecimalRecord11Array DecimalRecord11[]; + +type ClosedDecimalRecord11Array DecimalRecord11[3]; + +type DecimalRecord12Array DecimalRecord12[]; + +type ClosedDecimalRecord12Array DecimalRecord12[3]; + +type DecimalRecord13Array DecimalRecord13[]; + +type ClosedDecimalRecord13Array DecimalRecord13[3]; + +type DecimalRecord14Array DecimalRecord14[]; + +type ClosedDecimalRecord14Array DecimalRecord14[3]; + +type StringRecord1Array StringRecord1[]; + +type ClosedStringRecord1Array StringRecord1[3]; + +type StringRecord2Array StringRecord2[]; + +type ClosedStringRecord2Array StringRecord2[3]; + +type StringRecord3Array StringRecord3[]; + +type ClosedStringRecord3Array StringRecord3[3]; + +type StringRecord4Array StringRecord4[]; + +type ClosedStringRecord4Array StringRecord4[3]; + +type StringRecord5Array StringRecord5[]; + +type ClosedStringRecord5Array StringRecord5[3]; + +type StringRecord6Array StringRecord6[]; + +type ClosedStringRecord6Array StringRecord6[3]; + +type StringRecord7Array StringRecord7[]; + +type ClosedStringRecord7Array StringRecord7[3]; + +type StringRecord8Array StringRecord8[]; + +type ClosedStringRecord8Array StringRecord8[3]; + +type StringRecord9Array StringRecord9[]; + +type ClosedStringRecord9Array StringRecord9[3]; + +type StringRecord10Array StringRecord10[]; + +type ClosedStringRecord10Array StringRecord10[3]; + +type StringRecord11Array StringRecord11[]; + +type ClosedStringRecord11Array StringRecord11[3]; + +type StringRecord12Array StringRecord12[]; + +type ClosedStringRecord12Array StringRecord12[3]; + +type StringRecord13Array StringRecord13[]; + +type ClosedStringRecord13Array StringRecord13[3]; + +type StringRecord14Array StringRecord14[]; + +type ClosedStringRecord14Array StringRecord14[3]; + +type StringRecord15Array StringRecord15[]; + +type StringRecord16Array StringRecord16[]; + +type StringRecord17Array StringRecord17[]; + +type StringRecord18Array StringRecord18[]; + +type StringRecord19Array StringRecord19[]; + +type StringRecord20Array StringRecord20[]; + +type StringRecord21Array StringRecord21[]; + +type StringRecord22Array StringRecord22[]; + +type StringRecord23Array StringRecord23[]; + +type JsonRecord1Array JsonRecord1[]; + +type ClosedJsonRecord1Array JsonRecord1[3]; + +type JsonRecord2Array JsonRecord2[]; + +type ClosedJsonRecord2Array JsonRecord2[3]; + +type JsonRecord3Array JsonRecord3[]; + +type ClosedJsonRecord3Array JsonRecord3[3]; + +type JsonRecord4Array JsonRecord4[]; + +type ClosedJsonRecord4Array JsonRecord4[3]; + +type JsonRecord5Array JsonRecord5[]; + +type ClosedJsonRecord5Array JsonRecord5[3]; + +type JsonRecord6Array JsonRecord6[]; + +type ClosedJsonRecord6Array JsonRecord6[3]; + +type JsonRecord7Array JsonRecord7[]; + +type ClosedJsonRecord7Array JsonRecord7[3]; + +type JsonRecord8Array JsonRecord8[]; + +type ClosedJsonRecord8Array JsonRecord8[3]; + +type JsonRecord9Array JsonRecord9[]; + +type ClosedJsonRecord9Array JsonRecord9[3]; + +type JsonRecord10Array JsonRecord10[]; + +type ClosedJsonRecord10Array JsonRecord10[3]; + +type JsonRecord11Array JsonRecord11[]; + +type ClosedJsonRecord11Array JsonRecord11[3]; + +type JsonRecord12Array JsonRecord12[]; + +type ClosedJsonRecord12Array JsonRecord12[3]; + +type JsonRecord13Array JsonRecord13[]; + +type ClosedJsonRecord13Array JsonRecord13[3]; + +type JsonRecord14Array JsonRecord14[]; + +type ClosedJsonRecord14Array JsonRecord14[3]; + +type AnydataRecord1Array AnydataRecord1[]; + +type ClosedAnydataRecord1Array AnydataRecord1[3]; + +type AnydataRecord2Array AnydataRecord2[]; + +type ClosedAnydataRecord2Array AnydataRecord2[3]; + +type AnydataRecord3Array AnydataRecord3[]; + +type ClosedAnydataRecord3Array AnydataRecord3[3]; + +type AnydataRecord4Array AnydataRecord4[]; + +type ClosedAnydataRecord4Array AnydataRecord4[3]; + +type AnydataRecord5Array AnydataRecord5[]; + +type ClosedAnydataRecord5Array AnydataRecord5[3]; + +type AnydataRecord6Array AnydataRecord6[]; + +type ClosedAnydataRecord6Array AnydataRecord6[3]; + +type AnydataRecord7Array AnydataRecord7[]; + +type ClosedAnydataRecord7Array AnydataRecord7[3]; + +type AnydataRecord8Array AnydataRecord8[]; + +type ClosedAnydataRecord8Array AnydataRecord8[3]; + +type AnydataRecord9Array AnydataRecord9[]; + +type ClosedAnydataRecord9Array AnydataRecord9[3]; + +type AnydataRecord10Array AnydataRecord10[]; + +type ClosedAnydataRecord10Array AnydataRecord10[3]; + +type AnydataRecord11Array AnydataRecord11[]; + +type ClosedAnydataRecord11Array AnydataRecord11[3]; + +type AnydataRecord12Array AnydataRecord12[]; + +type ClosedAnydataRecord12Array AnydataRecord12[3]; + +type AnydataRecord13Array AnydataRecord13[]; + +type ClosedAnydataRecord13Array AnydataRecord13[3]; + +type AnydataRecord14Array AnydataRecord14[]; + +type ClosedAnydataRecord14Array AnydataRecord14[3]; + +type CustomRecord1Array CustomRecord1[]; + +type ClosedCustomRecord1Array CustomRecord1[3]; + +type CustomRecord2Array CustomRecord2[]; + +type ClosedCustomRecord2Array CustomRecord2[3]; + +type CustomRecord3Array CustomRecord3[]; + +type ClosedCustomRecord3Array CustomRecord3[3]; + +type CustomRecord4Array CustomRecord4[]; + +type ClosedCustomRecord4Array CustomRecord4[3]; + +type CustomRecord5Array CustomRecord5[]; + +type ClosedCustomRecord5Array CustomRecord5[3]; + +type CustomRecord6Array CustomRecord6[]; + +type ClosedCustomRecord6Array CustomRecord6[3]; + +type CustomRecord7Array CustomRecord7[]; + +type ClosedCustomRecord7Array CustomRecord7[3]; + +type CustomRecord8Array CustomRecord8[]; + +type ClosedCustomRecord8Array CustomRecord8[3]; + +type CustomRecord9Array CustomRecord9[]; + +type ClosedCustomRecord9Array CustomRecord9[3]; + +type CustomRecord10Array CustomRecord10[]; + +type ClosedCustomRecord10Array CustomRecord10[3]; + +type CustomRecord11Array CustomRecord11[]; + +type ClosedCustomRecord11Array CustomRecord11[3]; + +type CustomRecord12Array CustomRecord12[]; + +type ClosedCustomRecord12Array CustomRecord12[3]; + +type CustomRecord13Array CustomRecord13[]; + +type ClosedCustomRecord13Array CustomRecord13[3]; + +type CustomRecord14Array CustomRecord14[]; + +type ClosedCustomRecord14Array CustomRecord14[3]; + +type CustomRecord15Array CustomRecord15[]; + +type CustomRecord16Array CustomRecord16[]; + +type CustomRecord17Array CustomRecord17[]; + +type CustomRecord18Array CustomRecord18[]; + +type CustomRecord19Array CustomRecord19[]; + +type CustomRecord20Array CustomRecord20[]; + +type CustomRecord21Array CustomRecord21[]; + +type CustomRecord22Array CustomRecord22[]; + +type CustomRecord23Array CustomRecord23[]; + +type CustomRecord24Array CustomRecord24[]; + +type CustomRecord25Array CustomRecord25[]; + +type CustomRecord26Array CustomRecord26[]; + +type CustomRecord27Array CustomRecord27[]; +type CustomRecord28Array CustomRecord28[]; +type CustomRecord29Array CustomRecord29[]; +type CustomRecord30Array CustomRecord30[]; +type CustomRecord31Array CustomRecord31[]; +type CustomRecord32Array CustomRecord32[]; +type CustomRecord33Array CustomRecord33[]; +type CustomRecord34Array CustomRecord34[]; +type CustomRecord35Array CustomRecord35[]; +type CustomRecord36Array CustomRecord36[]; +type CustomRecord37Array CustomRecord37[]; +type CustomRecord38Array CustomRecord38[]; +type CustomRecord39Array CustomRecord39[]; +type CustomRecord40Array CustomRecord40[]; +type CustomRecord41Array CustomRecord41[]; +type CustomRecord42Array CustomRecord42[]; +type CustomRecord43Array CustomRecord43[]; +type CustomRecord44Array CustomRecord44[]; +type CustomRecord45Array CustomRecord45[]; +type CustomRecord46Array CustomRecord46[]; +type CustomRecord47Array CustomRecord47[]; +type CustomRecord48Array CustomRecord48[]; +type CustomRecord49Array CustomRecord49[]; +type CustomRecord50Array CustomRecord50[]; +type CustomRecord51Array CustomRecord51[]; +type CustomRecord52Array CustomRecord52[]; +type CustomRecord53Array CustomRecord53[]; +type CustomRecord54Array CustomRecord54[]; +type CustomRecord55Array CustomRecord55[]; +type CustomRecord56Array CustomRecord56[]; + +type BooleanTuple1Array BooleanTuple1[]; + +type ClosedBooleanTuple1Array BooleanTuple1[3]; + +type BooleanTuple2Array BooleanTuple2[]; + +type ClosedBooleanTuple2Array BooleanTuple2[3]; + +type BooleanTuple3Array BooleanTuple3[]; + +type ClosedBooleanTuple3Array BooleanTuple3[3]; + +type BooleanTuple4Array BooleanTuple4[]; + +type ClosedBooleanTuple4Array BooleanTuple4[3]; + +type NillableBooleanTuple5Array NillableBooleanTuple5[]; + +type NillableBooleanTuple6Array NillableBooleanTuple6[]; + +type NillableBooleanTuple7Array NillableBooleanTuple7[]; + +type NillableBooleanTuple8Array NillableBooleanTuple8[]; + +type NillableIntBooleanTuple9Array NillableIntBooleanTuple9[]; + +type NilTuple1Array NilTuple1[]; + +type ClosedNilTuple1Array NilTuple1[3]; + +type NilTuple2Array NilTuple2[]; + +type ClosedNilTuple2Array NilTuple2[3]; + +type NilTuple3Array NilTuple3[]; + +type ClosedNilTuple3Array NilTuple3[3]; + +type NilTuple4Array NilTuple4[]; + +type ClosedNilTuple4Array NilTuple4[3]; + +type IntegerTuple1Array IntegerTuple1[]; + +type ClosedIntegerTuple1Array IntegerTuple1[3]; + +type IntegerTuple2Array IntegerTuple2[]; + +type ClosedIntegerTuple2Array IntegerTuple2[3]; + +type IntegerTuple3Array IntegerTuple3[]; + +type ClosedIntegerTuple3Array IntegerTuple3[3]; + +type IntegerTuple4Array IntegerTuple4[]; + +type ClosedIntegerTuple4Array IntegerTuple4[3]; + +type FloatTuple1Array FloatTuple1[]; + +type ClosedFloatTuple1Array FloatTuple1[3]; + +type FloatTuple2Array FloatTuple2[]; + +type ClosedFloatTuple2Array FloatTuple2[3]; + +type FloatTuple3Array FloatTuple3[]; + +type ClosedFloatTuple3Array FloatTuple3[3]; + +type FloatTuple4Array FloatTuple4[]; + +type ClosedFloatTuple4Array FloatTuple4[3]; + +type DecimalTuple1Array DecimalTuple1[]; + +type ClosedDecimalTuple1Array DecimalTuple1[3]; + +type DecimalTuple2Array DecimalTuple2[]; + +type ClosedDecimalTuple2Array DecimalTuple2[3]; + +type DecimalTuple3Array DecimalTuple3[]; + +type ClosedDecimalTuple3Array DecimalTuple3[3]; + +type DecimalTuple4Array DecimalTuple4[]; + +type ClosedDecimalTuple4Array DecimalTuple4[3]; + +type StringTuple1Array StringTuple1[]; + +type ClosedStringTuple1Array StringTuple1[3]; + +type StringTuple2Array StringTuple2[]; + +type ClosedStringTuple2Array StringTuple2[3]; + +type StringTuple3Array StringTuple3[]; + +type ClosedStringTuple3Array StringTuple3[3]; + +type StringTuple4Array StringTuple4[]; + +type ClosedStringTuple4Array StringTuple4[3]; + +type AnydataTuple1Array AnydataTuple1[]; + +type ClosedAnydataTuple1Array AnydataTuple1[3]; + +type AnydataTuple2Array AnydataTuple2[]; + +type ClosedAnydataTuple2Array AnydataTuple2[3]; + +type AnydataTuple3Array AnydataTuple3[]; + +type ClosedAnydataTuple3Array AnydataTuple3[3]; + +type AnydataTuple4Array AnydataTuple4[]; + +type ClosedAnydataTuple4Array AnydataTuple4[3]; + +type JsonTuple1Array JsonTuple1[]; + +type ClosedJsonTuple1Array JsonTuple1[3]; + +type JsonTuple2Array JsonTuple2[]; + +type ClosedJsonTuple2Array JsonTuple2[3]; + +type JsonTuple3Array JsonTuple3[]; + +type ClosedJsonTuple3Array JsonTuple3[3]; + +type JsonTuple4Array JsonTuple4[]; + +type ClosedJsonTuple4Array JsonTuple4[3]; + +type CustomTuple1Array CustomTuple1[]; + +type ClosedCustomTuple1Array CustomTuple1[3]; + +type CustomTuple2Array CustomTuple2[]; + +type ClosedCustomTuple2Array CustomTuple2[3]; + +type CustomTuple3Array CustomTuple3[]; + +type ClosedCustomTuple3Array CustomTuple3[3]; + +type CustomTuple4Array CustomTuple4[]; + +type ClosedCustomTuple4Array CustomTuple4[3]; + +type CustomTuple5Array CustomTuple5[]; + +type ClosedCustomTuple5Array CustomTuple5[3]; + +type CustomTuple6Array CustomTuple6[]; + +type CustomTuple7Array CustomTuple7[]; + +type CustomTuple8Array CustomTuple8[]; + +type ClosedCustomTuple6Array CustomTuple6[3]; + +type IntegerArray1Array IntegerArray1[]; + +type ClosedIntegerArray1Array IntegerArray1[3]; + +type IntegerArray2Array IntegerArray2[]; + +type ClosedIntegerArray2Array IntegerArray2[3]; + +type IntegerArray3Array IntegerArray3[]; + +type ClosedIntegerArray3Array IntegerArray3[3]; + +type IntegerArray4Array IntegerArray4[]; + +type ClosedIntegerArray4Array IntegerArray4[3]; + +type IntegerArray5Array IntegerArray5[]; + +type ClosedIntegerArray5Array IntegerArray5[3]; + +type IntegerArray6Array IntegerArray5[]; + +type ClosedIntegerArray6Array IntegerArray5[3]; + +type StringArray1Array StringArray1[]; + +type StringArrayArray StringArray[]; + +type NillableStringArrayArray NillableStringArray[]; + +type NillableIntOrUnionStringArrayArray NillableIntOrUnionStringArray[]; + +type ClosedStringArray1Array StringArray1[3]; + +type StringArray2Array StringArray2[]; + +type ClosedStringArray2Array StringArray2[3]; + +type StringArray3Array StringArray3[]; + +type ClosedStringArray3Array StringArray3[3]; + +type StringArray4Array StringArray4[]; + +type ClosedStringArray4Array StringArray4[3]; + +type StringArray5Array StringArray5[]; + +type ClosedStringArray5Array StringArray5[3]; + +type StringArray6Array StringArray5[]; + +type ClosedStringArray6Array StringArray5[3]; + +type FloatArray1Array FloatArray1[]; + +type ClosedFloatArray1Array FloatArray1[3]; + +type FloatArray2Array FloatArray2[]; + +type ClosedFloatArray2Array FloatArray2[3]; + +type FloatArray3Array FloatArray3[]; + +type ClosedFloatArray3Array FloatArray3[3]; + +type FloatArray4Array FloatArray4[]; + +type ClosedFloatArray4Array FloatArray4[3]; + +type FloatArray5Array FloatArray5[]; + +type ClosedFloatArray5Array FloatArray5[3]; + +type FloatArray6Array FloatArray5[]; + +type ClosedFloatArray6Array FloatArray5[3]; + +type DecimalArray1Array DecimalArray1[]; + +type ClosedDecimalArray1Array DecimalArray1[3]; + +type DecimalArray2Array DecimalArray2[]; + +type ClosedDecimalArray2Array DecimalArray2[3]; + +type DecimalArray3Array DecimalArray3[]; + +type ClosedDecimalArray3Array DecimalArray3[3]; + +type DecimalArray4Array DecimalArray4[]; + +type ClosedDecimalArray4Array DecimalArray4[3]; + +type DecimalArray5Array DecimalArray5[]; + +type ClosedDecimalArray5Array DecimalArray5[3]; + +type DecimalArray6Array DecimalArray5[]; + +type ClosedDecimalArray6Array DecimalArray5[3]; + +type BooleanArrayArray BooleanArray[]; + +type ClosedBooleanArrayArray BooleanArray[3]; + +type NillableBooleanArrayArray NillableBooleanArray[]; + +type NillableIntOrUnionBooleanArrayArray NillableIntOrUnionBooleanArray[]; + +type BooleanArray2Array BooleanArray2[]; + +type ClosedBooleanArray2Array BooleanArray2[3]; + +type BooleanArray3Array BooleanArray3[]; + +type ClosedBooleanArray3Array BooleanArray3[3]; + +type BooleanArray4Array BooleanArray4[]; + +type ClosedBooleanArray4Array BooleanArray4[3]; + +type BooleanArray5Array BooleanArray5[]; + +type ClosedBooleanArray5Array BooleanArray5[3]; + +type BooleanArray6Array BooleanArray5[]; + +type ClosedBooleanArray6Array BooleanArray5[3]; + +type NilArray1Array NilArray1[]; + +type ClosedNilArray1Array NilArray1[3]; + +type NilArray2Array NilArray2[]; + +type ClosedNilArray2Array NilArray2[3]; + +type NilArray3Array NilArray3[]; + +type ClosedNilArray3Array NilArray3[3]; + +type NilArray4Array NilArray4[]; + +type ClosedNilArray4Array NilArray4[3]; + +type NilArray5Array NilArray5[]; + +type ClosedNilArray5Array NilArray5[3]; + +type NilArray6Array NilArray5[]; + +type ClosedNilArray6Array NilArray5[3]; + +type JsonArray1Array JsonArray1[]; + +type ClosedJsonArray1Array JsonArray1[3]; + +type JsonArray2Array JsonArray2[]; + +type ClosedJsonArray2Array JsonArray2[3]; + +type JsonArray3Array JsonArray3[]; + +type ClosedJsonArray3Array JsonArray3[3]; + +type JsonArray4Array JsonArray4[]; + +type ClosedJsonArray4Array JsonArray4[3]; + +type JsonArray5Array JsonArray5[]; + +type ClosedJsonArray5Array JsonArray5[3]; + +type JsonArray6Array JsonArray5[]; + +type ClosedJsonArray6Array JsonArray5[3]; + +type AnydataArray1Array AnydataArray1[]; + +type ClosedAnydataArray1Array AnydataArray1[3]; + +type AnydataArray2Array AnydataArray2[]; + +type ClosedAnydataArray2Array AnydataArray2[3]; + +type AnydataArray3Array AnydataArray3[]; + +type ClosedAnydataArray3Array AnydataArray3[3]; + +type AnydataArray4Array AnydataArray4[]; + +type ClosedAnydataArray4Array AnydataArray4[3]; + +type AnydataArray5Array AnydataArray5[]; + +type ClosedAnydataArray5Array AnydataArray5[3]; + +type AnydataArray6Array AnydataArray5[]; + +type ClosedAnydataArray6Array AnydataArray5[3]; + +type CustomArray1Array CustomArray1[]; + +type ClosedCustomArray1Array CustomArray1[3]; + +type CustomArray2Array CustomArray2[]; + +type ClosedCustomArray2Array CustomArray2[3]; + +type CustomArray3Array CustomArray3[]; + +type ClosedCustomArray3Array CustomArray3[3]; + +type CustomArray4Array CustomArray4[]; + +type ClosedCustomArray4Array CustomArray4[3]; + +type CustomArray5Array CustomArray5[]; + +type ClosedCustomArray5Array CustomArray5[3]; + +type CustomArray6Array CustomArray5[]; + +type ClosedCustomArray6Array CustomArray5[3]; + +type IntegerMapArray IntegerMap[]; + +type ClosedIntegerMapArray IntegerMap[3]; + +type StringMapArray StringMap[]; + +type NillableIntUnionStringMapArray NillableIntUnionStringMap[]; + +type IntUnionStringMapArray IntUnionStringMap[]; + +type ClosedStringMapArray StringMap[3]; + +type DecimalMapArray DecimalMap[]; + +type ClosedDecimalMapArray DecimalMap[3]; + +type FloatMapArray FloatMap[]; + +type ClosedFloatMapArray FloatMap[3]; + +type BooleanMapArray BooleanMap[]; + +type NillableBooleanMapArray NillableBooleanMap[]; + +type NillableIntUnionBooleanMapArray NillableIntUnionBooleanMap[]; + +type IntUnionBooleanMapArray IntUnionBooleanMap[]; + +type ClosedBooleanMapArray BooleanMap[3]; + +type NilMapArray NilMap[]; + +type ClosedNilMapArray NilMap[3]; + +type JsonMapArray JsonMap[]; + +type ClosedJsonMapArray JsonMap[3]; + +type AnydataMapArray AnydataMap[]; + +type ClosedAnydataMapArray AnydataMap[3]; + +type CustomMapArray CustomMap[]; + +type ClosedCustomMapArray CustomMap[3]; diff --git a/ballerina-tests/parse-string-record-types-tests/.gitignore b/ballerina-tests/parse-string-record-types-tests/.gitignore new file mode 100644 index 0000000..d5fc29a --- /dev/null +++ b/ballerina-tests/parse-string-record-types-tests/.gitignore @@ -0,0 +1,11 @@ +# Ballerina generates this directory during the compilation of a package. +# It contains compiler-generated artifacts and the final executable if this is an application package. +target/ + +# Ballerina maintains the compiler-generated source code here. +# Remove this if you want to commit generated sources. +generated/ + +# Contains configuration values used during development time. +# See https://ballerina.io/learn/provide-values-to-configurable-variables/ for more details. +Config.toml diff --git a/ballerina-tests/parse-string-record-types-tests/Ballerina.toml b/ballerina-tests/parse-string-record-types-tests/Ballerina.toml new file mode 100644 index 0000000..a9d8337 --- /dev/null +++ b/ballerina-tests/parse-string-record-types-tests/Ballerina.toml @@ -0,0 +1,13 @@ +[package] +org = "ballerina" +name = "parse_string_record_types_tests" +version = "0.1.0" + +[[dependency]] +org = "ballerina" +name = "csv_commons" +repository = "local" +version = "0.1.0" + +[platform.java17] +graalvmCompatible = true diff --git a/ballerina-tests/parse-string-record-types-tests/Dependencies.toml b/ballerina-tests/parse-string-record-types-tests/Dependencies.toml new file mode 100644 index 0000000..7e5d364 --- /dev/null +++ b/ballerina-tests/parse-string-record-types-tests/Dependencies.toml @@ -0,0 +1,98 @@ +# AUTO-GENERATED FILE. DO NOT MODIFY. + +# This file is auto-generated by Ballerina for managing dependency versions. +# It should not be modified by hand. + +[ballerina] +dependencies-toml-version = "2" +distribution-version = "2201.9.0" + +[[package]] +org = "ballerina" +name = "csv_commons" +version = "0.1.0" +scope = "testOnly" +modules = [ + {org = "ballerina", packageName = "csv_commons", moduleName = "csv_commons"} +] + +[[package]] +org = "ballerina" +name = "data.csv" +version = "0.1.0" +scope = "testOnly" +dependencies = [ + {org = "ballerina", name = "jballerina.java"} +] +modules = [ + {org = "ballerina", packageName = "data.csv", moduleName = "data.csv"} +] + +[[package]] +org = "ballerina" +name = "jballerina.java" +version = "0.0.0" +scope = "testOnly" + +[[package]] +org = "ballerina" +name = "lang.__internal" +version = "0.0.0" +scope = "testOnly" +dependencies = [ + {org = "ballerina", name = "jballerina.java"}, + {org = "ballerina", name = "lang.object"} +] + +[[package]] +org = "ballerina" +name = "lang.array" +version = "0.0.0" +scope = "testOnly" +dependencies = [ + {org = "ballerina", name = "jballerina.java"}, + {org = "ballerina", name = "lang.__internal"} +] + +[[package]] +org = "ballerina" +name = "lang.error" +version = "0.0.0" +scope = "testOnly" +dependencies = [ + {org = "ballerina", name = "jballerina.java"} +] + +[[package]] +org = "ballerina" +name = "lang.object" +version = "0.0.0" +scope = "testOnly" + +[[package]] +org = "ballerina" +name = "parse_string_record_types_tests" +version = "0.1.0" +dependencies = [ + {org = "ballerina", name = "csv_commons"}, + {org = "ballerina", name = "data.csv"}, + {org = "ballerina", name = "test"} +] +modules = [ + {org = "ballerina", packageName = "parse_string_record_types_tests", moduleName = "parse_string_record_types_tests"} +] + +[[package]] +org = "ballerina" +name = "test" +version = "0.0.0" +scope = "testOnly" +dependencies = [ + {org = "ballerina", name = "jballerina.java"}, + {org = "ballerina", name = "lang.array"}, + {org = "ballerina", name = "lang.error"} +] +modules = [ + {org = "ballerina", packageName = "test", moduleName = "test"} +] + diff --git a/ballerina-tests/parse-string-record-types-tests/tests/parse_string_to_map_tests copy.bal b/ballerina-tests/parse-string-record-types-tests/tests/parse_string_to_map_tests copy.bal new file mode 100644 index 0000000..8e95f6a --- /dev/null +++ b/ballerina-tests/parse-string-record-types-tests/tests/parse_string_to_map_tests copy.bal @@ -0,0 +1,409 @@ +import ballerina/data.csv as csv; +import ballerina/test; + +@test:Config +function testFromCsvStringWithTypeForStringAndMapAsExpectedType() { + BooleanMapArray|csv:Error bv1bma = csv:parseStringToRecord(csvStringWithBooleanValues1); + test:assertEquals(bv1bma, [ + {b1: true, b2: false, b3: true, b4: false}, + {b1: true, b2: false, b3: true, b4: false}, + {b1: true, b2: false, b3: true, b4: false} + ]); + + BooleanMapArray|csv:Error bv2bma = csv:parseStringToRecord(csvStringWithBooleanValues2); + test:assertEquals(bv2bma, [ + {b1: true, b2: false, b3: true, b4: false, b5: true}, + {b1: true, b2: false, b3: true, b4: false, b5: true} + ]); + + BooleanMapArray|csv:Error bv3bma = csv:parseStringToRecord(csvStringWithBooleanValues3); + test:assertEquals(bv3bma, [ + {b1: true, b2: false, b3: true}, + {b1: true, b2: false}, + {b1: true, b2: true, b3: false} + ]); + + BooleanMapArray|csv:Error bv4bma = csv:parseStringToRecord(csvStringWithBooleanValues4); + test:assertEquals(bv4bma, [ + {b1: true, b4: false}, + {b1: true, b4: false} + ]); + + BooleanMapArray|csv:Error bv5bma = csv:parseStringToRecord(csvStringWithBooleanValues5); + test:assertEquals(bv5bma, [ + {b1: true, b2: false, b3: true}, + {b1: true, b2: false, b3: true} + ]); + + BooleanMapArray|csv:Error bv6bma = csv:parseStringToRecord(csvStringWithBooleanValues6); + test:assertEquals(bv6bma, [ + {} + ]); + + BooleanMapArray|csv:Error bv7bma = csv:parseStringToRecord(csvStringWithBooleanValues7); + test:assertEquals(bv7bma, [ + {b1, b2, b4} + ]); + + NillableBooleanMapArray|csv:Error bv1bnbma = csv:parseStringToRecord(csvStringWithBooleanValues1); + test:assertEquals(bv1bnbma, [ + {b1: true, b2: false, b3: true, b4: false}, + {b1: true, b2: false, b3: true, b4: false}, + {b1: true, b2: false, b3: true, b4: false} + ]); + + NillableBooleanMapArray|csv:Error bv2bnbma = csv:parseStringToRecord(csvStringWithBooleanValues2); + test:assertEquals(bv2bnbma, [ + {b1: true, b2: false, b3: true, b4: false, b5: true}, + {b1: true, b2: false, b3: true, b4: false, b5: true} + ]); + + NillableBooleanMapArray|csv:Error bv3bnbma = csv:parseStringToRecord(csvStringWithBooleanValues3); + test:assertEquals(bv3bnbma, [ + {b1: true, b2: false, b3: true}, + {b1: true, b2: false, b3: null}, + {b1: true, b2: true, b3: false} + ]); + + NillableBooleanMapArray|csv:Error bv4bnbma = csv:parseStringToRecord(csvStringWithBooleanValues4); + test:assertEquals(bv4bnbma, [ + {b1: true, b2: (), b3: (), b4: false}, + {b1: true, b2: (), b3: (), b4: false} + ]); + + NillableBooleanMapArray|csv:Error bv5bnbma = csv:parseStringToRecord(csvStringWithBooleanValues5); + test:assertEquals(bv5bnbma, [ + {b1: true, b2: false, b3: true}, + {b1: true, b2: false, b3: true} + ]); + + NillableBooleanMapArray|csv:Error bv6bnbma = csv:parseStringToRecord(csvStringWithBooleanValues6); + test:assertEquals(bv6bnbma, [ + {b2: (), b3: ()} + ]); + + NillableBooleanMapArray|csv:Error bv7bnbma = csv:parseStringToRecord(csvStringWithBooleanValues7); + test:assertEquals(bv7bnbma, [ + {b1, b2, b3, b4} + ]); + + NillableIntUnionBooleanMapArray|csv:Error bv1bniubma = csv:parseStringToRecord(csvStringWithBooleanValues1); + test:assertEquals(bv1bniubma, [ + {b1: true, b2: false, b3: true, b4: false}, + {b1: true, b2: false, b3: true, b4: false}, + {b1: true, b2: false, b3: true, b4: false} + ]); + + NillableIntUnionBooleanMapArray|csv:Error bv2bniubma = csv:parseStringToRecord(csvStringWithBooleanValues2); + test:assertEquals(bv2bniubma, [ + {b1: true, b2: false, b3: true, b4: false, b5: true}, + {b1: true, b2: false, b3: true, b4: false, b5: true} + ]); + +} + +@test:Config +function testFromCsvStringWithTypeForStringAndMapAsExpectedType2() { + NillableIntUnionBooleanMapArray|csv:Error bv3bniubma = csv:parseStringToRecord(csvStringWithBooleanValues3); + test:assertEquals(bv3bniubma, [ + {b1: true, b2: false, b3: true}, + {b1: true, b2: false, b3: null}, + {b1: true, b2: true, b3: false} + ]); + + NillableIntUnionBooleanMapArray|csv:Error bv4bniubma = csv:parseStringToRecord(csvStringWithBooleanValues4); + test:assertEquals(bv4bniubma, [ + {b1: true, b2: (), b3: (), b4: false}, + {b1: true, b2: (), b3: (), b4: false} + ]); + + NillableIntUnionBooleanMapArray|csv:Error bv5bniubma = csv:parseStringToRecord(csvStringWithBooleanValues5); + test:assertEquals(bv5bniubma, [ + {b1: true, b2: false, b3: true, b4: 2}, + {b1: true, b2: false, b3: true, b4: 3} + ]); + + NillableIntUnionBooleanMapArray|csv:Error bv6bniubma = csv:parseStringToRecord(csvStringWithBooleanValues6); + test:assertEquals(bv6bniubma, [ + {b2: (), b3: ()} + ]); + + NillableIntUnionBooleanMapArray|csv:Error bv7bniubma = csv:parseStringToRecord(csvStringWithBooleanValues7); + test:assertEquals(bv7bniubma, [ + {b1, b2, b3, b4} + ]); + + IntUnionBooleanMapArray|csv:Error bv1biubma = csv:parseStringToRecord(csvStringWithBooleanValues1); + test:assertEquals(bv1biubma, [ + {b1: true, b2: false, b3: true, b4: false}, + {b1: true, b2: false, b3: true, b4: false}, + {b1: true, b2: false, b3: true, b4: false} + ]); + + IntUnionBooleanMapArray|csv:Error bv2biubma = csv:parseStringToRecord(csvStringWithBooleanValues2); + test:assertEquals(bv2biubma, [ + {b1: true, b2: false, b3: true, b4: false, b5: true}, + {b1: true, b2: false, b3: true, b4: false, b5: true} + ]); + + IntUnionBooleanMapArray|csv:Error bv3biubma = csv:parseStringToRecord(csvStringWithBooleanValues3); + test:assertEquals(bv3biubma, [ + {b1: true, b2: false, b3: true}, + {b1: true, b2: false}, + {b1: true, b2: true, b3: false} + ]); + + IntUnionBooleanMapArray|csv:Error bv4biubma = csv:parseStringToRecord(csvStringWithBooleanValues4); + test:assertEquals(bv4biubma, [ + {b1: true, b4: false}, + {b1: true, b4: false} + ]); + + IntUnionBooleanMapArray|csv:Error bv5biubma = csv:parseStringToRecord(csvStringWithBooleanValues5); + test:assertEquals(bv5biubma, [ + {b1: true, b2: false, b3: true, b4: 2}, + {b1: true, b2: false, b3: true, b4: 3} + ]); + + IntUnionBooleanMapArray|csv:Error bv6biubma = csv:parseStringToRecord(csvStringWithBooleanValues6); + test:assertEquals(bv6biubma, [ + {} + ]); + + IntUnionBooleanMapArray|csv:Error bv7biubma = csv:parseStringToRecord(csvStringWithBooleanValues7); + test:assertEquals(bv7biubma, [ + {b1, b2, b4} + ]); + + NilMapArray|csv:Error bv1bnma = csv:parseStringToRecord(csvStringWithBooleanValues1); + test:assertEquals(bv1bnma, [ + {}, + {}, + {} + ]); + + NilMapArray|csv:Error bv2bnma = csv:parseStringToRecord(csvStringWithBooleanValues2); + test:assertEquals(bv2bnma, [ + {}, + {} + ]); + + NilMapArray|csv:Error bv3bnma = csv:parseStringToRecord(csvStringWithBooleanValues3); + test:assertEquals(bv3bnma, [ + {}, + {b3: ()}, + {} + ]); + + NilMapArray|csv:Error bv4bnma = csv:parseStringToRecord(csvStringWithBooleanValues4); + test:assertEquals(bv4bnma, [ + {b2: (), b3: ()}, + {b2: (), b3: ()} + ]); + + NilMapArray|csv:Error bv5bnma = csv:parseStringToRecord(csvStringWithBooleanValues5); + test:assertEquals(bv5bnma, [ + {}, + {} + ]); +} + +@test:Config +function testFromCsvStringWithTypeForStringAndMapAsExpectedType3() { + NilMapArray|csv:Error bv6bnma = csv:parseStringToRecord(csvStringWithBooleanValues6); + test:assertEquals(bv6bnma, [ + {b2: (), b3: ()} + ]); + + NilMapArray|csv:Error bv7bnma = csv:parseStringToRecord(csvStringWithBooleanValues7); + test:assertEquals(bv7bnma, [ + {b3} + ]); + + JsonMapArray|csv:Error bv1bjma = csv:parseStringToRecord(csvStringWithBooleanValues1); + test:assertEquals(bv1bjma, [ + {b1: true, b2: false, b3: true, b4: false}, + {b1: true, b2: false, b3: true, b4: false}, + {b1: true, b2: false, b3: true, b4: false} + ]); + + JsonMapArray|csv:Error bv2bjma = csv:parseStringToRecord(csvStringWithBooleanValues2); + test:assertEquals(bv2bjma, [ + {b1: true, b2: false, b3: true, b4: false, b5: true}, + {b1: true, b2: false, b3: true, b4: false, b5: true} + ]); + + JsonMapArray|csv:Error bv3bjma = csv:parseStringToRecord(csvStringWithBooleanValues3); + test:assertEquals(bv3bjma, [ + {b1: true, b2: false, b3: true}, + {b1: true, b2: false, b3: null}, + {b1: true, b2: true, b3: false} + ]); + + JsonMapArray|csv:Error bv4bjma = csv:parseStringToRecord(csvStringWithBooleanValues4); + test:assertEquals(bv4bjma, [ + {b1: true, b2: (), b3: (), b4: false}, + {b1: true, b2: (), b3: (), b4: false} + ]); + + JsonMapArray|csv:Error bv5bjma = csv:parseStringToRecord(csvStringWithBooleanValues5); + test:assertEquals(bv5bjma, [ + {b1: true, b2: false, b3: true, b4: 2}, + {b1: true, b2: false, b3: true, b4: 3} + ]); + + JsonMapArray|csv:Error bv6bjma = csv:parseStringToRecord(csvStringWithBooleanValues6); + test:assertEquals(bv6bjma, [ + {b2: (), b3: ()} + ]); + + JsonMapArray|csv:Error bv7bjma = csv:parseStringToRecord(csvStringWithBooleanValues7); + test:assertEquals(bv7bjma, [ + {b1, b2, b3, b4} + ]); + + AnydataMapArray|csv:Error bv1banydma = csv:parseStringToRecord(csvStringWithBooleanValues1); + test:assertEquals(bv1banydma, [ + {b1: true, b2: false, b3: true, b4: false}, + {b1: true, b2: false, b3: true, b4: false}, + {b1: true, b2: false, b3: true, b4: false} + ]); + + AnydataMapArray|csv:Error bv2banydma = csv:parseStringToRecord(csvStringWithBooleanValues2); + test:assertEquals(bv2banydma, [ + {b1: true, b2: false, b3: true, b4: false, b5: true}, + {b1: true, b2: false, b3: true, b4: false, b5: true} + ]); + + AnydataMapArray|csv:Error bv3banydma = csv:parseStringToRecord(csvStringWithBooleanValues3); + test:assertEquals(bv3banydma, [ + {b1: true, b2: false, b3: true}, + {b1: true, b2: false, b3: null}, + {b1: true, b2: true, b3: false} + ]); + + AnydataMapArray|csv:Error bv4banydma = csv:parseStringToRecord(csvStringWithBooleanValues4); + test:assertEquals(bv4banydma, [ + {b1: true, b2: (), b3: (), b4: false}, + {b1: true, b2: (), b3: (), b4: false} + ]); + + AnydataMapArray|csv:Error bv5banydma = csv:parseStringToRecord(csvStringWithBooleanValues5); + test:assertEquals(bv5banydma, [ + {b1: true, b2: false, b3: true, b4: 2}, + {b1: true, b2: false, b3: true, b4: 3} + ]); + + AnydataMapArray|csv:Error bv6banydma = csv:parseStringToRecord(csvStringWithBooleanValues6); + test:assertEquals(bv6banydma, [ + {b2: (), b3: ()} + ]); + + AnydataMapArray|csv:Error bv7banydma = csv:parseStringToRecord(csvStringWithBooleanValues7); + test:assertEquals(bv7banydma, [ + {b1, b2, b3, b4} + ]); + + CustomMapArray|csv:Error bv1bcma = csv:parseStringToRecord(csvStringWithBooleanValues1); + test:assertEquals(bv1bcma, [ + {b1: "true", b2: "false", b3: "true", b4: "false"}, + {b1: "true", b2: "false", b3: "true", b4: "false"}, + {b1: "true", b2: "false", b3: "true", b4: "false"} + ]); +} + +@test:Config +function testFromCsvStringWithTypeForStringAndMapAsExpectedType4() { + CustomMapArray|csv:Error bv2bcma = csv:parseStringToRecord(csvStringWithBooleanValues2); + test:assertEquals(bv2bcma, [ + {b1: "true", b2: "false", b3: "true", b4: "false", b5: "true"}, + {b1: "true", b2: "false", b3: "true", b4: "false", b5: "true"} + ]); + + CustomMapArray|csv:Error bv3bcma = csv:parseStringToRecord(csvStringWithBooleanValues3); + test:assertEquals(bv3bcma, [ + {b1: "true", b2: "false", b3: "true"}, + {b1: "TRUE", b2: "FALSE", b3: "()"}, + {b1: "true", b2: "true", b3: "FALSE"} + ]); + + CustomMapArray|csv:Error bv4bcma = csv:parseStringToRecord(csvStringWithBooleanValues4); + test:assertEquals(bv4bcma, [ + {b1: "true", b2: "()", b3: "()", b4: "false"}, + {b1: "true", b2: "()", b3: "null", b4: "false"} + ]); + + CustomMapArray|csv:Error bv5bcma = csv:parseStringToRecord(csvStringWithBooleanValues5); + test:assertEquals(bv5bcma, [ + {b1: "true", b2: "false", b3: "true", b4: 2}, + {b1: "true", b2: "false", b3: "true", b4: 3} + ]); + + CustomMapArray|csv:Error bv6bcma = csv:parseStringToRecord(csvStringWithBooleanValues6); + test:assertEquals(bv6bcma, [ + {b2: "()", b3: "()"} + ]); + + CustomMapArray|csv:Error bv7bcma = csv:parseStringToRecord(csvStringWithBooleanValues7); + test:assertEquals(bv7bcma, [ + {b1: "true", b2: "false", b3: "()", b4: "false"} + ]); + + StringMapArray|csv:Error bv1bsma = csv:parseStringToRecord(csvStringWithBooleanValues1); + test:assertEquals(bv1bsma, [ + {b1: "true", b2: "false", b3: "true", b4: "false"}, + {b1: "true", b2: "false", b3: "true", b4: "false"}, + {b1: "true", b2: "false", b3: "true", b4: "false"} + ]); + + StringMapArray|csv:Error bv2bsma = csv:parseStringToRecord(csvStringWithBooleanValues2); + test:assertEquals(bv2bsma, [ + {b1: "true", b2: "false", b3: "true", b4: "false", b5: "true"}, + {b1: "true", b2: "false", b3: "true", b4: "false", b5: "true"} + ]); + + StringMapArray|csv:Error bv3bsma = csv:parseStringToRecord(csvStringWithBooleanValues3); + test:assertEquals(bv3bsma, [ + {b1: "true", b2: "false", b3: "true"}, + {b1: "TRUE", b2: "FALSE", b3: "()"}, + {b1: "true", b2: "true", b3: "FALSE"} + ]); + + StringMapArray|csv:Error bv4bsma = csv:parseStringToRecord(csvStringWithBooleanValues4); + test:assertEquals(bv4bsma, [ + {b1: "true", b2: "()", b3: "()", b4: "false"}, + {b1: "true", b2: "()", b3: "null", b4: "false"} + ]); + + StringMapArray|csv:Error bv5bsma = csv:parseStringToRecord(csvStringWithBooleanValues5); + test:assertEquals(bv5bsma, [ + {b1: "true", b2: "false", b3: "true", b4: "2"}, + {b1: "true", b2: "false", b3: "true", b4: "3"} + ]); + + StringMapArray|csv:Error bv6bsma = csv:parseStringToRecord(csvStringWithBooleanValues6); + test:assertEquals(bv6bsma, [ + {b2: "()", b3: "()"} + ]); + + StringMapArray|csv:Error bv7bsma = csv:parseStringToRecord(csvStringWithBooleanValues7); + test:assertEquals(bv7bsma, [ + {b1: "true", b2: "false", b3: "()", b4: "false"} + ]); + + DecimalMapArray|csv:Error bv1dsma = csv:parseStringToRecord(csvStringWithBooleanValues1); + test:assertEquals(bv1dsma, [ + {}, + {}, + {} + ]); + DecimalMapArray|csv:Error bv6dsma = csv:parseStringToRecord(csvStringWithBooleanValues6); + test:assertEquals(bv6dsma, [ + {} + ]); + + DecimalMapArray|csv:Error bv7dsma = csv:parseStringToRecord(csvStringWithBooleanValues7); + test:assertEquals(bv7dsma, [ + {} + ]); +} diff --git a/ballerina-tests/parse-string-record-types-tests/tests/parse_string_to_record_tests.bal b/ballerina-tests/parse-string-record-types-tests/tests/parse_string_to_record_tests.bal new file mode 100644 index 0000000..2383f72 --- /dev/null +++ b/ballerina-tests/parse-string-record-types-tests/tests/parse_string_to_record_tests.bal @@ -0,0 +1,496 @@ +import ballerina/csv_commons as common; +import ballerina/data.csv as csv; +import ballerina/test; + +@test:Config +function testFromCsvStringWithTypeForStringAndRecordAsExpectedType() { + BooleanRecord1Array|csv:Error csvb1br1 = csv:parseStringToRecord(csvStringWithBooleanValues1, {}); + test:assertEquals(csvb1br1, [ + {b1: true, b2: false, b3: true, b4: false}, + {b1: true, b2: false, b3: true, b4: false}, + {b1: true, b2: false, b3: true, b4: false} + ]); + + BooleanRecord1Array|csv:Error csvb2br1 = csv:parseStringToRecord(csvStringWithBooleanValues2, {}); + test:assertEquals(csvb2br1, [ + {b1: true, b2: false, b3: true, b4: false, b5: true}, + {b1: true, b2: false, b3: true, b4: false, b5: true} + ]); + + BooleanRecord1Array|csv:Error csvb3br1 = csv:parseStringToRecord(csvStringWithBooleanValues3, {}); + test:assertTrue(csvb3br1 is csv:Error); + test:assertEquals((csvb3br1).message(), common:generateErrorMessageForMissingRequiredField("b4")); + + BooleanRecord1Array|csv:Error csvb4br1 = csv:parseStringToRecord(csvStringWithBooleanValues4, {}); + test:assertEquals(csvb4br1, [ + {b1: true, b2: "()", b3: (), b4: false}, + {b1: true, b2: "()", b3: (), b4: false} + ]); + + BooleanRecord1Array|csv:Error csvb5br1 = csv:parseStringToRecord(csvStringWithBooleanValues5, {}); + test:assertTrue(csvb5br1 is csv:Error); + test:assertEquals((csvb5br1).message(), common:generateErrorMessageForInvalidCast("2", "boolean")); + + BooleanRecord1Array|csv:Error csvb6br1 = csv:parseStringToRecord(csvStringWithBooleanValues6, {}); + test:assertTrue(csvb6br1 is csv:Error); + test:assertEquals((csvb6br1).message(), common:generateErrorMessageForMissingRequiredField("b4")); + + BooleanRecord1Array|csv:Error csvb7br1 = csv:parseStringToRecord(csvStringWithBooleanValues7, {}); + test:assertEquals(csvb7br1, [ + {b1, b2, b3: (), b4} + ]); + + BooleanRecord2Array|csv:Error csvb1br2 = csv:parseStringToRecord(csvStringWithBooleanValues1, {}); + test:assertEquals(csvb1br2, [ + {b1: true, b2: false, b3: true, b4: false}, + {b1: true, b2: false, b3: true, b4: false}, + {b1: true, b2: false, b3: true, b4: false} + ]); + + BooleanRecord2Array|csv:Error csvb2br2 = csv:parseStringToRecord(csvStringWithBooleanValues2, {}); + test:assertEquals(csvb2br2, [ + {b1: true, b2: false, b3: true, b4: false}, + {b1: true, b2: false, b3: true, b4: false} + ]); + + BooleanRecord2Array|csv:Error csvb3br2 = csv:parseStringToRecord(csvStringWithBooleanValues3, {}); + test:assertTrue(csvb3br2 is csv:Error); + test:assertEquals((csvb3br2).message(), common:generateErrorMessageForMissingRequiredField("b4")); + + BooleanRecord2Array|csv:Error csvb4br2 = csv:parseStringToRecord(csvStringWithBooleanValues4, {}); + test:assertEquals(csvb4br2, [ + {b1: true, b2: "()", b3: (), b4: false}, + {b1: true, b2: "()", b3: (), b4: false} + ]); + + BooleanRecord2Array|csv:Error csvb5br2 = csv:parseStringToRecord(csvStringWithBooleanValues5, {}); + test:assertTrue(csvb5br2 is csv:Error); + test:assertEquals((csvb5br2).message(), common:generateErrorMessageForInvalidCast("2", "boolean")); + + BooleanRecord2Array|csv:Error csvb7br2 = csv:parseStringToRecord(csvStringWithBooleanValues7, {}); + test:assertEquals(csvb7br2, [ + {b1, b2, b3: (), b4} + ]); + + BooleanRecord3Array|csv:Error csvb1br3 = csv:parseStringToRecord(csvStringWithBooleanValues1, {}); + test:assertEquals(csvb1br3, [ + {b1: true, b3: true}, + {b1: true, b3: true}, + {b1: true, b3: true} + ]); + + BooleanRecord3Array|csv:Error csvb2br3 = csv:parseStringToRecord(csvStringWithBooleanValues2, {}); + test:assertEquals(csvb2br3, [ + {b1: true, b3: true}, + {b1: true, b3: true} + ]); + + BooleanRecord3Array|csv:Error csvb3br3 = csv:parseStringToRecord(csvStringWithBooleanValues3, {}); + test:assertEquals(csvb3br3, [ + {b1: true, b3: true}, + {b1: true, b3: ()}, + {b1: true, b3: false} + ]); + + BooleanRecord3Array|csv:Error csvb4br3 = csv:parseStringToRecord(csvStringWithBooleanValues4, {}); + test:assertEquals(csvb4br3, [ + {b1: true, b3: ()}, + {b1: true, b3: ()} + ]); + + BooleanRecord3Array|csv:Error csvb5br3 = csv:parseStringToRecord(csvStringWithBooleanValues5, {}); + test:assertEquals(csvb5br3, [ + {b1: true, b3: true}, + {b1: true, b3: true} + ]); +} + +@test:Config +function testFromCsvStringWithTypeForStringAndRecordAsExpectedType2() { + BooleanRecord3Array|csv:Error csvb7br3 = csv:parseStringToRecord(csvStringWithBooleanValues7, {}); + test:assertEquals(csvb7br3, [ + {b1, b3: ()} + ]); + + BooleanRecord4Array|csv:Error csvb1br4 = csv:parseStringToRecord(csvStringWithBooleanValues1, {}); + test:assertEquals(csvb1br4, [ + {b1: true, b2: false, b3: true, b4: false}, + {b1: true, b2: false, b3: true, b4: false}, + {b1: true, b2: false, b3: true, b4: false} + ]); + + BooleanRecord4Array|csv:Error csvb2br4 = csv:parseStringToRecord(csvStringWithBooleanValues2, {}); + test:assertEquals(csvb2br4, [ + {b1: true, b2: false, b3: true, b4: false, b5: true}, + {b1: true, b2: false, b3: true, b4: false, b5: true} + ]); + + BooleanRecord4Array|csv:Error csvb3br4 = csv:parseStringToRecord(csvStringWithBooleanValues3, {}); + test:assertEquals(csvb3br4, [ + {b1: true, b2: false, b3: true}, + {b1: true, b2: false, b3: ()}, + {b1: true, b2: true, b3: false} + ]); + + BooleanRecord4Array|csv:Error csvb4br4 = csv:parseStringToRecord(csvStringWithBooleanValues4, {}); + test:assertEquals(csvb4br4, [ + {b1: true, b2: (), b3: (), b4: false}, + {b1: true, b2: (), b3: (), b4: false} + ]); + + BooleanRecord4Array|csv:Error csvb5br4 = csv:parseStringToRecord(csvStringWithBooleanValues5, {}); + test:assertEquals(csvb5br4, [ + {b1: true, b2: false, b3: true, b4: 2}, + {b1: true, b2: false, b3: true, b4: 3} + ]); + + BooleanRecord4Array|csv:Error csvb7br4 = csv:parseStringToRecord(csvStringWithBooleanValues7, {}); + test:assertEquals(csvb7br4, [ + {b1, b2, b3: (), b4} + ]); + + BooleanRecord5Array|csv:Error csvb1br5 = csv:parseStringToRecord(csvStringWithBooleanValues1, {}); + test:assertEquals(csvb1br5, [ + {b1: true, b2: false, b3: true, b4: false, defaultableField: "", nillableField: ()}, + {b1: true, b2: false, b3: true, b4: false, defaultableField: "", nillableField: ()}, + {b1: true, b2: false, b3: true, b4: false, defaultableField: "", nillableField: ()} + ]); + + BooleanRecord5Array|csv:Error csvb2br5 = csv:parseStringToRecord(csvStringWithBooleanValues2, {}); + test:assertEquals(csvb2br5, [ + {b1: true, b2: false, b3: true, b4: false, b5: true, defaultableField: "", nillableField: ()}, + {b1: true, b2: false, b3: true, b4: false, b5: true, defaultableField: "", nillableField: ()} + ]); + + BooleanRecord5Array|csv:Error csvb3br5 = csv:parseStringToRecord(csvStringWithBooleanValues3, {}); + test:assertEquals(csvb3br5, [ + {b1: true, b2: false, b3: true, defaultableField: "", nillableField: ()}, + {b1: true, b2: false, b3: (), defaultableField: "", nillableField: ()}, + {b1: true, b2: true, b3: false, defaultableField: "", nillableField: ()} + ]); + + BooleanRecord5Array|csv:Error csvb4br5 = csv:parseStringToRecord(csvStringWithBooleanValues4, {}); + test:assertEquals(csvb4br5, [ + {b1: true, b2: (), b3: (), b4: false, defaultableField: "", nillableField: ()}, + {b1: true, b2: (), b3: (), b4: false, defaultableField: "", nillableField: ()} + ]); + + BooleanRecord5Array|csv:Error csvb5br5 = csv:parseStringToRecord(csvStringWithBooleanValues5, {}); + test:assertEquals(csvb5br5, [ + {b1: true, b2: false, b3: true, b4: 2, defaultableField: "", nillableField: ()}, + {b1: true, b2: false, b3: true, b4: 3, defaultableField: "", nillableField: ()} + ]); + + BooleanRecord5Array|csv:Error csvb7br5 = csv:parseStringToRecord(csvStringWithBooleanValues7, {}); + test:assertEquals(csvb7br5, [ + {b1, b2, b3: (), b4, defaultableField: "", nillableField: ()} + ]); + + BooleanRecord6Array|csv:Error csvb1br6 = csv:parseStringToRecord(csvStringWithBooleanValues1, {}); + test:assertEquals(csvb1br6, [ + {b1: true, b3: true, defaultableField: "", nillableField: ()}, + {b1: true, b3: true, defaultableField: "", nillableField: ()}, + {b1: true, b3: true, defaultableField: "", nillableField: ()} + ]); + + BooleanRecord6Array|csv:Error csvb2br6 = csv:parseStringToRecord(csvStringWithBooleanValues2, {}); + test:assertEquals(csvb2br6, [ + {b1: true, b3: true, defaultableField: "", nillableField: ()}, + {b1: true, b3: true, defaultableField: "", nillableField: ()} + ]); + + BooleanRecord6Array|csv:Error csvb3br6 = csv:parseStringToRecord(csvStringWithBooleanValues3, {}); + test:assertEquals(csvb3br6, [ + {b1: true, b3: true, defaultableField: "", nillableField: ()}, + {b1: true, b3: (), defaultableField: "", nillableField: ()}, + {b1: true, b3: false, defaultableField: "", nillableField: ()} + ]); +} + +@test:Config +function testFromCsvStringWithTypeForStringAndRecordAsExpectedType3() { + BooleanRecord6Array|csv:Error csvb4br6 = csv:parseStringToRecord(csvStringWithBooleanValues4, {}); + test:assertEquals(csvb4br6, [ + {b1: true, b3: (), defaultableField: "", nillableField: ()}, + {b1: true, b3: (), defaultableField: "", nillableField: ()} + ]); + + BooleanRecord6Array|csv:Error csvb5br6 = csv:parseStringToRecord(csvStringWithBooleanValues5, {}); + test:assertEquals(csvb5br6, [ + {b1: true, b3: true, defaultableField: "", nillableField: ()}, + {b1: true, b3: true, defaultableField: "", nillableField: ()} + ]); + + BooleanRecord6Array|csv:Error csvb7br6 = csv:parseStringToRecord(csvStringWithBooleanValues7, {}); + test:assertEquals(csvb7br6, [ + {b1, b3: (), defaultableField: "", nillableField: ()} + ]); + + BooleanRecord7Array|csv:Error csvb1br7 = csv:parseStringToRecord(csvStringWithBooleanValues1, {}); + test:assertTrue(csvb1br7 is csv:Error); + test:assertEquals((csvb1br7).message(), common:generateErrorMessageForMissingRequiredField("requiredField")); + + BooleanRecord8Array|csv:Error csvb1br8 = csv:parseStringToRecord(csvStringWithBooleanValues1, {}); + test:assertTrue(csvb1br8 is csv:Error); + test:assertEquals((csvb1br8).message(), common:generateErrorMessageForMissingRequiredField("requiredField")); + + BooleanRecord9Array|csv:Error csvb1br9 = csv:parseStringToRecord(csvStringWithBooleanValues1, {}); + test:assertEquals(csvb1br9, [ + {b1: true, b2: false, b3: true, b4: false}, + {b1: true, b2: false, b3: true, b4: false}, + {b1: true, b2: false, b3: true, b4: false} + ]); + + BooleanRecord9Array|csv:Error csvb2br9 = csv:parseStringToRecord(csvStringWithBooleanValues2, {}); + test:assertEquals(csvb2br9, [ + {b1: true, b2: false, b3: true, b4: false, b5: true}, + {b1: true, b2: false, b3: true, b4: false, b5: true} + ]); + + BooleanRecord9Array|csv:Error csvb3br9 = csv:parseStringToRecord(csvStringWithBooleanValues3, {}); + test:assertEquals(csvb3br9, [ + {b1: true, b2: false, b3: true}, + {b1: true, b2: false, b3: ()}, + {b1: true, b2: true, b3: false} + ]); + + BooleanRecord9Array|csv:Error csvb4br9 = csv:parseStringToRecord(csvStringWithBooleanValues4, {}); + test:assertEquals(csvb4br9, [ + {b1: true, b2: (), b3: (), b4: false}, + {b1: true, b2: (), b3: (), b4: false} + ]); + + BooleanRecord9Array|csv:Error csvb5br9 = csv:parseStringToRecord(csvStringWithBooleanValues5, {}); + test:assertEquals(csvb5br9, [ + {b1: true, b2: false, b3: true}, + {b1: true, b2: false, b3: true} + ]); + + BooleanRecord9Array|csv:Error csvb6br9 = csv:parseStringToRecord(csvStringWithBooleanValues6, {}); + test:assertTrue(csvb6br9 is csv:Error); + test:assertEquals((csvb6br9).message(), common:generateErrorMessageForMissingRequiredField("b1")); + + BooleanRecord9Array|csv:Error csvb7br9 = csv:parseStringToRecord(csvStringWithBooleanValues7, {}); + test:assertEquals(csvb7br9, [ + {b1, b2, b3: (), b4} + ]); + + BooleanRecord10Array|csv:Error csvb1br10 = csv:parseStringToRecord(csvStringWithBooleanValues1, {}); + test:assertEquals(csvb1br10, [ + {b1: true, b2: false, b3: true, b4: false}, + {b1: true, b2: false, b3: true, b4: false}, + {b1: true, b2: false, b3: true, b4: false} + ]); + + BooleanRecord10Array|csv:Error csvb2br10 = csv:parseStringToRecord(csvStringWithBooleanValues2, {}); + test:assertEquals(csvb2br10, [ + {b1: true, b2: false, b3: true, b4: false, b5: true}, + {b1: true, b2: false, b3: true, b4: false, b5: true} + ]); + + BooleanRecord10Array|csv:Error csvb3br10 = csv:parseStringToRecord(csvStringWithBooleanValues3, {}); + test:assertEquals(csvb3br10, [ + {b1: true, b2: false, b3: true}, + {b1: true, b2: false}, + {b1: true, b2: true, b3: false} + ]); + + BooleanRecord10Array|csv:Error csvb4br10 = csv:parseStringToRecord(csvStringWithBooleanValues4, {}); + test:assertEquals(csvb4br10, [ + {b1: true, b4: false}, + {b1: true, b4: false} + ]); + + BooleanRecord10Array|csv:Error csvb5br10 = csv:parseStringToRecord(csvStringWithBooleanValues5, {}); + test:assertEquals(csvb5br10, [ + {b1: true, b2: false, b3: true}, + {b1: true, b2: false, b3: true} + ]); + + BooleanRecord10Array|csv:Error csvb6br10 = csv:parseStringToRecord(csvStringWithBooleanValues6, {}); + test:assertEquals(csvb6br10, [ + {} + ]); + + BooleanRecord10Array|csv:Error csvb7br10 = csv:parseStringToRecord(csvStringWithBooleanValues7, {}); + test:assertEquals(csvb7br10, [ + {b1, b2, b4} + ]); + + BooleanRecord11Array|csv:Error csvb1br11 = csv:parseStringToRecord(csvStringWithBooleanValues1, {}); + test:assertEquals(csvb1br11, [ + {b1: true, b2: false, b3: true, b4: false, defaultableField: "", nillableField: ()}, + {b1: true, b2: false, b3: true, b4: false, defaultableField: "", nillableField: ()}, + {b1: true, b2: false, b3: true, b4: false, defaultableField: "", nillableField: ()} + ]); +} + +@test:Config +function testFromCsvStringWithTypeForStringAndRecordAsExpectedType4() { + BooleanRecord11Array|csv:Error csvb2br11 = csv:parseStringToRecord(csvStringWithBooleanValues2, {}); + test:assertEquals(csvb2br11, [ + {b1: true, b2: false, b3: true, b4: false, b5: true, defaultableField: "", nillableField: ()}, + {b1: true, b2: false, b3: true, b4: false, b5: true, defaultableField: "", nillableField: ()} + ]); + + BooleanRecord11Array|csv:Error csvb3br11 = csv:parseStringToRecord(csvStringWithBooleanValues3, {}); + test:assertEquals(csvb3br11, [ + {b1: true, b2: false, b3: true, defaultableField: "", nillableField: ()}, + {b1: true, b2: false, b3: (), defaultableField: "", nillableField: ()}, + {b1: true, b2: true, b3: false, defaultableField: "", nillableField: ()} + ]); + + BooleanRecord11Array|csv:Error csvb4br11 = csv:parseStringToRecord(csvStringWithBooleanValues4, {}); + test:assertEquals(csvb4br11, [ + {b1: true, b2: (), b3: (), b4: false, defaultableField: "", nillableField: ()}, + {b1: true, b2: (), b3: (), b4: false, defaultableField: "", nillableField: ()} + ]); + + BooleanRecord11Array|csv:Error csvb5br11 = csv:parseStringToRecord(csvStringWithBooleanValues5, {}); + test:assertEquals(csvb5br11, [ + {b1: true, b2: false, b3: true, b4: "2", defaultableField: "", nillableField: ()}, + {b1: true, b2: false, b3: true, b4: "3", defaultableField: "", nillableField: ()} + ]); + + BooleanRecord11Array|csv:Error csvb6br11 = csv:parseStringToRecord(csvStringWithBooleanValues6, {}); + test:assertTrue(csvb6br11 is csv:Error); + test:assertEquals((csvb6br11).message(), common:generateErrorMessageForMissingRequiredField("b1")); + + BooleanRecord11Array|csv:Error csvb7br11 = csv:parseStringToRecord(csvStringWithBooleanValues7, {}); + test:assertEquals(csvb7br11, [ + {b1, b2, b3, b4, defaultableField: "", nillableField: ()} + ]); + + BooleanRecord12Array|csv:Error csvb1br12 = csv:parseStringToRecord(csvStringWithBooleanValues1, {}); + test:assertTrue(csvb1br12 is csv:Error); + test:assertEquals((csvb1br12).message(), common:generateErrorMessageForMissingRequiredField("requiredField")); + + BooleanRecord13Array|csv:Error csvb1br13 = csv:parseStringToRecord(csvStringWithBooleanValues1, {}); + test:assertEquals(csvb1br13, [ + {b1: true, b2: false, b3: true, b4: false, defaultableField: "", nillableField: ()}, + {b1: true, b2: false, b3: true, b4: false, defaultableField: "", nillableField: ()}, + {b1: true, b2: false, b3: true, b4: false, defaultableField: "", nillableField: ()} + ]); + + BooleanRecord13Array|csv:Error csvb2br13 = csv:parseStringToRecord(csvStringWithBooleanValues2, {}); + test:assertEquals(csvb2br13, [ + {b1: true, b2: false, b3: true, b4: false, b5: true, defaultableField: "", nillableField: ()}, + {b1: true, b2: false, b3: true, b4: false, b5: true, defaultableField: "", nillableField: ()} + ]); + + BooleanRecord13Array|csv:Error csvb3br13 = csv:parseStringToRecord(csvStringWithBooleanValues3, {}); + test:assertEquals(csvb3br13, [ + {b1: true, b2: false, b3: true, defaultableField: "", nillableField: ()}, + {b1: true, b2: false, b3: "()", defaultableField: "", nillableField: ()}, + {b1: true, b2: true, b3: false, defaultableField: "", nillableField: ()} + ]); + + BooleanRecord13Array|csv:Error csvb4br13 = csv:parseStringToRecord(csvStringWithBooleanValues4, {}); + test:assertEquals(csvb4br13, [ + {b1: true, b2: "()", b3: "()", b4: false, defaultableField: "", nillableField: ()}, + {b1: true, b2: "()", b3: "null", b4: false, defaultableField: "", nillableField: ()} + ]); + + BooleanRecord13Array|csv:Error csvb5br13 = csv:parseStringToRecord(csvStringWithBooleanValues5, {}); + test:assertEquals(csvb5br13, [ + {b1: true, b2: false, b3: true, b4: "2", defaultableField: "", nillableField: ()}, + {b1: true, b2: false, b3: true, b4: "3", defaultableField: "", nillableField: ()} + ]); + + BooleanRecord13Array|csv:Error csvb6br13 = csv:parseStringToRecord(csvStringWithBooleanValues6, {}); + test:assertEquals(csvb6br13, [ + {b2: "()", b3: "()", defaultableField: "", nillableField: ()} + ]); + + BooleanRecord13Array|csv:Error csvb7br13 = csv:parseStringToRecord(csvStringWithBooleanValues7, {}); + test:assertEquals(csvb7br13, [ + {b1, b2, b3: "()", b4, defaultableField: "", nillableField: ()} + ]); + + BooleanRecord14Array|csv:Error csvb7br14 = csv:parseStringToRecord(csvStringWithBooleanValues6, {}); + test:assertTrue(csvb7br14 is csv:Error); + test:assertEquals((csvb7br14).message(), common:generateErrorMessageForMissingRequiredField("requiredField")); +} + +@test:Config +function testFromCsvStringWithTypeForStringAndRecordAsExpectedType5() { + BooleanRecord15Array|csv:Error csvb1br15 = csv:parseStringToRecord(csvStringWithBooleanValues1, {}); + test:assertTrue(csvb1br15 is csv:Error); + test:assertEquals((csvb1br15).message(), common:generateErrorMessageForInvalidCast("true", "int")); + + BooleanRecord15Array|csv:Error csvb6br15 = csv:parseStringToRecord(csvStringWithBooleanValues6, {}); + test:assertTrue(csvb6br15 is csv:Error); + test:assertEquals((csvb6br15).message(), common:generateErrorMessageForMissingRequiredField("b1")); + + BooleanRecord15Array|csv:Error csvb7br15 = csv:parseStringToRecord(csvStringWithBooleanValues7, {}); + test:assertTrue(csvb7br15 is csv:Error); + test:assertEquals((csvb7br15).message(), common:generateErrorMessageForInvalidCast("true", "int")); + + BooleanRecord16Array|csv:Error csvb1br16 = csv:parseStringToRecord(csvStringWithBooleanValues1, {}); + test:assertEquals(csvb1br16, [ + {b1: true, b2: false, b3: true, b4: false}, + {b1: true, b2: false, b3: true, b4: false}, + {b1: true, b2: false, b3: true, b4: false} + ]); + + BooleanRecord16Array|csv:Error csvb2br16 = csv:parseStringToRecord(csvStringWithBooleanValues2, {}); + test:assertEquals(csvb2br16, [ + {b1: true, b2: false, b3: true, b4: false, b5: true}, + {b1: true, b2: false, b3: true, b4: false, b5: true} + ]); + + BooleanRecord16Array|csv:Error csvb3br16 = csv:parseStringToRecord(csvStringWithBooleanValues3, {}); + test:assertEquals(csvb3br16, [ + {b1: true, b2: false, b3: true}, + {b1: true, b2: false, b3: ()}, + {b1: true, b2: true, b3: false} + ]); + + BooleanRecord16Array|csv:Error csvb4br16 = csv:parseStringToRecord(csvStringWithBooleanValues4, {}); + test:assertEquals(csvb4br16, [ + {b1: true, b2: (), b3: (), b4: false}, + {b1: true, b2: (), b3: (), b4: false} + ]); + + BooleanRecord16Array|csv:Error csvb5br16 = csv:parseStringToRecord(csvStringWithBooleanValues5, {}); + test:assertEquals(csvb5br16, [ + {b1: true, b2: false, b3: true}, + {b1: true, b2: false, b3: true} + ]); + + BooleanRecord16Array|csv:Error csvb6br16 = csv:parseStringToRecord(csvStringWithBooleanValues6, {}); + test:assertEquals(csvb6br16, [ + {b2: (), b3: ()} + ]); + + BooleanRecord16Array|csv:Error csvb7br16 = csv:parseStringToRecord(csvStringWithBooleanValues7, {}); + test:assertEquals(csvb7br16, [ + {b1, b2, b3: (), b4} + ]); + + BooleanRecord17Array|csv:Error csvb1br17 = csv:parseStringToRecord(csvStringWithBooleanValues1, {}); + test:assertEquals(csvb1br17, [{}, {}, {}]); + + BooleanRecord17Array|csv:Error csvb4br17 = csv:parseStringToRecord(csvStringWithBooleanValues4, {}); + test:assertEquals(csvb4br17, [{}, {}]); + + BooleanRecord17Array|csv:Error csvb6br17 = csv:parseStringToRecord(csvStringWithBooleanValues6, {}); + test:assertEquals(csvb6br17, [{}]); + + BooleanRecord17Array|csv:Error csvb7br17 = csv:parseStringToRecord(csvStringWithBooleanValues7, {}); + test:assertEquals(csvb7br17, [{}]); + + BooleanRecord18Array|csv:Error csvb1br18 = csv:parseStringToRecord(csvStringWithBooleanValues1, {}); + test:assertEquals(csvb1br18, [{b2: false}, {b2: false}, {b2: false}]); + + BooleanRecord18Array|csv:Error csvb4br18 = csv:parseStringToRecord(csvStringWithBooleanValues4, {}); + test:assertTrue(csvb4br18 is csv:Error); + test:assertEquals((csvb4br18).message(), common:generateErrorMessageForInvalidCast("()", "boolean")); + + BooleanRecord18Array|csv:Error csvb6br18 = csv:parseStringToRecord(csvStringWithBooleanValues6, {}); + test:assertTrue(csvb6br18 is csv:Error); + test:assertEquals((csvb6br18).message(), common:generateErrorMessageForInvalidCast("()", "boolean")); + + BooleanRecord18Array|csv:Error csvb7br18 = csv:parseStringToRecord(csvStringWithBooleanValues7, {}); + test:assertEquals(csvb7br18, [{b2, b3: ()}]); +} diff --git a/ballerina-tests/parse-string-record-types-tests/tests/test_data_values.bal b/ballerina-tests/parse-string-record-types-tests/tests/test_data_values.bal new file mode 100644 index 0000000..360a493 --- /dev/null +++ b/ballerina-tests/parse-string-record-types-tests/tests/test_data_values.bal @@ -0,0 +1,256 @@ +boolean b1 = true; +false b2 = false; +boolean? b3 = (); +boolean|int b4 = false; + +() n1 = (); +int? n2 = (); +() n3 = null; + +int i1 = 1; +int i2 = -2; +int i3 = int:MAX_VALUE; +int i4 = int:MIN_VALUE; +int i5 = 0; +2 i6 = 2; +int? i7 = (); +int|string i8 = 100; + +float f1 = 2.234; +float f2 = -3.21f; +float f3 = 0; +float f4 = float:Infinity; +float f5 = -float:Infinity; +float f6 = float:NaN; +2.3f f7 = 2.3; +float? f8 = (); +float|decimal f9 = 1.21; + +decimal d1 = 2.234; +decimal d2 = -3.21d; +decimal d3 = 0; +2.3d d4 = 2.3; +decimal? d5 = (); +decimal|int d6 = 1.21; + +string s1 = "string"; +string s2 = ""; +string:Char s3 = "a"; + +map bm1 = {b1, b2}; +map bm2 = {b1, b2, b3, n1, n3}; +map bm3 = {b1, b2, b3, b4, i1}; +map<()> bm4 = {n1, n3}; +map bm5 = {b1, b2, b3, b4:true}; + +map m5 = {i1, i2, i3, i4, i5, i6}; +map m6 = {f1, f2, f3, f4, f5, f6, f7}; +map m7 = {d1, d2, d3, d4}; +map m8 = {d1, f1, f9, f10: 1.23}; +map m9 = {s1, s2, s3}; +map m10 = {b1, b2, b3, b4, n1, n2, n3, i1, i2, i3, i4, i5, i6, i7, i8, f1, f2, f3, f4, f5, f6, f7, f8}; +map m11 = {b1, b2, b3, b4, n1, n2, n3, i1, i2, i3, i4, i5, i6, i7, i8, f1, f2, f3, f4, f5, f6, f7, f8}; + +boolean[] arr1 = [b1, b2]; +boolean?[] arr2 = [b1, b2, b3, n1, n3]; +(boolean|int?)[] arr3 = [b1, b2, b3, b4, i1]; +()[] arr4 = [n1, n3]; +int[] arr5 = [i1, i2, i3, i4, i5, i6]; +float[] arr6 = [f1, f2, f3, f4, f5, f6, f7]; +decimal[] arr7 = [d1, d2, d3, d4]; +(decimal|float)[] arr8 = [d1, f1, f9, 1.23]; +string[] arr9 = [s1, s2, s3]; +anydata[] arr10 = [b1, b2, b3, b4, n1, n2, n3, i1, i2, i3, i4, i5, i6, i7, i8, f1, f2, f3, f4, f5, f6, f7, f8]; +json[] arr11 = [b1, b2, b3, b4, n1, n2, n3, i1, i2, i3, i4, i5, i6, i7, i8, f1, f2, f3, f4, f5, f6, f7, f8]; + +[boolean, boolean] bt1 = [b1, b2]; +[boolean, boolean, boolean, boolean] bt2 = [b1, b2, b1, b2]; +[boolean?, boolean?, boolean?, boolean?, boolean?] bt3 = [b1, b2, b3, n1, n3]; +[boolean|int?, boolean|int?, boolean|int?, boolean|int?, boolean|int?] bt4 = [b1, b2, b3, b4, i1]; +[boolean...] bt5 = [b1, b2]; + +[string, string] st1 = [s1, s2]; +[string, string, string, string] st2 = [s1, s2, s3, s2]; +[string...] st3 = [s1, s2]; +[string, string, string...] st4 = [s1, s2, s3, s2]; + +[string?, string?, string?, string?, string?] st5 = [s1, s2, s3, n1, n3]; +[string|int?, string|int?, string|int?, string|int?, string|int?] st6 = [s1, s2, s3, n1, i1]; +[string?...] st7 = [s1, s2]; +[string...] st8 = []; +[string, string, string] st9 = [s1, s2, s3]; + +[(), ()] tup4 = [n1, n3]; +[int, int, int, int, int, int] tup5 = [i1, i2, i3, i4, i5, i6]; +[float, float, float, float, float, float, float] tup6 = [f1, f2, f3, f4, f5, f6, f7]; +[decimal, decimal, decimal, decimal] tup7 = [d1, d2, d3, d4]; +[decimal|float, decimal|float, decimal|float, decimal|float] tup8 = [d1, f1, f9, 1.23]; +[string, string, string] tup9 = [s1, s2, s3]; +[anydata, anydata, anydata, anydata, anydata, anydata, anydata, anydata, + anydata, anydata, anydata, anydata, anydata, anydata, anydata, anydata, + anydata, anydata, anydata, anydata, anydata, anydata, anydata] tup10 = [b1, b2, b3, b4, + n1, n2, n3, i1, i2, i3, i4, i5, i6, i7, i8, f1, f2, f3, f4, f5, f6, f7, f8]; +[json, json, json, json, json, json, json, json, json, json, json, json, + json, json, json, json, json, json, json, json, json, json, json] tup11 = + [b1, b2, b3, b4, n1, n2, n3, i1, i2, i3, i4, i5, i6, i7, i8, f1, + f2, f3, f4, f5, f6, f7, f8]; +[string, string, int, int, boolean, boolean, (), (), decimal, decimal, float, float] tup12 = [ + s1, s2, i1, i2, b1, b2, n1, n3, d1, d2, f1, f2 +]; + +[boolean, boolean...] restTup1 = [b1, b2]; +[boolean?, boolean?, boolean?...] restTup2 = [b1, b2, b3, n1, n3]; +[boolean|int?...] restTup3 = [b1, b2, b3, b4, i1]; +[(), ()...] restTup4 = [n1, n3]; +[int...] restTup5 = [i1, i2, i3, i4, i5, i6]; +[float...] restTup6 = [f1, f2, f3, f4, f5, f6, f7]; +[decimal...] restTup7 = [d1, d2, d3, d4]; +[decimal|float, decimal|float...] restTup8 = [d1, f1, f9, 1.23]; +[string...] restTup9 = [s1, s2, s3]; +[anydata...] restTup10 = [b1, b2, b3, b4, n1, n2, n3, i1, i2, i3, i4, i5, i6, i7, i8, f1, f2, f3, f4, f5, f6, f7, f8]; +[json, json, json...] restTup11 = [b1, b2, b3, b4, n1, n2, n3, i1, i2, i3, i4, i5, i6, i7, i8, f1, f2, f3, f4, f5, f6, f7, f8]; +[string, string, int, int, boolean, boolean, (), (), decimal, decimal, float, float...] restTup12 = [ + s1, s2, i1, i2, b1, b2, n1, n3, d1, d2, f1, f2, f2, f2 +]; + +var booleanRecordArray = [ + {b1, b2, b3, b4}, {b1, b2, b3, b4} +]; + +var booleanRecordArray2 = [ + {},{} +]; + +string csvStringWithBooleanValues1 = string `b1,b2,b3,b4 +true,false,true,false +true,false, true,false +true,false,true,false +`; + +string csvStringWithBooleanValues2 = string `b1,b2,b3,b4,b5 +true,false, true,false,true +true,false, true,false,true`; + +string csvStringWithBooleanValues3 = string `b1,b2,b3 +${" "}${"\t"} +true, false,true +${" "} + TRUE, FALSE,() +${" "} + +true, true,FALSE + +`; + +string csvStringWithBooleanValues4 = string `b1,b2,b3,b4 + true,(), (),false + true,(), null,false + +`; + +string csvStringWithBooleanValues5 = string `b1,b2,b3,b4 + +true,false,true,2 + +true,false,true,3 +`; + +string csvStringWithBooleanValues6 = string `b2,b3 +(),() + +`; + +string csvStringWithBooleanValues7 = string `b1,b2,b3,b4 +${b1},${b2},(),${b4} +`; + +string csvStringData1 = string ` + a, b, c, d, e, f + 1, string1, true, 2.234, 2.234, () + 2, string2, false, 0, 0, null + 3, string3, false, 1.23, 1.23, () + 4, string4, true, -6.51, -6.51, () + 5, string5, true, 3, 3, ()`; + +string csvStringData2 = string ` + hello, hello, (), 12, true, 12.34 + // comment + + a, b, c, d, e, f + + + 1, string1, true, 2.234, 2.234, () + 2, string2, false, 0, 0, null + 3, string3, false, 1.23, 1.23, () + 4, string4, true, -6.51, -6.51, () + 5, string5, true, 3, 3, ()`; + +string csvStringData3 = string ` + a, b, c, d, e, f + + + + 1, string1, true, 2.234, 2.234, () + 2, string2, false, 0, 0, null + 3, string3, false, 1.23, 1.23, () + + 4, string4, true, -6.51, -6.51, () + 5, string5, true, 3, 3, ()`; + +string csvStringData4 = string ` + 1, string1, true, 2.234, 2.234, () + 2, string2, false, 0, 0, null + 3, string3, false, 1.23, 1.23, () + 4, string4, true, -6.51, -6.51, () + 5, string5, true, 3, 3, ()`; + +string csvStringData5 = string ` + + + + 1, string1, true, 2.234, 2.234, () + 2, string2, false, 0, 0, null + + 3, string3, false, 1.23, 1.23, () + 4, string4, true, -6.51, -6.51, () + + 5, string5, true, 3, 3, ()`; + +string csvStringData6 = string ` + + 1, string1, true, 2.234, 2.234, () + 2, string2, false, 0, 0, null + + 3, string3, false, 1.23, 1.23, () + 4, string4, true, -6.51, -6.51, () + + 5, string5, true, 3, 3, ()`; + +string csvStringData7 = string ` + a@ b@ c@ d@ e@ f + 1@ string@ true@ 2.234@ -3.21@ () + 2@ s,tring@ true@ 2.234@ -3.21@ null + 3@ stri,ng@ true@ 2.234@ -3.21@ () + 4@ string@ true@ 2.234@ -3.21@ () + 5@ string@ true@ 2.234@ -3.21@ ()`; +string csvStringData8 = string ` + a@ b@ c@ d@ e@ f + + + + 1@ stri,ng@ true@ 2.234@ -3.21@ () + 2@ string@ true@ 2.234@ ()@-3.21 + 3@ string@ true@ 2.234@ -3.21@ null + + 4@ s,tring@ true@ 2.234@ -3.21@ () + 5@ string@ true@ 2.234@ -3.21@ ()`; + +string csvStringData9 = string ` + + 1@ string@ true@ 2.234@ -3.21@ () + 2@ string@ true@ 2.234@ -3.21@ null + + 3@ string@ true@ 2.234@ -3.21@ () + 4@ string@ true@ 2.234@ ()@-3.21 + + 5@ string@ true@ 2.234@ -3.21@ null`; diff --git a/ballerina-tests/parse-string-record-types-tests/tests/types.bal b/ballerina-tests/parse-string-record-types-tests/tests/types.bal new file mode 100644 index 0000000..a2b4b2b --- /dev/null +++ b/ballerina-tests/parse-string-record-types-tests/tests/types.bal @@ -0,0 +1,2534 @@ +type BooleanRecord1 record { + boolean b1; + boolean|string b2; + boolean|string? b3; + boolean b4; +}; + +type BooleanRecord2 record {| + boolean b1; + boolean|string b2; + boolean|string? b3; + boolean b4; +|}; + +type BooleanRecord3 record {| + boolean b1; + boolean? b3; +|}; + +type BooleanRecord4 record { + boolean b1; + boolean? b3; +}; + +type BooleanRecord5 record { + boolean b1; + boolean? b3; + string defaultableField = ""; + string? nillableField = (); +}; + +type BooleanRecord6 record {| + boolean b1; + boolean? b3; + string defaultableField = ""; + string? nillableField = (); +|}; + +type BooleanRecord7 record { + boolean b1; + boolean? b3; + string defaultableField = ""; + string? nillableField = (); + string requiredField; +}; + +type BooleanRecord8 record {| + boolean b1; + boolean? b3; + string defaultableField = ""; + string? nillableField = (); + string requiredField; +|}; + +type BooleanRecord9 record {| + boolean b1; + boolean? b3; + boolean?...; +|}; + +type BooleanRecord10 record {| + boolean...; +|}; + +type BooleanRecord11 record {| + boolean b1; + string defaultableField = ""; + string? nillableField = (); + boolean?|string...; +|}; + +type BooleanRecord12 record {| + boolean b1; + string defaultableField = ""; + string? nillableField = (); + string requiredField; + boolean...; +|}; + +type BooleanRecord13 record {| + string defaultableField = ""; + string? nillableField = (); + string|boolean...; +|}; + +type BooleanRecord14 record {| + string defaultableField = ""; + string? nillableField = (); + string requiredField; + boolean...; +|}; + +type BooleanRecord15 record {| + int b1; + string defaultableField = ""; + string? nillableField = (); + boolean?...; +|}; + +type BooleanRecord16 record {| + boolean?...; +|}; + +type BooleanRecord17 record {| + int...; +|}; + +type BooleanRecord18 record {| + boolean b2; + int?...; +|}; + +type NilRecord1 record { + () n1; + () n2; + () n3; +}; + +type NilRecord2 record {| + () n1; + () n2; + () n3; +|}; + +type NilRecord3 record {| + () n1; + () n4; +|}; + +type NilRecord4 record { + () n1; + () n4; +}; + +type NilRecord5 record { + () n1; + () n4; + string defaultableField = ""; + string? nillableField = (); +}; + +type NilRecord6 record {| + () n1; + () n4; + string defaultableField = ""; + string? nillableField = (); +|}; + +type NilRecord7 record { + () n1; + () n4; + string defaultableField = ""; + string? nillableField = (); + string requiredField; +}; + +type NilRecord8 record {| + () n1; + () n4; + string defaultableField = ""; + string? nillableField = (); + string requiredField; +|}; + +type NilRecord9 record {| + () n1; + () n2; + ()...; +|}; + +type NilRecord10 record {| + ()...; +|}; + +type NilRecord11 record {| + () n1; + string defaultableField = ""; + string? nillableField = (); + ()...; +|}; + +type NilRecord12 record {| + () n1; + string defaultableField = ""; + string? nillableField = (); + string requiredField; + ()...; +|}; + +type NilRecord13 record {| + string defaultableField = ""; + string? nillableField = (); + ()...; +|}; + +type NilRecord14 record {| + string defaultableField = ""; + string? nillableField = (); + string requiredField; + ()...; +|}; + +type IntegerRecord1 record { + int i1; + int i2; + int i3; + int? i4; + int? i5; + int i6; + int i7; + int? i8; +}; + +type IntegerRecord2 record {| + int i1; + int? i2; + int i3; + int i4; + int? i5; + int i6; + int i7; + int? i8; +|}; + +type IntegerRecord3 record {| + int i1; + int i4; + int i6; +|}; + +type IntegerRecord4 record { + int i1; + int i4; + int i6; +}; + +type IntegerRecord5 record { + int i1; + int i4; + int i6; + string defaultableField = ""; + string? nillableField = (); +}; + +type IntegerRecord6 record {| + int i1; + int i4; + int i6; + string defaultableField = ""; + string? nillableField = (); +|}; + +type IntegerRecord7 record { + int i1; + int i4; + int i6; + string defaultableField = ""; + string? nillableField = (); + string requiredField; +}; + +type IntegerRecord8 record {| + int i1; + int i4; + int i6; + string defaultableField = ""; + string? nillableField = (); + string requiredField; +|}; + +type IntegerRecord9 record {| + int i1; + int i2; + int...; +|}; + +type IntegerRecord10 record {| + int...; +|}; + +type IntegerRecord11 record {| + int i1; + string defaultableField = ""; + string? nillableField = (); + int...; +|}; + +type IntegerRecord12 record {| + int i1; + string defaultableField = ""; + string? nillableField = (); + string requiredField; + int...; +|}; + +type IntegerRecord13 record {| + string defaultableField = ""; + string? nillableField = (); + int...; +|}; + +type IntegerRecord14 record {| + string defaultableField = ""; + string? nillableField = (); + string requiredField; + int...; +|}; + +type FloatRecord1 record { + float f1; + float f2; + float f3; + float f4; + float f5; + float f6; + float f7; + float f8; +}; + +type FloatRecord2 record {| + float f1; + float f2; + float f3; + float f4; + float f5; + float f6; + float f7; + float f8; +|}; + +type FloatRecord3 record {| + float f1; + float f4; + float f7; +|}; + +type FloatRecord4 record { + float f1; + float f4; + float f7; +}; + +type FloatRecord5 record { + float f1; + float f4; + float f7; + string defaultableField = ""; + string? nillableField = (); +}; + +type FloatRecord6 record {| + float f1; + float f4; + float f7; + string defaultableField = ""; + string? nillableField = (); +|}; + +type FloatRecord7 record { + float f1; + float f4; + float f7; + string defaultableField = ""; + string? nillableField = (); + string requiredField; +}; + +type FloatRecord8 record {| + float f1; + float f4; + float f7; + string defaultableField = ""; + string? nillableField = (); + string requiredField; +|}; + +type FloatRecord9 record {| + float f1; + float f2; + float...; +|}; + +type FloatRecord10 record {| + float...; +|}; + +type FloatRecord11 record {| + float f1; + string defaultableField = ""; + string? nillableField = (); + float...; +|}; + +type FloatRecord12 record {| + float f1; + string defaultableField = ""; + string? nillableField = (); + string requiredField; + float...; +|}; + +type FloatRecord13 record {| + string defaultableField = ""; + string? nillableField = (); + float...; +|}; + +type FloatRecord14 record {| + string defaultableField = ""; + string? nillableField = (); + string requiredField; + float...; +|}; + +type DecimalRecord1 record { + decimal d1; + decimal d2; + decimal d3; + decimal d4; + decimal d5; + decimal d6; + decimal d7; + decimal d8; +}; + +type DecimalRecord2 record {| + decimal d1; + decimal d2; + decimal d3; + decimal d4; + decimal d5; + decimal d6; + decimal d7; + decimal d8; +|}; + +type DecimalRecord3 record {| + decimal d1; + decimal d4; + decimal d7; +|}; + +type DecimalRecord4 record { + decimal d1; + decimal d4; + decimal d7; +}; + +type DecimalRecord5 record { + decimal d1; + decimal d4; + decimal d7; + string defaultableField = ""; + string? nillableField = (); +}; + +type DecimalRecord6 record {| + decimal d1; + decimal d4; + decimal d7; + string defaultableField = ""; + string? nillableField = (); +|}; + +type DecimalRecord7 record { + decimal d1; + decimal d4; + decimal d7; + string defaultableField = ""; + string? nillableField = (); + string requiredField; +}; + +type DecimalRecord8 record {| + decimal d1; + decimal d4; + decimal d7; + string defaultableField = ""; + string? nillableField = (); + string requiredField; +|}; + +type DecimalRecord9 record {| + decimal d1; + decimal d2; + decimal...; +|}; + +type DecimalRecord10 record {| + decimal...; +|}; + +type DecimalRecord11 record {| + decimal d1; + string defaultableField = ""; + string? nillableField = (); + decimal...; +|}; + +type DecimalRecord12 record {| + decimal d1; + string defaultableField = ""; + string? nillableField = (); + string requiredField; + decimal...; +|}; + +type DecimalRecord13 record {| + string defaultableField = ""; + string? nillableField = (); + decimal...; +|}; + +type DecimalRecord14 record {| + string defaultableField = ""; + string? nillableField = (); + string requiredField; + decimal...; +|}; + +type StringRecord1 record { + string s1; + string s2; + string s3; +}; + +type StringRecord2 record {| + string s1; + string s2; + string s3; +|}; + +type StringRecord3 record {| + string s1; + string s4; +|}; + +type StringRecord4 record { + string s1; + string s4; +}; + +type StringRecord5 record { + string s1; + string s4; + string defaultableField = ""; + string? nillableField = (); +}; + +type StringRecord6 record {| + string s1; + string s4; + string defaultableField = ""; + string? nillableField = (); +|}; + +type StringRecord7 record { + string s1; + string s4; + string defaultableField = ""; + string? nillableField = (); + string requiredField; +}; + +type StringRecord8 record {| + string s1; + string s4; + string defaultableField = ""; + string? nillableField = (); + string requiredField; +|}; + +type StringRecord9 record {| + string s1; + string s2; + string...; +|}; + +type StringRecord10 record {| + string...; +|}; + +type StringRecord11 record {| + string s1; + string defaultableField = ""; + string? nillableField = (); + string...; +|}; + +type StringRecord12 record {| + string d1; + string defaultableField = ""; + string? nillableField = (); + string requiredField; + string...; +|}; + +type StringRecord13 record {| + string defaultableField = ""; + string? nillableField = (); + string...; +|}; + +type StringRecord14 record {| + string defaultableField = ""; + string? nillableField = (); + string requiredField; + string...; +|}; + +type StringRecord15 record {| + string defaultableField = ""; + string? nillableField = (); + string requiredField; + string...; +|}; + +type StringRecord16 record {| + string?...; +|}; + +type StringRecord17 record {| + int...; +|}; + +type StringRecord18 record {| + string b2; + int?...; +|}; + +type StringRecord19 record { + string s1 = ""; + string s2 = ""; +}; + +type StringRecord20 record {| + string s1 = ""; + string s2 = ""; +|}; + +type StringRecord21 record { +}; + +type StringRecord22 record {| + string s1 = ""; + string s2 = ""; + json...; +|}; + +type StringRecord23 record {| + json...; +|}; + +type JsonRecord1 record { + json j1; + json j2; + json j3; +}; + +type JsonRecord2 record {| + json j1; + json j2; + json j3; +|}; + +type JsonRecord3 record {| + json j1; + json j4; +|}; + +type JsonRecord4 record { + json j1; + json j4; +}; + +type JsonRecord5 record { + json j1; + json j4; + json defaultableField = ""; + json? nillableField = (); +}; + +type JsonRecord6 record {| + json j1; + json j4; + json defaultableField = ""; + json? nillableField = (); +|}; + +type JsonRecord7 record { + json j1; + json j4; + json defaultableField = ""; + json? nillableField = (); + json requiredField; +}; + +type JsonRecord8 record {| + json j1; + json j4; + json defaultableField = ""; + json? nillableField = (); + json requiredField; +|}; + +type JsonRecord9 record {| + json j1; + json j2; + json...; +|}; + +type JsonRecord10 record {| + json...; +|}; + +type JsonRecord11 record {| + json j1; + json defaultableField = ""; + json? nillableField = (); + json...; +|}; + +type JsonRecord12 record {| + json j1; + json defaultableField = ""; + json? nillableField = (); + json requiredField; + json...; +|}; + +type JsonRecord13 record {| + json defaultableField = ""; + json? nillableField = (); + json...; +|}; + +type JsonRecord14 record {| + json defaultableField = ""; + json? nillableField = (); + json requiredField; + json...; +|}; + +type AnydataRecord1 record { + anydata anydata1; + anydata anydata2; + anydata anydata3; +}; + +type AnydataRecord2 record {| + anydata anydata1; + anydata anydata2; + anydata anydata3; +|}; + +type AnydataRecord3 record {| + anydata anydata1; + anydata anydata4; +|}; + +type AnydataRecord4 record { + anydata anydata1; + anydata anydata4; +}; + +type AnydataRecord5 record { + anydata anydata1; + anydata anydata4; + anydata defaultableField = ""; + anydata? nillableField = (); +}; + +type AnydataRecord6 record {| + anydata anydata1; + anydata anydata4; + anydata defaultableField = ""; + anydata? nillableField = (); +|}; + +type AnydataRecord7 record { + anydata anydata1; + anydata anydata4; + anydata defaultableField = ""; + anydata? nillableField = (); + anydata requiredField; +}; + +type AnydataRecord8 record {| + anydata anydata1; + anydata anydata4; + anydata defaultableField = ""; + anydata? nillableField = (); + anydata requiredField; +|}; + +type AnydataRecord9 record {| + anydata anydata1; + anydata anydata2; + anydata...; +|}; + +type AnydataRecord10 record {| + anydata...; +|}; + +type AnydataRecord11 record {| + anydata anydata1; + anydata defaultableField = ""; + anydata? nillableField = (); + anydata...; +|}; + +type AnydataRecord12 record {| + anydata anydata1; + anydata defaultableField = ""; + anydata? nillableField = (); + anydata requiredField; + anydata...; +|}; + +type AnydataRecord13 record {| + anydata defaultableField = ""; + anydata? nillableField = (); + anydata...; +|}; + +type AnydataRecord14 record {| + anydata defaultableField = ""; + anydata? nillableField = (); + anydata requiredField; + anydata...; +|}; + +type CustomRecord1 record { + int i1; + int i2; + string s1; + string s2; + boolean b1; + boolean b2; + () n1; + () n2; + float f1; + float f2; + decimal d1; + decimal d2; +}; + +type CustomRecord2 record {| + int i1; + int i2; + string s1; + string s2; + boolean b1; + boolean b2; + () n1; + () n2; + float f1; + float f2; + decimal d1; + decimal d2; +|}; + +type CustomRecord3 record {| + int i1; + string s1; + boolean b1; + () n1; + float f1; + decimal d1; +|}; + +type CustomRecord4 record { + int i1; + string s1; + boolean b1; + () n1; + float f1; + decimal d1; +}; + +type CustomRecord5 record { + int i1; + string s1; + boolean b1; + () n1; + float f1; + decimal d1; + string defaultableField = ""; + string? nillableField = (); +}; + +type CustomRecord6 record {| + int i1; + string s1; + boolean b1; + () n1; + float f1; + decimal d1; + anydata defaultableField = ""; + anydata? nillableField = (); +|}; + +type CustomRecord7 record { + int i1; + string s1; + boolean b1; + () n1; + float f1; + decimal d1; + anydata defaultableField = ""; + anydata? nillableField = (); + anydata requiredField; +}; + +type CustomRecord8 record {| + int i1; + string s1; + boolean b1; + () n1; + float f1; + decimal d1; + anydata defaultableField = ""; + anydata? nillableField = (); + anydata requiredField; +|}; + +type CustomRecord9 record {| + int i1; + string s1; + boolean b1; + () n1; + float f1; + decimal d1; + string...; +|}; + +type CustomRecord10 record {| + string...; +|}; + +type CustomRecord11 record {| + int i1; + string s1; + boolean b1; + () n1; + float f1; + decimal d1; + anydata defaultableField = ""; + anydata? nillableField = (); + string...; +|}; + +type CustomRecord12 record {| + int i1; + string s1; + boolean b1; + () n1; + float f1; + decimal d1; + anydata defaultableField = ""; + anydata? nillableField = (); + anydata requiredField; + string...; +|}; + +type CustomRecord13 record {| + anydata defaultableField = ""; + anydata? nillableField = (); + string...; +|}; + +type CustomRecord14 record {| + anydata defaultableField = ""; + anydata? nillableField = (); + anydata requiredField; + string...; +|}; + +type CustomRecord15 record {| + string '1; + string '2; +|}; + +type CustomRecord16 record {| + string '1; + string '2; + string '3; + string '4; +|}; + +type CustomRecord17 record { + string '1; + string '2; +}; + +type CustomRecord18 record { + string '1; + string '2; + string '3; + string '4; +}; + +type CustomRecord19 record { + string '1; + string '2; + string '3 = ""; + string '4 = ""; +}; + +type CustomRecord20 record { + string '1; +}; + +type CustomRecord21 record {| + string '1; + json...; +|}; + +type CustomRecord22 record {| + string '1; + string...; +|}; + +type CustomRecord23 record {| + string '1; + string a = ""; + string...; +|}; + +type CustomRecord24 record {| + string '1; + string '2 = ""; + string...; +|}; + +type CustomRecord25 record {| + int '1; + string...; +|}; + +type CustomRecord26 record {| + string '1; + int...; +|}; + +type CustomRecord27 record {| + int i1; + string s1; + boolean b1; + () n1; + float f1; + decimal d1; + anydata a1; + json j1; + anydata defaultableField = ""; + anydata? nillableField = (); + string...; +|}; + +type CustomRecord28 record { + string '1; +}; + +type CustomRecord29 record { + int '1; +}; + +type CustomRecord30 record {| + string '1; + string '2; + string '3; + string '4; + string '5; + string '6; +|}; + +type CustomRecord31 record {| + string '1; + string '6; +|}; + +type CustomRecord32 record {| + int '1; +|}; + +type CustomRecord33 record {| + string '1; + string '2; + string '3; + string '4; + string '5; + string '6; +|}; + +type CustomRecord34 record { + string '1; + string '6; + string '5 = ""; +}; + +type CustomRecord35 record { + string '1; + string '6; + string '9 = ""; +}; + +type CustomRecord36 record {| + string '1; + string '6; + string '9 = ""; +|}; + +type CustomRecord37 record {| + string '1; + string '6; + string '5 = ""; +|}; + +type CustomRecord38 record {| + string '1; + string '2; + string '3; + string '4; + string '5; + string '6; + string ...; +|}; + +type CustomRecord39 record {| + string '1; + string '2; + string '3; + string '4; + string '5; + string '6; + json ...; +|}; + +type CustomRecord40 record {| + string '5; + string '6; + json ...; +|}; + +type CustomRecord41 record {| + json ...; +|}; + +type CustomRecord42 record {| + int '1; + string '2; + boolean '3; + decimal '4; + float '5; + () '6; +|}; + +type CustomRecord43 record { + int '1; + string '2; + boolean '3; + decimal '4; + float '5; + () '6; +}; + +type CustomRecord44 record {| + int '1; + string '2; + boolean '3; + decimal '4; + float '5; + () '6; + string ...; +|}; + +type CustomRecord45 record {| + int H1; + string H2; + boolean H3; + decimal H4; + float H5; + () H6; +|}; + +type CustomRecord46 record { + int H1; + string H2; + boolean H3; + decimal H4; + float H5; + () H6; +}; + +type CustomRecord47 record {| + int H1; + string H2; + boolean H3; + decimal H4; + float H5; + () H6; + string ...; +|}; + +type CustomRecord48 record { + string H1; + string H2; + string H3; + string H4; + string H5; + string H6; +}; + +type CustomRecord49 record {| + string H1; + string H2; + string H3; + string H4; + string H5; + string H6; +|}; + +type CustomRecord50 record { + int H1; + float H4; +}; + +type CustomRecord51 record {| + int H1; + float H4; +|}; + +type CustomRecord52 record {| + string H1; + string H4; + string ...; +|}; + +type CustomRecord53 record {| + int H1; + float H4; + decimal ...; +|}; + +type CustomRecord54 record {| + string H1 = ""; + string H4; + string '1; +|}; + +type CustomRecord55 record {| + string H1 = ""; + string H4 = ""; + int '1 = 10; +|}; + +type CustomRecord56 record { + string H1 = ""; + string H4 = ""; + anydata '1 = 10; +}; + +type BooleanTuple1 [boolean, boolean, boolean, boolean]; + +type BooleanTuple2 [boolean, boolean]; + +type BooleanTuple3 [boolean, boolean...]; + +type BooleanTuple4 [boolean...]; + +type NillableBooleanTuple5 [boolean?, boolean?, boolean?, boolean?, boolean?]; + +type NillableBooleanTuple6 [boolean?, boolean?]; + +type NillableBooleanTuple7 [boolean?, boolean?, boolean?...]; + +type NillableBooleanTuple8 [boolean?...]; + +type NillableIntBooleanTuple9 [int|boolean?, int|boolean?...]; + +type NilTuple1 [(), (), ()]; + +type NilTuple2 [(), ()]; + +type NilTuple3 [(), ()...]; + +type NilTuple4 [()...]; + +type IntegerTuple1 [int, int, int, int, int, int]; + +type IntegerTuple2 [int, int]; + +type IntegerTuple3 [int, int...]; + +type IntegerTuple4 [int...]; + +type FloatTuple1 [float, float, float, float, float, float, float]; + +type FloatTuple2 [float, float]; + +type FloatTuple3 [float, float...]; + +type FloatTuple4 [float...]; + +type DecimalTuple1 [decimal, decimal, decimal, decimal]; + +type DecimalTuple2 [decimal, decimal]; + +type DecimalTuple3 [decimal, decimal...]; + +type DecimalTuple4 [decimal...]; + +type StringTuple1 [string, string, string, string]; + +type StringTuple2 [string, string]; + +type StringTuple3 [string, string...]; + +type StringTuple4 [string...]; + +type AnydataTuple1 [anydata, anydata, anydata, anydata, anydata, + anydata, anydata, anydata, anydata, anydata, anydata, anydata, + anydata, anydata, anydata, anydata, anydata, anydata, anydata, + anydata, anydata, anydata, anydata]; + +type AnydataTuple2 [anydata, anydata]; + +type AnydataTuple3 [anydata, anydata...]; + +type AnydataTuple4 [anydata...]; + +type JsonTuple1 [json, json, json, json, json, json, json, json, + json, json, json, json, json, json, json, json, json, json, + json, json, json, json, json]; + +type JsonTuple2 [json, json]; + +type JsonTuple3 [json, json...]; + +type JsonTuple4 [json...]; + +type CustomTuple1 [string, int, decimal, float, (), boolean, anydata, json, string, int, decimal, float, (), boolean, anydata, json]; + +type CustomTuple2 [string, int, decimal, float, (), boolean, anydata, json]; + +type CustomTuple3 [string, int, decimal, float, (), boolean, anydata, json, string...]; + +type CustomTuple4 [string...]; + +type CustomTuple5 [string, int, decimal, float, (), boolean, anydata, json, anydata...]; + +type CustomTuple6 [anydata...]; + +type CustomTuple7 [int, string, boolean, (), float, decimal, json, anydata, string...]; + +type CustomTuple8 [int, string, boolean, (), float, decimal, json, anydata, int...]; + +type IntegerArray1 int[]; + +type IntegerArray2 int[2]; + +type IntegerArray3 int[]; + +type IntegerArray4 int[2]; + +type IntegerArray5 int[3]; + +type IntegerArray6 int[4]; + +type StringArray string[]; + +type NillableStringArray string?[]; + +type NillableIntOrUnionStringArray (int|string?)[]; + +type StringArray1 string[]; + +type StringArray2 string[2]; + +type StringArray3 string[]; + +type StringArray4 string[2]; + +type StringArray5 string[3]; + +type StringArray6 string[4]; + +type FloatArray1 float[]; + +type FloatArray2 float[2]; + +type FloatArray3 float[]; + +type FloatArray4 float[2]; + +type FloatArray5 float[3]; + +type FloatArray6 float[4]; + +type DecimalArray1 decimal[]; + +type DecimalArray2 decimal[2]; + +type DecimalArray3 decimal[]; + +type DecimalArray4 decimal[2]; + +type DecimalArray5 decimal[3]; + +type DecimalArray6 decimal[4]; + +type BooleanArray boolean[]; + +type NillableBooleanArray boolean?[]; + +type NillableIntOrUnionBooleanArray (int|boolean?)[]; + +type BooleanArray2 boolean[2]; + +type BooleanArray3 boolean[3]; + +type BooleanArray4 boolean[]; + +type BooleanArray5 boolean[2]; + +type BooleanArray6 boolean[4]; + +type NilArray1 ()[]; + +type NilArray2 ()[2]; + +type NilArray3 ()[]; + +type NilArray4 ()[2]; + +type NilArray5 ()[3]; + +type NilArray6 ()[4]; + +type JsonArray1 json[]; + +type JsonArray2 json[2]; + +type JsonArray3 json[]; + +type JsonArray4 json[2]; + +type JsonArray5 json[3]; + +type JsonArray6 json[4]; + +type AnydataArray1 anydata[]; + +type AnydataArray2 anydata[2]; + +type AnydataArray3 anydata[]; + +type AnydataArray4 anydata[2]; + +type AnydataArray5 anydata[3]; + +type AnydataArray6 anydata[4]; + +type CustomArray1 CustomTuple2[]; + +type CustomArray2 CustomTuple2[2]; + +type CustomArray3 CustomTuple2[]; + +type CustomArray4 CustomTuple2[2]; + +type CustomArray5 CustomTuple2[3]; + +type CustomArray6 CustomTuple2[4]; + +type IntegerMap map; + +type StringMap map; + +type NillableIntUnionStringMap map; + +type IntUnionStringMap map; + +type DecimalMap map; + +type FloatMap map; + +type BooleanMap map; + +type NillableBooleanMap map; + +type NillableIntUnionBooleanMap map; + +type IntUnionBooleanMap map; + +type NilMap map<()>; + +type JsonMap map; + +type AnydataMap map; + +type CustomMap map; + +type BooleanRecord1Array BooleanRecord1[]; + +type ClosedBooleanRecord1Array BooleanRecord1[3]; + +type BooleanRecord2Array BooleanRecord2[]; + +type ClosedBooleanRecord2Array BooleanRecord2[3]; + +type BooleanRecord3Array BooleanRecord3[]; + +type ClosedBooleanRecord3Array BooleanRecord3[3]; + +type BooleanRecord4Array BooleanRecord4[]; + +type ClosedBooleanRecord4Array BooleanRecord4[3]; + +type BooleanRecord5Array BooleanRecord5[]; + +type ClosedBooleanRecord5Array BooleanRecord5[3]; + +type BooleanRecord6Array BooleanRecord6[]; + +type ClosedBooleanRecord6Array BooleanRecord6[3]; + +type BooleanRecord7Array BooleanRecord7[]; + +type ClosedBooleanRecord7Array BooleanRecord7[3]; + +type BooleanRecord8Array BooleanRecord8[]; + +type ClosedBooleanRecord8Array BooleanRecord8[3]; + +type BooleanRecord9Array BooleanRecord9[]; + +type ClosedBooleanRecord9Array BooleanRecord9[3]; + +type BooleanRecord10Array BooleanRecord10[]; + +type ClosedBooleanRecord10Array BooleanRecord10[3]; + +type BooleanRecord11Array BooleanRecord11[]; + +type ClosedBooleanRecord11Array BooleanRecord11[3]; + +type BooleanRecord12Array BooleanRecord12[]; + +type ClosedBooleanRecord12Array BooleanRecord12[3]; + +type BooleanRecord13Array BooleanRecord13[]; + +type ClosedBooleanRecord13Array BooleanRecord13[3]; + +type BooleanRecord14Array BooleanRecord14[]; + +type ClosedBooleanRecord14Array BooleanRecord14[3]; + +type BooleanRecord15Array BooleanRecord15[]; + +type ClosedBooleanRecord15Array BooleanRecord15[3]; + +type BooleanRecord16Array BooleanRecord16[]; + +type ClosedBooleanRecord16Array BooleanRecord16[3]; + +type BooleanRecord17Array BooleanRecord17[]; + +type ClosedBooleanRecord17Array BooleanRecord17[3]; + +type BooleanRecord18Array BooleanRecord18[]; + +type ClosedBooleanRecord18Array BooleanRecord18[3]; + +type NilRecord1Array NilRecord1[]; + +type ClosedNilRecord1Array NilRecord1[3]; + +type NilRecord2Array NilRecord2[]; + +type ClosedNilRecord2Array NilRecord2[3]; + +type NilRecord3Array NilRecord3[]; + +type ClosedNilRecord3Array NilRecord3[3]; + +type NilRecord4Array NilRecord4[]; + +type ClosedNilRecord4Array NilRecord4[3]; + +type NilRecord5Array NilRecord5[]; + +type ClosedNilRecord5Array NilRecord5[3]; + +type NilRecord6Array NilRecord6[]; + +type ClosedNilRecord6Array NilRecord6[3]; + +type NilRecord7Array NilRecord7[]; + +type ClosedNilRecord7Array NilRecord7[3]; + +type NilRecord8Array NilRecord8[]; + +type ClosedNilRecord8Array NilRecord8[3]; + +type NilRecord9Array NilRecord9[]; + +type ClosedNilRecord9Array NilRecord9[3]; + +type NilRecord10Array NilRecord10[]; + +type ClosedNilRecord10Array NilRecord10[3]; + +type NilRecord11Array NilRecord11[]; + +type ClosedNilRecord11Array NilRecord11[3]; + +type NilRecord12Array NilRecord12[]; + +type ClosedNilRecord12Array NilRecord12[3]; + +type NilRecord13Array NilRecord13[]; + +type ClosedNilRecord13Array NilRecord13[3]; + +type NilRecord14Array NilRecord14[]; + +type ClosedNilRecord14Array NilRecord14[3]; + +type IntegerRecord1Array IntegerRecord1[]; + +type ClosedIntegerRecord1Array IntegerRecord1[3]; + +type IntegerRecord2Array IntegerRecord2[]; + +type ClosedIntegerRecord2Array IntegerRecord2[3]; + +type IntegerRecord3Array IntegerRecord3[]; + +type ClosedIntegerRecord3Array IntegerRecord3[3]; + +type IntegerRecord4Array IntegerRecord4[]; + +type ClosedIntegerRecord4Array IntegerRecord4[3]; + +type IntegerRecord5Array IntegerRecord5[]; + +type ClosedIntegerRecord5Array IntegerRecord5[3]; + +type IntegerRecord6Array IntegerRecord6[]; + +type ClosedIntegerRecord6Array IntegerRecord6[3]; + +type IntegerRecord7Array IntegerRecord7[]; + +type ClosedIntegerRecord7Array IntegerRecord7[3]; + +type IntegerRecord8Array IntegerRecord8[]; + +type ClosedIntegerRecord8Array IntegerRecord8[3]; + +type IntegerRecord9Array IntegerRecord9[]; + +type ClosedIntegerRecord9Array IntegerRecord9[3]; + +type IntegerRecord10Array IntegerRecord10[]; + +type ClosedIntegerRecord10Array IntegerRecord10[3]; + +type IntegerRecord11Array IntegerRecord11[]; + +type ClosedIntegerRecord11Array IntegerRecord11[3]; + +type IntegerRecord12Array IntegerRecord12[]; + +type ClosedIntegerRecord12Array IntegerRecord12[3]; + +type IntegerRecord13Array IntegerRecord13[]; + +type ClosedIntegerRecord13Array IntegerRecord13[3]; + +type IntegerRecord14Array IntegerRecord14[]; + +type ClosedIntegerRecord14Array IntegerRecord14[3]; + +type FloatRecord1Array FloatRecord1[]; + +type ClosedFloatRecord1Array FloatRecord1[3]; + +type FloatRecord2Array FloatRecord2[]; + +type ClosedFloatRecord2Array FloatRecord2[3]; + +type FloatRecord3Array FloatRecord3[]; + +type ClosedFloatRecord3Array FloatRecord3[3]; + +type FloatRecord4Array FloatRecord4[]; + +type ClosedFloatRecord4Array FloatRecord4[3]; + +type FloatRecord5Array FloatRecord5[]; + +type ClosedFloatRecord5Array FloatRecord5[3]; + +type FloatRecord6Array FloatRecord6[]; + +type ClosedFloatRecord6Array FloatRecord6[3]; + +type FloatRecord7Array FloatRecord7[]; + +type ClosedFloatRecord7Array FloatRecord7[3]; + +type FloatRecord8Array FloatRecord8[]; + +type ClosedFloatRecord8Array FloatRecord8[3]; + +type FloatRecord9Array FloatRecord9[]; + +type ClosedFloatRecord9Array FloatRecord9[3]; + +type FloatRecord10Array FloatRecord10[]; + +type ClosedFloatRecord10Array FloatRecord10[3]; + +type FloatRecord11Array FloatRecord11[]; + +type ClosedFloatRecord11Array FloatRecord11[3]; + +type FloatRecord12Array FloatRecord12[]; + +type ClosedFloatRecord12Array FloatRecord12[3]; + +type FloatRecord13Array FloatRecord13[]; + +type ClosedFloatRecord13Array FloatRecord13[3]; + +type FloatRecord14Array FloatRecord14[]; + +type ClosedFloatRecord14Array FloatRecord14[3]; + +type DecimalRecord1Array DecimalRecord1[]; + +type ClosedDecimalRecord1Array DecimalRecord1[3]; + +type DecimalRecord2Array DecimalRecord2[]; + +type ClosedDecimalRecord2Array DecimalRecord2[3]; + +type DecimalRecord3Array DecimalRecord3[]; + +type ClosedDecimalRecord3Array DecimalRecord3[3]; + +type DecimalRecord4Array DecimalRecord4[]; + +type ClosedDecimalRecord4Array DecimalRecord4[3]; + +type DecimalRecord5Array DecimalRecord5[]; + +type ClosedDecimalRecord5Array DecimalRecord5[3]; + +type DecimalRecord6Array DecimalRecord6[]; + +type ClosedDecimalRecord6Array DecimalRecord6[3]; + +type DecimalRecord7Array DecimalRecord7[]; + +type ClosedDecimalRecord7Array DecimalRecord7[3]; + +type DecimalRecord8Array DecimalRecord8[]; + +type ClosedDecimalRecord8Array DecimalRecord8[3]; + +type DecimalRecord9Array DecimalRecord9[]; + +type ClosedDecimalRecord9Array DecimalRecord9[3]; + +type DecimalRecord10Array DecimalRecord10[]; + +type ClosedDecimalRecord10Array DecimalRecord10[3]; + +type DecimalRecord11Array DecimalRecord11[]; + +type ClosedDecimalRecord11Array DecimalRecord11[3]; + +type DecimalRecord12Array DecimalRecord12[]; + +type ClosedDecimalRecord12Array DecimalRecord12[3]; + +type DecimalRecord13Array DecimalRecord13[]; + +type ClosedDecimalRecord13Array DecimalRecord13[3]; + +type DecimalRecord14Array DecimalRecord14[]; + +type ClosedDecimalRecord14Array DecimalRecord14[3]; + +type StringRecord1Array StringRecord1[]; + +type ClosedStringRecord1Array StringRecord1[3]; + +type StringRecord2Array StringRecord2[]; + +type ClosedStringRecord2Array StringRecord2[3]; + +type StringRecord3Array StringRecord3[]; + +type ClosedStringRecord3Array StringRecord3[3]; + +type StringRecord4Array StringRecord4[]; + +type ClosedStringRecord4Array StringRecord4[3]; + +type StringRecord5Array StringRecord5[]; + +type ClosedStringRecord5Array StringRecord5[3]; + +type StringRecord6Array StringRecord6[]; + +type ClosedStringRecord6Array StringRecord6[3]; + +type StringRecord7Array StringRecord7[]; + +type ClosedStringRecord7Array StringRecord7[3]; + +type StringRecord8Array StringRecord8[]; + +type ClosedStringRecord8Array StringRecord8[3]; + +type StringRecord9Array StringRecord9[]; + +type ClosedStringRecord9Array StringRecord9[3]; + +type StringRecord10Array StringRecord10[]; + +type ClosedStringRecord10Array StringRecord10[3]; + +type StringRecord11Array StringRecord11[]; + +type ClosedStringRecord11Array StringRecord11[3]; + +type StringRecord12Array StringRecord12[]; + +type ClosedStringRecord12Array StringRecord12[3]; + +type StringRecord13Array StringRecord13[]; + +type ClosedStringRecord13Array StringRecord13[3]; + +type StringRecord14Array StringRecord14[]; + +type ClosedStringRecord14Array StringRecord14[3]; + +type StringRecord15Array StringRecord15[]; + +type StringRecord16Array StringRecord16[]; + +type StringRecord17Array StringRecord17[]; + +type StringRecord18Array StringRecord18[]; + +type StringRecord19Array StringRecord19[]; + +type StringRecord20Array StringRecord20[]; + +type StringRecord21Array StringRecord21[]; + +type StringRecord22Array StringRecord22[]; + +type StringRecord23Array StringRecord23[]; + +type JsonRecord1Array JsonRecord1[]; + +type ClosedJsonRecord1Array JsonRecord1[3]; + +type JsonRecord2Array JsonRecord2[]; + +type ClosedJsonRecord2Array JsonRecord2[3]; + +type JsonRecord3Array JsonRecord3[]; + +type ClosedJsonRecord3Array JsonRecord3[3]; + +type JsonRecord4Array JsonRecord4[]; + +type ClosedJsonRecord4Array JsonRecord4[3]; + +type JsonRecord5Array JsonRecord5[]; + +type ClosedJsonRecord5Array JsonRecord5[3]; + +type JsonRecord6Array JsonRecord6[]; + +type ClosedJsonRecord6Array JsonRecord6[3]; + +type JsonRecord7Array JsonRecord7[]; + +type ClosedJsonRecord7Array JsonRecord7[3]; + +type JsonRecord8Array JsonRecord8[]; + +type ClosedJsonRecord8Array JsonRecord8[3]; + +type JsonRecord9Array JsonRecord9[]; + +type ClosedJsonRecord9Array JsonRecord9[3]; + +type JsonRecord10Array JsonRecord10[]; + +type ClosedJsonRecord10Array JsonRecord10[3]; + +type JsonRecord11Array JsonRecord11[]; + +type ClosedJsonRecord11Array JsonRecord11[3]; + +type JsonRecord12Array JsonRecord12[]; + +type ClosedJsonRecord12Array JsonRecord12[3]; + +type JsonRecord13Array JsonRecord13[]; + +type ClosedJsonRecord13Array JsonRecord13[3]; + +type JsonRecord14Array JsonRecord14[]; + +type ClosedJsonRecord14Array JsonRecord14[3]; + +type AnydataRecord1Array AnydataRecord1[]; + +type ClosedAnydataRecord1Array AnydataRecord1[3]; + +type AnydataRecord2Array AnydataRecord2[]; + +type ClosedAnydataRecord2Array AnydataRecord2[3]; + +type AnydataRecord3Array AnydataRecord3[]; + +type ClosedAnydataRecord3Array AnydataRecord3[3]; + +type AnydataRecord4Array AnydataRecord4[]; + +type ClosedAnydataRecord4Array AnydataRecord4[3]; + +type AnydataRecord5Array AnydataRecord5[]; + +type ClosedAnydataRecord5Array AnydataRecord5[3]; + +type AnydataRecord6Array AnydataRecord6[]; + +type ClosedAnydataRecord6Array AnydataRecord6[3]; + +type AnydataRecord7Array AnydataRecord7[]; + +type ClosedAnydataRecord7Array AnydataRecord7[3]; + +type AnydataRecord8Array AnydataRecord8[]; + +type ClosedAnydataRecord8Array AnydataRecord8[3]; + +type AnydataRecord9Array AnydataRecord9[]; + +type ClosedAnydataRecord9Array AnydataRecord9[3]; + +type AnydataRecord10Array AnydataRecord10[]; + +type ClosedAnydataRecord10Array AnydataRecord10[3]; + +type AnydataRecord11Array AnydataRecord11[]; + +type ClosedAnydataRecord11Array AnydataRecord11[3]; + +type AnydataRecord12Array AnydataRecord12[]; + +type ClosedAnydataRecord12Array AnydataRecord12[3]; + +type AnydataRecord13Array AnydataRecord13[]; + +type ClosedAnydataRecord13Array AnydataRecord13[3]; + +type AnydataRecord14Array AnydataRecord14[]; + +type ClosedAnydataRecord14Array AnydataRecord14[3]; + +type CustomRecord1Array CustomRecord1[]; + +type ClosedCustomRecord1Array CustomRecord1[3]; + +type CustomRecord2Array CustomRecord2[]; + +type ClosedCustomRecord2Array CustomRecord2[3]; + +type CustomRecord3Array CustomRecord3[]; + +type ClosedCustomRecord3Array CustomRecord3[3]; + +type CustomRecord4Array CustomRecord4[]; + +type ClosedCustomRecord4Array CustomRecord4[3]; + +type CustomRecord5Array CustomRecord5[]; + +type ClosedCustomRecord5Array CustomRecord5[3]; + +type CustomRecord6Array CustomRecord6[]; + +type ClosedCustomRecord6Array CustomRecord6[3]; + +type CustomRecord7Array CustomRecord7[]; + +type ClosedCustomRecord7Array CustomRecord7[3]; + +type CustomRecord8Array CustomRecord8[]; + +type ClosedCustomRecord8Array CustomRecord8[3]; + +type CustomRecord9Array CustomRecord9[]; + +type ClosedCustomRecord9Array CustomRecord9[3]; + +type CustomRecord10Array CustomRecord10[]; + +type ClosedCustomRecord10Array CustomRecord10[3]; + +type CustomRecord11Array CustomRecord11[]; + +type ClosedCustomRecord11Array CustomRecord11[3]; + +type CustomRecord12Array CustomRecord12[]; + +type ClosedCustomRecord12Array CustomRecord12[3]; + +type CustomRecord13Array CustomRecord13[]; + +type ClosedCustomRecord13Array CustomRecord13[3]; + +type CustomRecord14Array CustomRecord14[]; + +type ClosedCustomRecord14Array CustomRecord14[3]; + +type CustomRecord15Array CustomRecord15[]; + +type CustomRecord16Array CustomRecord16[]; + +type CustomRecord17Array CustomRecord17[]; + +type CustomRecord18Array CustomRecord18[]; + +type CustomRecord19Array CustomRecord19[]; + +type CustomRecord20Array CustomRecord20[]; + +type CustomRecord21Array CustomRecord21[]; + +type CustomRecord22Array CustomRecord22[]; + +type CustomRecord23Array CustomRecord23[]; + +type CustomRecord24Array CustomRecord24[]; + +type CustomRecord25Array CustomRecord25[]; + +type CustomRecord26Array CustomRecord26[]; + +type CustomRecord27Array CustomRecord27[]; +type CustomRecord28Array CustomRecord28[]; +type CustomRecord29Array CustomRecord29[]; +type CustomRecord30Array CustomRecord30[]; +type CustomRecord31Array CustomRecord31[]; +type CustomRecord32Array CustomRecord32[]; +type CustomRecord33Array CustomRecord33[]; +type CustomRecord34Array CustomRecord34[]; +type CustomRecord35Array CustomRecord35[]; +type CustomRecord36Array CustomRecord36[]; +type CustomRecord37Array CustomRecord37[]; +type CustomRecord38Array CustomRecord38[]; +type CustomRecord39Array CustomRecord39[]; +type CustomRecord40Array CustomRecord40[]; +type CustomRecord41Array CustomRecord41[]; +type CustomRecord42Array CustomRecord42[]; +type CustomRecord43Array CustomRecord43[]; +type CustomRecord44Array CustomRecord44[]; +type CustomRecord45Array CustomRecord45[]; +type CustomRecord46Array CustomRecord46[]; +type CustomRecord47Array CustomRecord47[]; +type CustomRecord48Array CustomRecord48[]; +type CustomRecord49Array CustomRecord49[]; +type CustomRecord50Array CustomRecord50[]; +type CustomRecord51Array CustomRecord51[]; +type CustomRecord52Array CustomRecord52[]; +type CustomRecord53Array CustomRecord53[]; +type CustomRecord54Array CustomRecord54[]; +type CustomRecord55Array CustomRecord55[]; +type CustomRecord56Array CustomRecord56[]; + +type BooleanTuple1Array BooleanTuple1[]; + +type ClosedBooleanTuple1Array BooleanTuple1[3]; + +type BooleanTuple2Array BooleanTuple2[]; + +type ClosedBooleanTuple2Array BooleanTuple2[3]; + +type BooleanTuple3Array BooleanTuple3[]; + +type ClosedBooleanTuple3Array BooleanTuple3[3]; + +type BooleanTuple4Array BooleanTuple4[]; + +type ClosedBooleanTuple4Array BooleanTuple4[3]; + +type NillableBooleanTuple5Array NillableBooleanTuple5[]; + +type NillableBooleanTuple6Array NillableBooleanTuple6[]; + +type NillableBooleanTuple7Array NillableBooleanTuple7[]; + +type NillableBooleanTuple8Array NillableBooleanTuple8[]; + +type NillableIntBooleanTuple9Array NillableIntBooleanTuple9[]; + +type NilTuple1Array NilTuple1[]; + +type ClosedNilTuple1Array NilTuple1[3]; + +type NilTuple2Array NilTuple2[]; + +type ClosedNilTuple2Array NilTuple2[3]; + +type NilTuple3Array NilTuple3[]; + +type ClosedNilTuple3Array NilTuple3[3]; + +type NilTuple4Array NilTuple4[]; + +type ClosedNilTuple4Array NilTuple4[3]; + +type IntegerTuple1Array IntegerTuple1[]; + +type ClosedIntegerTuple1Array IntegerTuple1[3]; + +type IntegerTuple2Array IntegerTuple2[]; + +type ClosedIntegerTuple2Array IntegerTuple2[3]; + +type IntegerTuple3Array IntegerTuple3[]; + +type ClosedIntegerTuple3Array IntegerTuple3[3]; + +type IntegerTuple4Array IntegerTuple4[]; + +type ClosedIntegerTuple4Array IntegerTuple4[3]; + +type FloatTuple1Array FloatTuple1[]; + +type ClosedFloatTuple1Array FloatTuple1[3]; + +type FloatTuple2Array FloatTuple2[]; + +type ClosedFloatTuple2Array FloatTuple2[3]; + +type FloatTuple3Array FloatTuple3[]; + +type ClosedFloatTuple3Array FloatTuple3[3]; + +type FloatTuple4Array FloatTuple4[]; + +type ClosedFloatTuple4Array FloatTuple4[3]; + +type DecimalTuple1Array DecimalTuple1[]; + +type ClosedDecimalTuple1Array DecimalTuple1[3]; + +type DecimalTuple2Array DecimalTuple2[]; + +type ClosedDecimalTuple2Array DecimalTuple2[3]; + +type DecimalTuple3Array DecimalTuple3[]; + +type ClosedDecimalTuple3Array DecimalTuple3[3]; + +type DecimalTuple4Array DecimalTuple4[]; + +type ClosedDecimalTuple4Array DecimalTuple4[3]; + +type StringTuple1Array StringTuple1[]; + +type ClosedStringTuple1Array StringTuple1[3]; + +type StringTuple2Array StringTuple2[]; + +type ClosedStringTuple2Array StringTuple2[3]; + +type StringTuple3Array StringTuple3[]; + +type ClosedStringTuple3Array StringTuple3[3]; + +type StringTuple4Array StringTuple4[]; + +type ClosedStringTuple4Array StringTuple4[3]; + +type AnydataTuple1Array AnydataTuple1[]; + +type ClosedAnydataTuple1Array AnydataTuple1[3]; + +type AnydataTuple2Array AnydataTuple2[]; + +type ClosedAnydataTuple2Array AnydataTuple2[3]; + +type AnydataTuple3Array AnydataTuple3[]; + +type ClosedAnydataTuple3Array AnydataTuple3[3]; + +type AnydataTuple4Array AnydataTuple4[]; + +type ClosedAnydataTuple4Array AnydataTuple4[3]; + +type JsonTuple1Array JsonTuple1[]; + +type ClosedJsonTuple1Array JsonTuple1[3]; + +type JsonTuple2Array JsonTuple2[]; + +type ClosedJsonTuple2Array JsonTuple2[3]; + +type JsonTuple3Array JsonTuple3[]; + +type ClosedJsonTuple3Array JsonTuple3[3]; + +type JsonTuple4Array JsonTuple4[]; + +type ClosedJsonTuple4Array JsonTuple4[3]; + +type CustomTuple1Array CustomTuple1[]; + +type ClosedCustomTuple1Array CustomTuple1[3]; + +type CustomTuple2Array CustomTuple2[]; + +type ClosedCustomTuple2Array CustomTuple2[3]; + +type CustomTuple3Array CustomTuple3[]; + +type ClosedCustomTuple3Array CustomTuple3[3]; + +type CustomTuple4Array CustomTuple4[]; + +type ClosedCustomTuple4Array CustomTuple4[3]; + +type CustomTuple5Array CustomTuple5[]; + +type ClosedCustomTuple5Array CustomTuple5[3]; + +type CustomTuple6Array CustomTuple6[]; + +type CustomTuple7Array CustomTuple7[]; + +type CustomTuple8Array CustomTuple8[]; + +type ClosedCustomTuple6Array CustomTuple6[3]; + +type IntegerArray1Array IntegerArray1[]; + +type ClosedIntegerArray1Array IntegerArray1[3]; + +type IntegerArray2Array IntegerArray2[]; + +type ClosedIntegerArray2Array IntegerArray2[3]; + +type IntegerArray3Array IntegerArray3[]; + +type ClosedIntegerArray3Array IntegerArray3[3]; + +type IntegerArray4Array IntegerArray4[]; + +type ClosedIntegerArray4Array IntegerArray4[3]; + +type IntegerArray5Array IntegerArray5[]; + +type ClosedIntegerArray5Array IntegerArray5[3]; + +type IntegerArray6Array IntegerArray5[]; + +type ClosedIntegerArray6Array IntegerArray5[3]; + +type StringArray1Array StringArray1[]; + +type StringArrayArray StringArray[]; + +type NillableStringArrayArray NillableStringArray[]; + +type NillableIntOrUnionStringArrayArray NillableIntOrUnionStringArray[]; + +type ClosedStringArray1Array StringArray1[3]; + +type StringArray2Array StringArray2[]; + +type ClosedStringArray2Array StringArray2[3]; + +type StringArray3Array StringArray3[]; + +type ClosedStringArray3Array StringArray3[3]; + +type StringArray4Array StringArray4[]; + +type ClosedStringArray4Array StringArray4[3]; + +type StringArray5Array StringArray5[]; + +type ClosedStringArray5Array StringArray5[3]; + +type StringArray6Array StringArray5[]; + +type ClosedStringArray6Array StringArray5[3]; + +type FloatArray1Array FloatArray1[]; + +type ClosedFloatArray1Array FloatArray1[3]; + +type FloatArray2Array FloatArray2[]; + +type ClosedFloatArray2Array FloatArray2[3]; + +type FloatArray3Array FloatArray3[]; + +type ClosedFloatArray3Array FloatArray3[3]; + +type FloatArray4Array FloatArray4[]; + +type ClosedFloatArray4Array FloatArray4[3]; + +type FloatArray5Array FloatArray5[]; + +type ClosedFloatArray5Array FloatArray5[3]; + +type FloatArray6Array FloatArray5[]; + +type ClosedFloatArray6Array FloatArray5[3]; + +type DecimalArray1Array DecimalArray1[]; + +type ClosedDecimalArray1Array DecimalArray1[3]; + +type DecimalArray2Array DecimalArray2[]; + +type ClosedDecimalArray2Array DecimalArray2[3]; + +type DecimalArray3Array DecimalArray3[]; + +type ClosedDecimalArray3Array DecimalArray3[3]; + +type DecimalArray4Array DecimalArray4[]; + +type ClosedDecimalArray4Array DecimalArray4[3]; + +type DecimalArray5Array DecimalArray5[]; + +type ClosedDecimalArray5Array DecimalArray5[3]; + +type DecimalArray6Array DecimalArray5[]; + +type ClosedDecimalArray6Array DecimalArray5[3]; + +type BooleanArrayArray BooleanArray[]; + +type ClosedBooleanArrayArray BooleanArray[3]; + +type NillableBooleanArrayArray NillableBooleanArray[]; + +type NillableIntOrUnionBooleanArrayArray NillableIntOrUnionBooleanArray[]; + +type BooleanArray2Array BooleanArray2[]; + +type ClosedBooleanArray2Array BooleanArray2[3]; + +type BooleanArray3Array BooleanArray3[]; + +type ClosedBooleanArray3Array BooleanArray3[3]; + +type BooleanArray4Array BooleanArray4[]; + +type ClosedBooleanArray4Array BooleanArray4[3]; + +type BooleanArray5Array BooleanArray5[]; + +type ClosedBooleanArray5Array BooleanArray5[3]; + +type BooleanArray6Array BooleanArray5[]; + +type ClosedBooleanArray6Array BooleanArray5[3]; + +type NilArray1Array NilArray1[]; + +type ClosedNilArray1Array NilArray1[3]; + +type NilArray2Array NilArray2[]; + +type ClosedNilArray2Array NilArray2[3]; + +type NilArray3Array NilArray3[]; + +type ClosedNilArray3Array NilArray3[3]; + +type NilArray4Array NilArray4[]; + +type ClosedNilArray4Array NilArray4[3]; + +type NilArray5Array NilArray5[]; + +type ClosedNilArray5Array NilArray5[3]; + +type NilArray6Array NilArray5[]; + +type ClosedNilArray6Array NilArray5[3]; + +type JsonArray1Array JsonArray1[]; + +type ClosedJsonArray1Array JsonArray1[3]; + +type JsonArray2Array JsonArray2[]; + +type ClosedJsonArray2Array JsonArray2[3]; + +type JsonArray3Array JsonArray3[]; + +type ClosedJsonArray3Array JsonArray3[3]; + +type JsonArray4Array JsonArray4[]; + +type ClosedJsonArray4Array JsonArray4[3]; + +type JsonArray5Array JsonArray5[]; + +type ClosedJsonArray5Array JsonArray5[3]; + +type JsonArray6Array JsonArray5[]; + +type ClosedJsonArray6Array JsonArray5[3]; + +type AnydataArray1Array AnydataArray1[]; + +type ClosedAnydataArray1Array AnydataArray1[3]; + +type AnydataArray2Array AnydataArray2[]; + +type ClosedAnydataArray2Array AnydataArray2[3]; + +type AnydataArray3Array AnydataArray3[]; + +type ClosedAnydataArray3Array AnydataArray3[3]; + +type AnydataArray4Array AnydataArray4[]; + +type ClosedAnydataArray4Array AnydataArray4[3]; + +type AnydataArray5Array AnydataArray5[]; + +type ClosedAnydataArray5Array AnydataArray5[3]; + +type AnydataArray6Array AnydataArray5[]; + +type ClosedAnydataArray6Array AnydataArray5[3]; + +type CustomArray1Array CustomArray1[]; + +type ClosedCustomArray1Array CustomArray1[3]; + +type CustomArray2Array CustomArray2[]; + +type ClosedCustomArray2Array CustomArray2[3]; + +type CustomArray3Array CustomArray3[]; + +type ClosedCustomArray3Array CustomArray3[3]; + +type CustomArray4Array CustomArray4[]; + +type ClosedCustomArray4Array CustomArray4[3]; + +type CustomArray5Array CustomArray5[]; + +type ClosedCustomArray5Array CustomArray5[3]; + +type CustomArray6Array CustomArray5[]; + +type ClosedCustomArray6Array CustomArray5[3]; + +type IntegerMapArray IntegerMap[]; + +type ClosedIntegerMapArray IntegerMap[3]; + +type StringMapArray StringMap[]; + +type NillableIntUnionStringMapArray NillableIntUnionStringMap[]; + +type IntUnionStringMapArray IntUnionStringMap[]; + +type ClosedStringMapArray StringMap[3]; + +type DecimalMapArray DecimalMap[]; + +type ClosedDecimalMapArray DecimalMap[3]; + +type FloatMapArray FloatMap[]; + +type ClosedFloatMapArray FloatMap[3]; + +type BooleanMapArray BooleanMap[]; + +type NillableBooleanMapArray NillableBooleanMap[]; + +type NillableIntUnionBooleanMapArray NillableIntUnionBooleanMap[]; + +type IntUnionBooleanMapArray IntUnionBooleanMap[]; + +type ClosedBooleanMapArray BooleanMap[3]; + +type NilMapArray NilMap[]; + +type ClosedNilMapArray NilMap[3]; + +type JsonMapArray JsonMap[]; + +type ClosedJsonMapArray JsonMap[3]; + +type AnydataMapArray AnydataMap[]; + +type ClosedAnydataMapArray AnydataMap[3]; + +type CustomMapArray CustomMap[]; + +type ClosedCustomMapArray CustomMap[3]; diff --git a/ballerina-tests/type-compatible-tests/.gitignore b/ballerina-tests/type-compatible-tests/.gitignore new file mode 100644 index 0000000..d5fc29a --- /dev/null +++ b/ballerina-tests/type-compatible-tests/.gitignore @@ -0,0 +1,11 @@ +# Ballerina generates this directory during the compilation of a package. +# It contains compiler-generated artifacts and the final executable if this is an application package. +target/ + +# Ballerina maintains the compiler-generated source code here. +# Remove this if you want to commit generated sources. +generated/ + +# Contains configuration values used during development time. +# See https://ballerina.io/learn/provide-values-to-configurable-variables/ for more details. +Config.toml diff --git a/ballerina-tests/type-compatible-tests/Ballerina.toml b/ballerina-tests/type-compatible-tests/Ballerina.toml new file mode 100644 index 0000000..2d5ec74 --- /dev/null +++ b/ballerina-tests/type-compatible-tests/Ballerina.toml @@ -0,0 +1,13 @@ +[package] +org = "ballerina" +name = "type_compatible_tests" +version = "0.1.0" + +[[dependency]] +org = "ballerina" +name = "csv_commons" +repository = "local" +version = "0.1.0" + +[platform.java17] +graalvmCompatible = true diff --git a/ballerina-tests/type-compatible-tests/Dependencies.toml b/ballerina-tests/type-compatible-tests/Dependencies.toml new file mode 100644 index 0000000..2e33529 --- /dev/null +++ b/ballerina-tests/type-compatible-tests/Dependencies.toml @@ -0,0 +1,98 @@ +# AUTO-GENERATED FILE. DO NOT MODIFY. + +# This file is auto-generated by Ballerina for managing dependency versions. +# It should not be modified by hand. + +[ballerina] +dependencies-toml-version = "2" +distribution-version = "2201.9.0" + +[[package]] +org = "ballerina" +name = "csv_commons" +version = "0.1.0" +scope = "testOnly" +modules = [ + {org = "ballerina", packageName = "csv_commons", moduleName = "csv_commons"} +] + +[[package]] +org = "ballerina" +name = "data.csv" +version = "0.1.0" +scope = "testOnly" +dependencies = [ + {org = "ballerina", name = "jballerina.java"} +] +modules = [ + {org = "ballerina", packageName = "data.csv", moduleName = "data.csv"} +] + +[[package]] +org = "ballerina" +name = "jballerina.java" +version = "0.0.0" +scope = "testOnly" + +[[package]] +org = "ballerina" +name = "lang.__internal" +version = "0.0.0" +scope = "testOnly" +dependencies = [ + {org = "ballerina", name = "jballerina.java"}, + {org = "ballerina", name = "lang.object"} +] + +[[package]] +org = "ballerina" +name = "lang.array" +version = "0.0.0" +scope = "testOnly" +dependencies = [ + {org = "ballerina", name = "jballerina.java"}, + {org = "ballerina", name = "lang.__internal"} +] + +[[package]] +org = "ballerina" +name = "lang.error" +version = "0.0.0" +scope = "testOnly" +dependencies = [ + {org = "ballerina", name = "jballerina.java"} +] + +[[package]] +org = "ballerina" +name = "lang.object" +version = "0.0.0" +scope = "testOnly" + +[[package]] +org = "ballerina" +name = "test" +version = "0.0.0" +scope = "testOnly" +dependencies = [ + {org = "ballerina", name = "jballerina.java"}, + {org = "ballerina", name = "lang.array"}, + {org = "ballerina", name = "lang.error"} +] +modules = [ + {org = "ballerina", packageName = "test", moduleName = "test"} +] + +[[package]] +org = "ballerina" +name = "type_compatible_tests" +version = "0.1.0" +dependencies = [ + {org = "ballerina", name = "csv_commons"}, + {org = "ballerina", name = "data.csv"}, + {org = "ballerina", name = "test"} +] +modules = [ + {org = "ballerina", packageName = "type_compatible_tests", moduleName = "type_compatible_tests"} +] + diff --git a/ballerina-tests/type-compatible-tests/tests/csv_content.txt b/ballerina-tests/type-compatible-tests/tests/csv_content.txt new file mode 100644 index 0000000..2917073 --- /dev/null +++ b/ballerina-tests/type-compatible-tests/tests/csv_content.txt @@ -0,0 +1,4 @@ +a, b, c d, e +"Hello World", \"Hello World\", Hello World, 2 +"Hello World", \"Hello World\", Hello World, 2 +"Hello World", \"Hello World\", Hello World, 2 \ No newline at end of file diff --git a/ballerina-tests/type-compatible-tests/tests/parse_string_compatibality_test.bal b/ballerina-tests/type-compatible-tests/tests/parse_string_compatibality_test.bal new file mode 100644 index 0000000..8cb60fd --- /dev/null +++ b/ballerina-tests/type-compatible-tests/tests/parse_string_compatibality_test.bal @@ -0,0 +1,234 @@ +import ballerina/csv_commons as common; +import ballerina/data.csv as csv; +import ballerina/io; +import ballerina/test; + +const string filepath = "tests/csv_content.txt"; + +@test:Config +function testFromCsvStringWithTypeCompatibility() { + string value = string `i1,i2,s1,s2, b1,b2,n1,n2,f1,f2, d1,d2,j1,a1,j2,a2 + ${i1},${i2},${s1},${s2},${b1},${b2},(),(),${f1}, ${f2},${d1},${d2},${b1},${d1},${b2},${d2} + ${i1},${i2},${s1},${s2},${b1},${b2},(),(), ${f1},${f2},${d1},${d2},${b1},${d1},${b2},${d2} + `; + string value2 = string `i1, s1, b1, n1, f1, d1, j1, a1, s2, s3, j2, a2 + ${i1}, ${s1},${b1}, null,${f1}, ${d1},${b1}, ${d1},${s2}, ${s3},${b2}, ${d2} + `; + string value3 = string `i1, s1, b1, n1, f1, d1, j1, a1, s2, s3 + ${i1}, ${s1},${b1}, null,${f1}, ${d1},${b1}, ${d1},${s2}, ${s3} + `; + + AnydataArray1Array|csv:Error v3anyd1a = csv:parseStringToList(value); + test:assertEquals(v3anyd1a, [ + [i1, i2, s1, s2, b1, b2, n1, n2, 2.234, -3.21, 2.234, -3.21, b1, 2.234, b2, -3.21], + [i1, i2, s1, s2, b1, b2, n1, n2, 2.234, -3.21, 2.234, -3.21, b1, 2.234, b2, -3.21] + ]); + + CustomRecord27Array|csv:Error vcr27a = csv:parseStringToRecord(value, {}, CustomRecord27Array); + test:assertEquals(vcr27a, [ + {i1, s1, b1, n1, f1, d1, a1: 2.234, j1: b1, defaultableField: "", nillableField: null, i2: "-2", s2: "", b2: "false", n2: "()", f2: "-3.21", d2: "-3.21", j2: "false", a2: "-3.21"}, + {i1, s1, b1, n1, f1, d1, a1: 2.234, j1: b1, defaultableField: "", nillableField: null, i2: "-2", s2: "", b2: "false", n2: "()", f2: "-3.21", d2: "-3.21", j2: "false", a2: "-3.21"} + ]); + + CustomRecord27Array|csv:Error v2cr27a = csv:parseStringToRecord(value2, {}, CustomRecord27Array); + test:assertEquals(v2cr27a, [ + {i1, s1, b1, n1, f1, d1, a1: 2.234, j1: b1, defaultableField: "", nillableField: null, s2, j2: "false", a2: "-3.21", s3} + ]); + + CustomRecord27Array|csv:Error v3cr27a = csv:parseStringToRecord(value3, {}); + test:assertEquals(v3cr27a, [ + {i1, s1, b1, n1, f1, d1, a1: 2.234, j1: b1, defaultableField: "", nillableField: null, s2, s3} + ]); + + AnydataMapArray|csv:Error vanydma = csv:parseStringToRecord(value); + test:assertEquals(vanydma, [ + {i1, i2, s1, s2, b1, b2, n1, n2, f1: 2.234, f2: -3.21, d1: 2.234, d2: -3.21, j1: b1, a1: 2.234, j2: false, a2: -3.21}, + {i1, i2, s1, s2, b1, b2, n1, n2, f1: 2.234, f2: -3.21, d1: 2.234, d2: -3.21, j1: b1, a1: 2.234, j2: false, a2: -3.21} + ]); + + JsonMapArray|csv:Error vjma = csv:parseStringToRecord(value); + test:assertEquals(vjma, [ + {i1, i2, s1, s2, b1, b2, n1, n2, f1: 2.234, f2: -3.21, d1: 2.234, d2: -3.21, j1: b1, a1: 2.234, j2: false, a2: -3.21}, + {i1, i2, s1, s2, b1, b2, n1, n2, f1: 2.234, f2: -3.21, d1: 2.234, d2: -3.21, j1: b1, a1: 2.234, j2: false, a2: -3.21} + ]); + + StringMapArray|csv:Error vsma = csv:parseStringToRecord(value); + test:assertEquals(vsma, [ + {i1: "1", s1: "string", b1: "true", n1: "()", f1: "2.234", d1: "2.234", a1: "2.234", j1: "true", i2: "-2", s2: "", b2: "false", n2: "()", f2: "-3.21", d2: "-3.21", j2: "false", a2: "-3.21"}, + {i1: "1", s1: "string", b1: "true", n1: "()", f1: "2.234", d1: "2.234", a1: "2.234", j1: "true", i2: "-2", s2: "", b2: "false", n2: "()", f2: "-3.21", d2: "-3.21", j2: "false", a2: "-3.21"} + ]); + + CustomTuple7Array|csv:Error v2ct7a = csv:parseStringToList(value2); + test:assertEquals(v2ct7a, [ + [i1, s1, b1, n1, 2.234, 2.234, b1, 2.234, s2, s3, "false", "-3.21"] + ]); + + CustomTuple7Array|csv:Error v3ct7a = csv:parseStringToList(value3); + test:assertEquals(v3ct7a, [ + [i1, s1, b1, n1, 2.234, 2.234, b1, 2.234, s2, s3] + ]); + + [float, decimal, string][]|csv:Error mrrta = csv:parseStringToList(string `a, b,c + 1.23, 1.23, 1.23 + 0,0,0 + 0.0,0.0,0.0 + -1.2,-1.2,-1.2`); + test:assertEquals(mrrta, [ + [1.23, 1.23, "1.23"], + [0, 0, "0"], + [0, 0, "0.0"], + [-1.2, -1.2, "-1.2"] + ]); + + [float, decimal, string, int][]|csv:Error m2rrta = csv:parseStringToList(string `a, b,c,d + 1, 1, 1,1 + 0,0,0,0 + -1,-1,-1,-1`); + test:assertEquals(m2rrta, [ + [1, 1, "1", 1], + [0, 0, "0", 0], + [-1, -1, "-1", -1] + ]); + + [int...][]|csv:Error m3rrta = csv:parseStringToList(string `a, b,c,d + 1.2, abc, true,1.0`); + test:assertTrue(m3rrta is csv:Error); + test:assertEquals((m3rrta).message(), common:generateErrorMessageForInvalidCast("1.2", "int")); + + [boolean|int, int|boolean][]|csv:Error m4rrta = csv:parseStringToList(string `a, b + 1, 1 + 0,0`); + test:assertEquals(m4rrta, [ + [1, 1], + [0, 0] + ]); + + record {|int...;|}[]|csv:Error irrma = csv:parseStringToRecord(string ` + a, b, c + 1, a, 2.3 + 1, -2, true + hello, -2, hello`, {header: 1}); + test:assertEquals(irrma, [ + {a: 1}, + {a: i1, b: i2}, + {b: i2} + ]); + + record {|()...;|}[]|csv:Error nrrma = csv:parseStringToRecord(string ` + a, b, c + 1, a, () + 1, null, () + hello, -2, hello`, {header: 1}); + test:assertEquals(nrrma, [ + {c: ()}, + {b: (), c: ()}, + {} + ]); + + record {|decimal...;|}[]|csv:Error drra = csv:parseStringToRecord(string `a, b, c + 2.234, invalid , 1 + ${f2}, 0, 2.3d + invalid, ${d2}, ${f3}`); + test:assertTrue(drra is record {|decimal...;|}[]); + test:assertEquals(drra, [ + {a: d1, c: 1.0}, + {a: f2, b: d3}, + {b: -3.21d, c: f3} + ]); + + record {|string...;|}[]|csv:Error srra = csv:parseStringToRecord(string `a, b, c + 1, a, 2.3 + 1, -2, true + hello, -2, hello`); + test:assertTrue(srra is record {|string...;|}[]); + test:assertEquals(srra, [ + {a: "1", b: "a", c: "2.3"}, + {a: "1", b: "-2", c: "true"}, + {a: "hello", b: "-2", c: "hello"} + ]); + + record {|float...;|}[]|csv:Error frra = csv:parseStringToRecord(string `a, b, c + 1.2, invalid , 1 + ${d2}, ${d3}, true + ${d4}, ${f2}, 0.0`); + test:assertEquals(frra, [ + {a: 1.2, c: 1.0}, + {a: d2, b: d3}, + {a: d4, b: f2, c: 0.0} + ]); + + record {float a; decimal b; string c;}[]|csv:Error mrra = csv:parseStringToRecord(string `a, b,c + 1.23, 1.23, 1.23 + 0,0,0 + 0.0,0.0,0.0 + -1.2,-1.2,-1.2`); + test:assertEquals(mrra, [ + {a: 1.23, b: 1.23, c: "1.23"}, + {a: 0, b: 0, c: "0"}, + {a: 0, b: 0, c: "0.0"}, + {a: -1.2, b: -1.2, c: "-1.2"} + ]); + + record {|float a; decimal b; string c; int d;|}[]|csv:Error m2rra = csv:parseStringToRecord(string `a, b,c,d + 1, 1, 1,1 + 0,0,0,0 + -1,-1,-1,-1`); + test:assertEquals(m2rra, [ + {a: 1, b: 1, c: "1", d: 1}, + {a: 0, b: 0, c: "0", d: 0}, + {a: -1, b: -1, c: "-1", d: -1} + ]); + + record {int d;}[]|csv:Error m3rra = csv:parseStringToRecord(string `a, b,c,d + 1.2, abc, true,1.0`); + test:assertTrue(m3rra is csv:Error); + test:assertEquals((m3rra).message(), common:generateErrorMessageForInvalidCast("1.0", "int")); +} + +@test:Config +function testSpaceBetweendData() { + string csv = string `a b, b d e, f + "Hello world", " Hi I am ", \" Hi I am \"`; + + record{|string...;|}[]|csv:Error rec = csv:parseStringToRecord(csv); + test:assertEquals(rec, [ + {"a b":"Hello world","b d e":" Hi I am ","f":"\"Hi I am \""}]); +} + +@test:Config +function testParseBytes() returns error? { + byte[] csvBytes = check io:fileReadBytes(filepath); + + record{}[]|csv:Error rec = csv:parseBytesToRecord(csvBytes, {}); + test:assertEquals(rec, [ + {"a":"Hello World","b":"\"Hello World\"","c d":"Hello World","e":2}, + {"a":"Hello World","b":"\"Hello World\"","c d":"Hello World","e":2}, + {"a":"Hello World","b":"\"Hello World\"","c d":"Hello World","e":2}] + ); + + string[][]|csv:Error rec2 = csv:parseBytesToList(csvBytes, {}); + test:assertEquals(rec2, [ + ["Hello World", "\"Hello World\"", "Hello World", "2"], + ["Hello World", "\"Hello World\"", "Hello World", "2"], + ["Hello World", "\"Hello World\"", "Hello World", "2"] + ]); +} + +@test:Config +function testParseStream() returns error? { + stream csvByteStream = check io:fileReadBlocksAsStream(filepath); + record{}[]|csv:Error rec = csv:parseStreamToRecord(csvByteStream, {}); + test:assertEquals(rec, [ + {"a":"Hello World","b":"\"Hello World\"","c d":"Hello World","e":2}, + {"a":"Hello World","b":"\"Hello World\"","c d":"Hello World","e":2}, + {"a":"Hello World","b":"\"Hello World\"","c d":"Hello World","e":2}] + ); + + csvByteStream = check io:fileReadBlocksAsStream(filepath); + string[][]|csv:Error rec2 = csv:parseStreamToList(csvByteStream, {}); + test:assertEquals(rec2, [ + ["Hello World", "\"Hello World\"", "Hello World", "2"], + ["Hello World", "\"Hello World\"", "Hello World", "2"], + ["Hello World", "\"Hello World\"", "Hello World", "2"] + ]); +} diff --git a/ballerina-tests/type-compatible-tests/tests/parse_type_compatibility_test.bal b/ballerina-tests/type-compatible-tests/tests/parse_type_compatibility_test.bal new file mode 100644 index 0000000..ed41a81 --- /dev/null +++ b/ballerina-tests/type-compatible-tests/tests/parse_type_compatibility_test.bal @@ -0,0 +1,437 @@ +import ballerina/csv_commons as common; +import ballerina/data.csv as csv; +import ballerina/test; + +@test:Config +function testFromCsvWithTypeFunctionWithTypeCompatibility() { + var value = {i1, i2, s1, s2, b1, b2, n1, n2, f1, f2, d1, d2, j1: b1, a1: d1, j2: b2, a2: d2}; + + CustomRecord27Array|csv:Error vcr27a = csv:parseRecordAsRecordType([value, value, value], {}, CustomRecord27Array); + test:assertEquals(vcr27a , [ + {i1, s1, s2, b1, n1, f1, d1, j1: b1, a1: d1, defaultableField: "", nillableField: ()}, + {i1, s1, s2, b1, n1, f1, d1, j1: b1, a1: d1, defaultableField: "", nillableField: ()}, + {i1, s1, s2, b1, n1, f1, d1, j1: b1, a1: d1, defaultableField: "", nillableField: ()} + ]); + + AnydataMapArray|csv:Error vanydma = csv:parseRecordAsRecordType([value, value, value], {}, AnydataMapArray); + test:assertEquals(vanydma , [ + value, + value, + value + ]); + + JsonMapArray|csv:Error vjma = csv:parseRecordAsRecordType([value, value, value], {}, JsonMapArray); + test:assertEquals(vjma , [ + value, + value, + value + ]); + + record{|int...;|}[]|csv:Error irrma = csv:parseRecordAsRecordType([{"a": 1}, {"a": i1, "b": i2}, {"a": i1, "b": i2, "c": s1}]); + test:assertEquals(irrma , [ + {a:1}, + {a: i1, b: i2}, + {a: i1, b: i2} + ]); + + record{|decimal...;|}[]|csv:Error drra = csv:parseRecordAsRecordType([{"a": d1}, {"a": d2, "b": d3}, {"a": d4, "b": f2, "c": s1, "d": f3}]); + test:assertTrue(drra is record{|decimal...;|}[]); + test:assertEquals(drra , [ + {a: d1}, + {a: d2, b: d3}, + {a: d4, b: -3.21d, d: f3} + ]); + + record{|string...;|}[]|csv:Error srra = csv:parseRecordAsRecordType([{"a": "string"}, {"c": 1, "a": s1, "b": s2}, {"a": b1, "b": s3, "c": d1}]); + test:assertEquals(srra , [ + {a: "string"}, + {a: s1, b: s2}, + {b: s3} + ]); + + record{|float...;|}[]|csv:Error frra = csv:parseRecordAsRecordType([{"a": 1.2, "b": 1.2f}, {"a": d2, "b": d3}, {"a": d4, "b": f2, "c": s1}]); + test:assertEquals(frra , [ + {a: 1.2, b: 1.2}, + {a: d2, b: d3}, + {a: d4, b: f2} + ]); + + record{|float a; decimal b;|}[]|csv:Error fdc1a = csv:parseRecordAsRecordType([{"a": d1, "b": d2}, {"a": f1, "b": f2}, {"a": d2, "b": f2}, {"a": f2, "b": d2}]); + test:assertEquals(fdc1a , [ + {a: d1, b: d2}, + {a: f1, b: f2}, + {a: d2, b: f2}, + {a: f2, b: d2} + ]); + + record{|float a; decimal ...;|}[]|csv:Error fdc2a = csv:parseRecordAsRecordType([{"a": d1, "b": d2}, {"a": f1, "b": f2}, {"a": d2, "b": f2}, {"a": f2, "b": d2}]); + test:assertEquals(fdc2a , [ + {a: d1, b: d2}, + {a: f1, b: f2}, + {a: d2, b: f2}, + {a: f2, b: d2} + ]); + + record{|decimal b; float...;|}[]|csv:Error fdc3a = csv:parseRecordAsRecordType([{"a": d1, "b": d2}, {"a": f1, "b": f2}, {"a": d2, "b": f2}, {"a": f2, "b": d2}]); + test:assertEquals(fdc3a , [ + {a: d1, b: d2}, + {a: f1, b: f2}, + {a: d2, b: f2}, + {a: f2, b: d2} + ]); +} + +type A decimal|int; +type A2 int|decimal; +type B readonly & A | C; +type B2 readonly & C | readonly & A2; +type C string|boolean; +type C2 boolean|string; + +@test:Config +function testFromCsvWithIntersectionTypeCompatibility2() { + record{ + readonly & int a; + readonly & string b; + (readonly & boolean) | (readonly & decimal) c; + }[]|csv:Error r1a = csv:parseStringToRecord( string `a,b,c + 1,string,true + 2,string2,false + 3,string3,true`); + + test:assertEquals(r1a , [ + {a: 1, b: "string", c: true}, + {a: 2, b: "string2", c: false}, + {a: 3, b: "string3", c: true} + ]); + + record{A a; B b; C c;}[]|csv:Error r2a = csv:parseStringToRecord( string `a,b,c + 1,string,true + 2,string2,false + 3,string3,true`); + + test:assertEquals(r2a , [ + {a: 1, b: "string", c: true}, + {a: 2, b: "string2", c: false}, + {a: 3, b: "string3", c: true} + ]); + + record{A2 a; B2 b; C2 c;}[]|csv:Error r3a = csv:parseStringToRecord( string `a,b,c + 1,string,true + 2,string2,false + 3,string3,true`); + + test:assertEquals(r3a , [ + {a: 1, b: "string", c: true}, + {a: 2, b: "string2", c: false}, + {a: 3, b: "string3", c: true} + ]); + + record{|A2 a; B2 b; C2...;|}[]|csv:Error r4a = csv:parseStringToRecord( string ` + a,b,c,d + 1,string,true,string + 2,string2,false,string2 + 3,string3,true,string3`, {header: 1}); + + test:assertEquals(r4a , [ + {a: 1, b: "string", c: true, d: "string"}, + {a: 2, b: "string2", c: false, d: "string2"}, + {a: 3, b: "string3", c: true, d: "string3"} + ]); + + record{|C2...;|}[]|csv:Error r5a = csv:parseStringToRecord( string `a,b,c,d + 1,string,true,string + 2,string2,false,string2 + 3,string3,true,string3`); + + test:assertEquals(r5a , [ + {a: "1", b: "string", c: true, d: "string"}, + {a: "2", b: "string2", c: false, d: "string2"}, + {a: "3", b: "string3", c: true, d: "string3"} + ]); + + [readonly & int, readonly & string, (readonly & boolean) | (readonly & decimal)][]|csv:Error r16a = + csv:parseStringToList( string `a,b,c + 1,string,true + 2,string2,false + 3,string3,true`); + + test:assertEquals(r16a , [ + [1, "string", true], + [2, "string2", false], + [3, "string3", true] + ]); + + [A, B, C][]|csv:Error r17a = csv:parseStringToList( + string `a,b,c + 1,string,true + 2,string2,false + 3,string3,true`); + + test:assertEquals(r17a , [ + [1, "string", true], + [2, "string2", false], + [3, "string3", true] + ]); + + [A2, B2, C2][]|csv:Error r18a = csv:parseStringToList( + string `a,b,c + 1,string,true + 2,string2,false + 3,string3,true`); + + test:assertEquals(r18a , [ + [1, "string", true], + [2, "string2", false], + [3, "string3", true] + ]); + + [A2, B2, C2...][]|csv:Error r19a = csv:parseStringToList( + string `a,b,c,d + 1,string,true,string + 2,string2,false,string2 + 3,string3,true,string3`); + + test:assertEquals(r19a , [ + [1, "string", true, "string"], + [2, "string2", false, "string2"], + [3, "string3", true, "string3"] + ]); + + [C2...][]|csv:Error r20a = csv:parseStringToList( + string `a,b,c,d + 1,string,true,string + 2,string2,false,string2 + 3,string3,true,string3`); + + test:assertEquals(r20a, [["1", "string",true, "string"], + ["2", "string2", false, "string2"], ["3", "string3",true, "string3"]]); + + + record{A a; B b; C c;}[]|csv:Error rt2a = csv:parseRecordAsRecordType( + [{"a": 1, "b": "string", "c": true}, {"a": 2, "b": "string2", "c": false}, {"a": 3, "b": "string3", "c": true}]); + + test:assertEquals(rt2a , [ + {a: 1, b: "string", c: true}, + {a: 2, b: "string2", c: false}, + {a: 3, b: "string3", c: true} + ]); + + record{ + readonly & int a; + readonly & string b; + (readonly & boolean) | (readonly & decimal) c; + }[]|csv:Error rt1a = csv:parseRecordAsRecordType( + [{"a": 1, "b": "string", "c": true}, {"a": 2, "b": "string2", "c": false}, {"a": 3, "b": "string3", "c": true}]); + + test:assertEquals(rt1a , [ + {a: 1, b: "string", c: true}, + {a: 2, b: "string2", c: false}, + {a: 3, b: "string3", c: true} + ]); + + record{A2 a; B2 b; C2 c;}[]|csv:Error rt3a = csv:parseRecordAsRecordType( + [{"a": 1, "b": "string", "c": true}, {"a": 2, "b": "string2", "c": false}, {"a": 3, "b": "string3", "c": true}]); + + test:assertEquals(rt3a , [ + {a: 1, b: "string", c: true}, + {a: 2, b: "string2", c: false}, + {a: 3, b: "string3", c: true} + ]); + + record{|A2 a; B2 b; C2...;|}[]|csv:Error rt4a = csv:parseRecordAsRecordType( + [{"a": 1, "b": "string", "c": true, "d": "string"}, {"a": 2, "b": "string2", "c": false, "d": "string2"}, {"a": 3, "b": "string3", "c": true, "d": "string3"}]); + + test:assertEquals(rt4a , [ + {a: 1, b: "string", c: true, d: "string"}, + {a: 2, b: "string2", c: false, d: "string2"}, + {a: 3, b: "string3", c: true, d: "string3"} + ]); + + record{|C2...;|}[]|csv:Error rt5a = csv:parseRecordAsRecordType( + [{"a": 1, "b": "string", "c": true, "d": "string"}, {"a": 2, "b": "string2", "c": false, "d": "string2"}, {"a": 3, "b": "string3", "c": true, "d": "string3"}]); + + test:assertEquals(rt5a , [ + {b: "string", c: true, d: "string"}, + {b: "string2", c: false, d: "string2"}, + {b: "string3", c: true, d: "string3"} + ]); + + [readonly & int, readonly & string, (readonly & boolean) | (readonly & decimal)][]|csv:Error rt6a = + csv:parseRecordAsListType( + [{"a": 1, "b": "string", "c": true}, + {"a": 2, "b": "string2", "c": false}, + {"a": 3, "b": "string3", "c": true} + ], ["a", "b", "c"]); + + test:assertEquals(rt6a , [ + [1, "string", true], + [2, "string2", false], + [3, "string3", true] + ]); + + [A, B, C][]|csv:Error rt7a = csv:parseRecordAsListType( + [{"a": 1, "b": "string", "c": true}, {"a": 2, "b": "string2", "c": false}, {"a": 3, "b": "string3", "c": true}] + , ["a", "b", "c"]); + + test:assertEquals(rt7a , [ + [1, "string", true], + [2, "string2", false], + [3, "string3", true] + ]); + + [A2, B2, C2][]|csv:Error rt8a = csv:parseRecordAsListType( + [{"a": 1, "b": "string", "c": true}, {"a": 2, "b": "string2", "c": false}, {"a": 3, "b": "string3", "c": true}] + , ["a", "b", "c"]); + + test:assertEquals(rt8a , [ + [1, "string", true], + [2, "string2", false], + [3, "string3", true] + ]); + + [A2, B2, C2...][]|csv:Error rt9a = csv:parseRecordAsListType( + [{"a": 1, "b": "string", "c": true, "d": "string"}, {"a": 2, "b": "string2", "c": false, "d": "string2"}, {"a": 3, "b": "string3", "c": true, "d": "string3"}] + , ["a", "b", "c", "d"]); + + test:assertEquals(rt9a , [ + [1, "string", true, "string"], + [2, "string2", false, "string2"], + [3, "string3", true, "string3"] + ]); + + [C2...][]|csv:Error rt10a = csv:parseRecordAsListType( + [{"a": 1, "b": "string", "c": true, "d": "string"}, {"a": 2, "b": "string2", "c": false, "d": "string2"}, {"a": 3, "b": "string3", "c": true, "d": "string3"}] + , ["a", "b", "c", "d"]); + + test:assertTrue(rt10a is csv:Error); + test:assertEquals((rt10a).message(), common:generateErrorMessageForInvalidValueForArrayType("1", "0", "type_compatible_tests:C2")); + + record{ + readonly & int a; + readonly & string b; + (readonly & boolean) | (readonly & decimal) c; + }[]|csv:Error rt11a = csv:parseListAsRecordType( + [["1", "string", "true"], ["2", "string2", "false"], ["3", "string3", "true"]], ["a", "b", "c"]); + + test:assertEquals(rt11a , [ + {a: 1, b: "string", c: true}, + {a: 2, b: "string2", c: false}, + {a: 3, b: "string3", c: true} + ]); + + record{A a; B b; C c;}[]|csv:Error rt12a = csv:parseListAsRecordType( + [["1", "string", "true"], ["2", "string2", "false"], ["3", "string3", "true"]], ["a", "b", "c"]); + + test:assertEquals(rt12a , [ + {a: 1, b: "string", c: true}, + {a: 2, b: "string2", c: false}, + {a: 3, b: "string3", c: true} + ]); + + record{A a; B b; C c;}[]|csv:Error rt12a_2 = csv:parseListAsRecordType( + [["1", "string", "true"], ["2", "string2", "false"], ["3", "string3", "true"]], ["a", "b", "c"], {stringConversion: false}); + + test:assertTrue(rt12a_2 is csv:Error); + test:assertEquals((rt12a_2).message(), + common:generateErrorMessageForInvalidFieldType("1", "a")); + + record{string|decimal a; B b; C c;}[]|csv:Error rt12a_3 = csv:parseListAsRecordType( + [["1", "string", "true"], ["2", "string2", "false"], ["3", "string3", "true"]], ["a", "b", "c"]); + + test:assertEquals(rt12a_3 , [ + {a: 1, b: "string", c: true}, + {a: 2, b: "string2", c: false}, + {a: 3, b: "string3", c: true} + ]); + + record{A2 a; B2 b; C2 c;}[]|csv:Error rt13a = csv:parseListAsRecordType( + [["1", "string", "true"], ["2", "string2", "false"], ["3", "string3", "true"]], ["a", "b", "c"]); + + test:assertEquals(rt13a , [ + {a: 1, b: "string", c: true}, + {a: 2, b: "string2", c: false}, + {a: 3, b: "string3", c: true} + ]); + + record{|A2 a; B2 b; C2...;|}[]|csv:Error rt14a = csv:parseListAsRecordType( + [["1", "string", "true", "string"], ["2", "string2", "false", "string2"], ["3", "string3", "true", "string3"]] + , ["a", "b", "c", "d"]); + + test:assertEquals(rt14a , [ + {a: 1, b: "string", c: true, d: "string"}, + {a: 2, b: "string2", c: false, d: "string2"}, + {a: 3, b: "string3", c: true, d: "string3"} + ]); + + record{|C2...;|}[]|csv:Error rt15a = csv:parseListAsRecordType( + [["1", "string", "true", "string"], ["2", "string2", "false", "string2"], ["3", "string3", "true", "string3"]] + , ["a", "b", "c", "d"]); + + test:assertEquals(rt15a , [ + {a: "1", b: "string", c: true, d: "string"}, + {a: "2", b: "string2", c: false, d: "string2"}, + {a: "3", b: "string3", c: true, d: "string3"} + ]); + + record{|C2...;|}[]|csv:Error rt15a_2 = csv:parseListAsRecordType( + [["1", "string", "true", "string"], ["2", "string2", "false", "string2"], ["3", "string3", "true", "string3"]] + , ["a", "b", "c", "d"], {stringConversion: false}); + + test:assertEquals(rt15a_2 , [ + {a: "1", b: "string", c: "true", d: "string"}, + {a: "2", b: "string2", c: "false", d: "string2"}, + {a: "3",b: "string3", c: "true", d: "string3"} + ]); + + [readonly & int, readonly & string, (readonly & boolean) | (readonly & decimal)][]|csv:Error rt16a = + csv:parseListAsListType( + [["1", "string", "true"], + ["2", "string2", "false"], + ["3", "string3", "true"]]); + + test:assertEquals(rt16a , [ + [1, "string", true], + [2, "string2", false], + [3, "string3", true] + ]); + + [A, B, C][]|csv:Error rt17a = csv:parseListAsListType( + [["1", "string", "true"], ["2", "string2", "false"], ["3", "string3", "true"]]); + + test:assertEquals(rt17a , [ + [1, "string", true], + [2, "string2", false], + [3, "string3", true] + ]); + + [A, B, C][]|csv:Error rt17a_2 = csv:parseListAsListType( + [["1", "string", "true"], ["2", "string2", "false"], ["3", "string3", "true"]], {stringConversion: false}); + + test:assertTrue(rt17a_2 is csv:Error); + test:assertEquals((rt17a_2).message(), common:generateErrorMessageForInvalidValueForArrayType("1", "0", "type_compatible_tests:A")); + + [A2, B2, C2][]|csv:Error rt18a = csv:parseListAsListType( + [["1", "string", "true"], ["2", "string2", "false"], ["3", "string3", "true"]]); + + test:assertEquals(rt18a , [ + [1, "string", true], + [2, "string2", false], + [3, "string3", true] + ]); + + [A2, B2, C2...][]|csv:Error rt19a = csv:parseListAsListType( + [["1", "string", "true", "string"], ["2", "string2", "false", "string2"], ["3", "string3", "true", "string3"]]); + + test:assertEquals(rt19a , [ + [1, "string", true, "string"], + [2, "string2", false, "string2"], + [3, "string3", true, "string3"] + ]); + + [C2...][]|csv:Error rt20a = csv:parseListAsListType( + [["1", "string", "true", "string"], ["2", "string2", "false", "string2"], ["3", "string3", "true", "string3"]]); + + test:assertEquals(rt20a, [["1", "string",true, "string"], + ["2", "string2", false, "string2"], ["3", "string3",true, "string3"]]); +} \ No newline at end of file diff --git a/ballerina-tests/type-compatible-tests/tests/test_data_values.bal b/ballerina-tests/type-compatible-tests/tests/test_data_values.bal new file mode 100644 index 0000000..360a493 --- /dev/null +++ b/ballerina-tests/type-compatible-tests/tests/test_data_values.bal @@ -0,0 +1,256 @@ +boolean b1 = true; +false b2 = false; +boolean? b3 = (); +boolean|int b4 = false; + +() n1 = (); +int? n2 = (); +() n3 = null; + +int i1 = 1; +int i2 = -2; +int i3 = int:MAX_VALUE; +int i4 = int:MIN_VALUE; +int i5 = 0; +2 i6 = 2; +int? i7 = (); +int|string i8 = 100; + +float f1 = 2.234; +float f2 = -3.21f; +float f3 = 0; +float f4 = float:Infinity; +float f5 = -float:Infinity; +float f6 = float:NaN; +2.3f f7 = 2.3; +float? f8 = (); +float|decimal f9 = 1.21; + +decimal d1 = 2.234; +decimal d2 = -3.21d; +decimal d3 = 0; +2.3d d4 = 2.3; +decimal? d5 = (); +decimal|int d6 = 1.21; + +string s1 = "string"; +string s2 = ""; +string:Char s3 = "a"; + +map bm1 = {b1, b2}; +map bm2 = {b1, b2, b3, n1, n3}; +map bm3 = {b1, b2, b3, b4, i1}; +map<()> bm4 = {n1, n3}; +map bm5 = {b1, b2, b3, b4:true}; + +map m5 = {i1, i2, i3, i4, i5, i6}; +map m6 = {f1, f2, f3, f4, f5, f6, f7}; +map m7 = {d1, d2, d3, d4}; +map m8 = {d1, f1, f9, f10: 1.23}; +map m9 = {s1, s2, s3}; +map m10 = {b1, b2, b3, b4, n1, n2, n3, i1, i2, i3, i4, i5, i6, i7, i8, f1, f2, f3, f4, f5, f6, f7, f8}; +map m11 = {b1, b2, b3, b4, n1, n2, n3, i1, i2, i3, i4, i5, i6, i7, i8, f1, f2, f3, f4, f5, f6, f7, f8}; + +boolean[] arr1 = [b1, b2]; +boolean?[] arr2 = [b1, b2, b3, n1, n3]; +(boolean|int?)[] arr3 = [b1, b2, b3, b4, i1]; +()[] arr4 = [n1, n3]; +int[] arr5 = [i1, i2, i3, i4, i5, i6]; +float[] arr6 = [f1, f2, f3, f4, f5, f6, f7]; +decimal[] arr7 = [d1, d2, d3, d4]; +(decimal|float)[] arr8 = [d1, f1, f9, 1.23]; +string[] arr9 = [s1, s2, s3]; +anydata[] arr10 = [b1, b2, b3, b4, n1, n2, n3, i1, i2, i3, i4, i5, i6, i7, i8, f1, f2, f3, f4, f5, f6, f7, f8]; +json[] arr11 = [b1, b2, b3, b4, n1, n2, n3, i1, i2, i3, i4, i5, i6, i7, i8, f1, f2, f3, f4, f5, f6, f7, f8]; + +[boolean, boolean] bt1 = [b1, b2]; +[boolean, boolean, boolean, boolean] bt2 = [b1, b2, b1, b2]; +[boolean?, boolean?, boolean?, boolean?, boolean?] bt3 = [b1, b2, b3, n1, n3]; +[boolean|int?, boolean|int?, boolean|int?, boolean|int?, boolean|int?] bt4 = [b1, b2, b3, b4, i1]; +[boolean...] bt5 = [b1, b2]; + +[string, string] st1 = [s1, s2]; +[string, string, string, string] st2 = [s1, s2, s3, s2]; +[string...] st3 = [s1, s2]; +[string, string, string...] st4 = [s1, s2, s3, s2]; + +[string?, string?, string?, string?, string?] st5 = [s1, s2, s3, n1, n3]; +[string|int?, string|int?, string|int?, string|int?, string|int?] st6 = [s1, s2, s3, n1, i1]; +[string?...] st7 = [s1, s2]; +[string...] st8 = []; +[string, string, string] st9 = [s1, s2, s3]; + +[(), ()] tup4 = [n1, n3]; +[int, int, int, int, int, int] tup5 = [i1, i2, i3, i4, i5, i6]; +[float, float, float, float, float, float, float] tup6 = [f1, f2, f3, f4, f5, f6, f7]; +[decimal, decimal, decimal, decimal] tup7 = [d1, d2, d3, d4]; +[decimal|float, decimal|float, decimal|float, decimal|float] tup8 = [d1, f1, f9, 1.23]; +[string, string, string] tup9 = [s1, s2, s3]; +[anydata, anydata, anydata, anydata, anydata, anydata, anydata, anydata, + anydata, anydata, anydata, anydata, anydata, anydata, anydata, anydata, + anydata, anydata, anydata, anydata, anydata, anydata, anydata] tup10 = [b1, b2, b3, b4, + n1, n2, n3, i1, i2, i3, i4, i5, i6, i7, i8, f1, f2, f3, f4, f5, f6, f7, f8]; +[json, json, json, json, json, json, json, json, json, json, json, json, + json, json, json, json, json, json, json, json, json, json, json] tup11 = + [b1, b2, b3, b4, n1, n2, n3, i1, i2, i3, i4, i5, i6, i7, i8, f1, + f2, f3, f4, f5, f6, f7, f8]; +[string, string, int, int, boolean, boolean, (), (), decimal, decimal, float, float] tup12 = [ + s1, s2, i1, i2, b1, b2, n1, n3, d1, d2, f1, f2 +]; + +[boolean, boolean...] restTup1 = [b1, b2]; +[boolean?, boolean?, boolean?...] restTup2 = [b1, b2, b3, n1, n3]; +[boolean|int?...] restTup3 = [b1, b2, b3, b4, i1]; +[(), ()...] restTup4 = [n1, n3]; +[int...] restTup5 = [i1, i2, i3, i4, i5, i6]; +[float...] restTup6 = [f1, f2, f3, f4, f5, f6, f7]; +[decimal...] restTup7 = [d1, d2, d3, d4]; +[decimal|float, decimal|float...] restTup8 = [d1, f1, f9, 1.23]; +[string...] restTup9 = [s1, s2, s3]; +[anydata...] restTup10 = [b1, b2, b3, b4, n1, n2, n3, i1, i2, i3, i4, i5, i6, i7, i8, f1, f2, f3, f4, f5, f6, f7, f8]; +[json, json, json...] restTup11 = [b1, b2, b3, b4, n1, n2, n3, i1, i2, i3, i4, i5, i6, i7, i8, f1, f2, f3, f4, f5, f6, f7, f8]; +[string, string, int, int, boolean, boolean, (), (), decimal, decimal, float, float...] restTup12 = [ + s1, s2, i1, i2, b1, b2, n1, n3, d1, d2, f1, f2, f2, f2 +]; + +var booleanRecordArray = [ + {b1, b2, b3, b4}, {b1, b2, b3, b4} +]; + +var booleanRecordArray2 = [ + {},{} +]; + +string csvStringWithBooleanValues1 = string `b1,b2,b3,b4 +true,false,true,false +true,false, true,false +true,false,true,false +`; + +string csvStringWithBooleanValues2 = string `b1,b2,b3,b4,b5 +true,false, true,false,true +true,false, true,false,true`; + +string csvStringWithBooleanValues3 = string `b1,b2,b3 +${" "}${"\t"} +true, false,true +${" "} + TRUE, FALSE,() +${" "} + +true, true,FALSE + +`; + +string csvStringWithBooleanValues4 = string `b1,b2,b3,b4 + true,(), (),false + true,(), null,false + +`; + +string csvStringWithBooleanValues5 = string `b1,b2,b3,b4 + +true,false,true,2 + +true,false,true,3 +`; + +string csvStringWithBooleanValues6 = string `b2,b3 +(),() + +`; + +string csvStringWithBooleanValues7 = string `b1,b2,b3,b4 +${b1},${b2},(),${b4} +`; + +string csvStringData1 = string ` + a, b, c, d, e, f + 1, string1, true, 2.234, 2.234, () + 2, string2, false, 0, 0, null + 3, string3, false, 1.23, 1.23, () + 4, string4, true, -6.51, -6.51, () + 5, string5, true, 3, 3, ()`; + +string csvStringData2 = string ` + hello, hello, (), 12, true, 12.34 + // comment + + a, b, c, d, e, f + + + 1, string1, true, 2.234, 2.234, () + 2, string2, false, 0, 0, null + 3, string3, false, 1.23, 1.23, () + 4, string4, true, -6.51, -6.51, () + 5, string5, true, 3, 3, ()`; + +string csvStringData3 = string ` + a, b, c, d, e, f + + + + 1, string1, true, 2.234, 2.234, () + 2, string2, false, 0, 0, null + 3, string3, false, 1.23, 1.23, () + + 4, string4, true, -6.51, -6.51, () + 5, string5, true, 3, 3, ()`; + +string csvStringData4 = string ` + 1, string1, true, 2.234, 2.234, () + 2, string2, false, 0, 0, null + 3, string3, false, 1.23, 1.23, () + 4, string4, true, -6.51, -6.51, () + 5, string5, true, 3, 3, ()`; + +string csvStringData5 = string ` + + + + 1, string1, true, 2.234, 2.234, () + 2, string2, false, 0, 0, null + + 3, string3, false, 1.23, 1.23, () + 4, string4, true, -6.51, -6.51, () + + 5, string5, true, 3, 3, ()`; + +string csvStringData6 = string ` + + 1, string1, true, 2.234, 2.234, () + 2, string2, false, 0, 0, null + + 3, string3, false, 1.23, 1.23, () + 4, string4, true, -6.51, -6.51, () + + 5, string5, true, 3, 3, ()`; + +string csvStringData7 = string ` + a@ b@ c@ d@ e@ f + 1@ string@ true@ 2.234@ -3.21@ () + 2@ s,tring@ true@ 2.234@ -3.21@ null + 3@ stri,ng@ true@ 2.234@ -3.21@ () + 4@ string@ true@ 2.234@ -3.21@ () + 5@ string@ true@ 2.234@ -3.21@ ()`; +string csvStringData8 = string ` + a@ b@ c@ d@ e@ f + + + + 1@ stri,ng@ true@ 2.234@ -3.21@ () + 2@ string@ true@ 2.234@ ()@-3.21 + 3@ string@ true@ 2.234@ -3.21@ null + + 4@ s,tring@ true@ 2.234@ -3.21@ () + 5@ string@ true@ 2.234@ -3.21@ ()`; + +string csvStringData9 = string ` + + 1@ string@ true@ 2.234@ -3.21@ () + 2@ string@ true@ 2.234@ -3.21@ null + + 3@ string@ true@ 2.234@ -3.21@ () + 4@ string@ true@ 2.234@ ()@-3.21 + + 5@ string@ true@ 2.234@ -3.21@ null`; diff --git a/ballerina-tests/type-compatible-tests/tests/types.bal b/ballerina-tests/type-compatible-tests/tests/types.bal new file mode 100644 index 0000000..a2b4b2b --- /dev/null +++ b/ballerina-tests/type-compatible-tests/tests/types.bal @@ -0,0 +1,2534 @@ +type BooleanRecord1 record { + boolean b1; + boolean|string b2; + boolean|string? b3; + boolean b4; +}; + +type BooleanRecord2 record {| + boolean b1; + boolean|string b2; + boolean|string? b3; + boolean b4; +|}; + +type BooleanRecord3 record {| + boolean b1; + boolean? b3; +|}; + +type BooleanRecord4 record { + boolean b1; + boolean? b3; +}; + +type BooleanRecord5 record { + boolean b1; + boolean? b3; + string defaultableField = ""; + string? nillableField = (); +}; + +type BooleanRecord6 record {| + boolean b1; + boolean? b3; + string defaultableField = ""; + string? nillableField = (); +|}; + +type BooleanRecord7 record { + boolean b1; + boolean? b3; + string defaultableField = ""; + string? nillableField = (); + string requiredField; +}; + +type BooleanRecord8 record {| + boolean b1; + boolean? b3; + string defaultableField = ""; + string? nillableField = (); + string requiredField; +|}; + +type BooleanRecord9 record {| + boolean b1; + boolean? b3; + boolean?...; +|}; + +type BooleanRecord10 record {| + boolean...; +|}; + +type BooleanRecord11 record {| + boolean b1; + string defaultableField = ""; + string? nillableField = (); + boolean?|string...; +|}; + +type BooleanRecord12 record {| + boolean b1; + string defaultableField = ""; + string? nillableField = (); + string requiredField; + boolean...; +|}; + +type BooleanRecord13 record {| + string defaultableField = ""; + string? nillableField = (); + string|boolean...; +|}; + +type BooleanRecord14 record {| + string defaultableField = ""; + string? nillableField = (); + string requiredField; + boolean...; +|}; + +type BooleanRecord15 record {| + int b1; + string defaultableField = ""; + string? nillableField = (); + boolean?...; +|}; + +type BooleanRecord16 record {| + boolean?...; +|}; + +type BooleanRecord17 record {| + int...; +|}; + +type BooleanRecord18 record {| + boolean b2; + int?...; +|}; + +type NilRecord1 record { + () n1; + () n2; + () n3; +}; + +type NilRecord2 record {| + () n1; + () n2; + () n3; +|}; + +type NilRecord3 record {| + () n1; + () n4; +|}; + +type NilRecord4 record { + () n1; + () n4; +}; + +type NilRecord5 record { + () n1; + () n4; + string defaultableField = ""; + string? nillableField = (); +}; + +type NilRecord6 record {| + () n1; + () n4; + string defaultableField = ""; + string? nillableField = (); +|}; + +type NilRecord7 record { + () n1; + () n4; + string defaultableField = ""; + string? nillableField = (); + string requiredField; +}; + +type NilRecord8 record {| + () n1; + () n4; + string defaultableField = ""; + string? nillableField = (); + string requiredField; +|}; + +type NilRecord9 record {| + () n1; + () n2; + ()...; +|}; + +type NilRecord10 record {| + ()...; +|}; + +type NilRecord11 record {| + () n1; + string defaultableField = ""; + string? nillableField = (); + ()...; +|}; + +type NilRecord12 record {| + () n1; + string defaultableField = ""; + string? nillableField = (); + string requiredField; + ()...; +|}; + +type NilRecord13 record {| + string defaultableField = ""; + string? nillableField = (); + ()...; +|}; + +type NilRecord14 record {| + string defaultableField = ""; + string? nillableField = (); + string requiredField; + ()...; +|}; + +type IntegerRecord1 record { + int i1; + int i2; + int i3; + int? i4; + int? i5; + int i6; + int i7; + int? i8; +}; + +type IntegerRecord2 record {| + int i1; + int? i2; + int i3; + int i4; + int? i5; + int i6; + int i7; + int? i8; +|}; + +type IntegerRecord3 record {| + int i1; + int i4; + int i6; +|}; + +type IntegerRecord4 record { + int i1; + int i4; + int i6; +}; + +type IntegerRecord5 record { + int i1; + int i4; + int i6; + string defaultableField = ""; + string? nillableField = (); +}; + +type IntegerRecord6 record {| + int i1; + int i4; + int i6; + string defaultableField = ""; + string? nillableField = (); +|}; + +type IntegerRecord7 record { + int i1; + int i4; + int i6; + string defaultableField = ""; + string? nillableField = (); + string requiredField; +}; + +type IntegerRecord8 record {| + int i1; + int i4; + int i6; + string defaultableField = ""; + string? nillableField = (); + string requiredField; +|}; + +type IntegerRecord9 record {| + int i1; + int i2; + int...; +|}; + +type IntegerRecord10 record {| + int...; +|}; + +type IntegerRecord11 record {| + int i1; + string defaultableField = ""; + string? nillableField = (); + int...; +|}; + +type IntegerRecord12 record {| + int i1; + string defaultableField = ""; + string? nillableField = (); + string requiredField; + int...; +|}; + +type IntegerRecord13 record {| + string defaultableField = ""; + string? nillableField = (); + int...; +|}; + +type IntegerRecord14 record {| + string defaultableField = ""; + string? nillableField = (); + string requiredField; + int...; +|}; + +type FloatRecord1 record { + float f1; + float f2; + float f3; + float f4; + float f5; + float f6; + float f7; + float f8; +}; + +type FloatRecord2 record {| + float f1; + float f2; + float f3; + float f4; + float f5; + float f6; + float f7; + float f8; +|}; + +type FloatRecord3 record {| + float f1; + float f4; + float f7; +|}; + +type FloatRecord4 record { + float f1; + float f4; + float f7; +}; + +type FloatRecord5 record { + float f1; + float f4; + float f7; + string defaultableField = ""; + string? nillableField = (); +}; + +type FloatRecord6 record {| + float f1; + float f4; + float f7; + string defaultableField = ""; + string? nillableField = (); +|}; + +type FloatRecord7 record { + float f1; + float f4; + float f7; + string defaultableField = ""; + string? nillableField = (); + string requiredField; +}; + +type FloatRecord8 record {| + float f1; + float f4; + float f7; + string defaultableField = ""; + string? nillableField = (); + string requiredField; +|}; + +type FloatRecord9 record {| + float f1; + float f2; + float...; +|}; + +type FloatRecord10 record {| + float...; +|}; + +type FloatRecord11 record {| + float f1; + string defaultableField = ""; + string? nillableField = (); + float...; +|}; + +type FloatRecord12 record {| + float f1; + string defaultableField = ""; + string? nillableField = (); + string requiredField; + float...; +|}; + +type FloatRecord13 record {| + string defaultableField = ""; + string? nillableField = (); + float...; +|}; + +type FloatRecord14 record {| + string defaultableField = ""; + string? nillableField = (); + string requiredField; + float...; +|}; + +type DecimalRecord1 record { + decimal d1; + decimal d2; + decimal d3; + decimal d4; + decimal d5; + decimal d6; + decimal d7; + decimal d8; +}; + +type DecimalRecord2 record {| + decimal d1; + decimal d2; + decimal d3; + decimal d4; + decimal d5; + decimal d6; + decimal d7; + decimal d8; +|}; + +type DecimalRecord3 record {| + decimal d1; + decimal d4; + decimal d7; +|}; + +type DecimalRecord4 record { + decimal d1; + decimal d4; + decimal d7; +}; + +type DecimalRecord5 record { + decimal d1; + decimal d4; + decimal d7; + string defaultableField = ""; + string? nillableField = (); +}; + +type DecimalRecord6 record {| + decimal d1; + decimal d4; + decimal d7; + string defaultableField = ""; + string? nillableField = (); +|}; + +type DecimalRecord7 record { + decimal d1; + decimal d4; + decimal d7; + string defaultableField = ""; + string? nillableField = (); + string requiredField; +}; + +type DecimalRecord8 record {| + decimal d1; + decimal d4; + decimal d7; + string defaultableField = ""; + string? nillableField = (); + string requiredField; +|}; + +type DecimalRecord9 record {| + decimal d1; + decimal d2; + decimal...; +|}; + +type DecimalRecord10 record {| + decimal...; +|}; + +type DecimalRecord11 record {| + decimal d1; + string defaultableField = ""; + string? nillableField = (); + decimal...; +|}; + +type DecimalRecord12 record {| + decimal d1; + string defaultableField = ""; + string? nillableField = (); + string requiredField; + decimal...; +|}; + +type DecimalRecord13 record {| + string defaultableField = ""; + string? nillableField = (); + decimal...; +|}; + +type DecimalRecord14 record {| + string defaultableField = ""; + string? nillableField = (); + string requiredField; + decimal...; +|}; + +type StringRecord1 record { + string s1; + string s2; + string s3; +}; + +type StringRecord2 record {| + string s1; + string s2; + string s3; +|}; + +type StringRecord3 record {| + string s1; + string s4; +|}; + +type StringRecord4 record { + string s1; + string s4; +}; + +type StringRecord5 record { + string s1; + string s4; + string defaultableField = ""; + string? nillableField = (); +}; + +type StringRecord6 record {| + string s1; + string s4; + string defaultableField = ""; + string? nillableField = (); +|}; + +type StringRecord7 record { + string s1; + string s4; + string defaultableField = ""; + string? nillableField = (); + string requiredField; +}; + +type StringRecord8 record {| + string s1; + string s4; + string defaultableField = ""; + string? nillableField = (); + string requiredField; +|}; + +type StringRecord9 record {| + string s1; + string s2; + string...; +|}; + +type StringRecord10 record {| + string...; +|}; + +type StringRecord11 record {| + string s1; + string defaultableField = ""; + string? nillableField = (); + string...; +|}; + +type StringRecord12 record {| + string d1; + string defaultableField = ""; + string? nillableField = (); + string requiredField; + string...; +|}; + +type StringRecord13 record {| + string defaultableField = ""; + string? nillableField = (); + string...; +|}; + +type StringRecord14 record {| + string defaultableField = ""; + string? nillableField = (); + string requiredField; + string...; +|}; + +type StringRecord15 record {| + string defaultableField = ""; + string? nillableField = (); + string requiredField; + string...; +|}; + +type StringRecord16 record {| + string?...; +|}; + +type StringRecord17 record {| + int...; +|}; + +type StringRecord18 record {| + string b2; + int?...; +|}; + +type StringRecord19 record { + string s1 = ""; + string s2 = ""; +}; + +type StringRecord20 record {| + string s1 = ""; + string s2 = ""; +|}; + +type StringRecord21 record { +}; + +type StringRecord22 record {| + string s1 = ""; + string s2 = ""; + json...; +|}; + +type StringRecord23 record {| + json...; +|}; + +type JsonRecord1 record { + json j1; + json j2; + json j3; +}; + +type JsonRecord2 record {| + json j1; + json j2; + json j3; +|}; + +type JsonRecord3 record {| + json j1; + json j4; +|}; + +type JsonRecord4 record { + json j1; + json j4; +}; + +type JsonRecord5 record { + json j1; + json j4; + json defaultableField = ""; + json? nillableField = (); +}; + +type JsonRecord6 record {| + json j1; + json j4; + json defaultableField = ""; + json? nillableField = (); +|}; + +type JsonRecord7 record { + json j1; + json j4; + json defaultableField = ""; + json? nillableField = (); + json requiredField; +}; + +type JsonRecord8 record {| + json j1; + json j4; + json defaultableField = ""; + json? nillableField = (); + json requiredField; +|}; + +type JsonRecord9 record {| + json j1; + json j2; + json...; +|}; + +type JsonRecord10 record {| + json...; +|}; + +type JsonRecord11 record {| + json j1; + json defaultableField = ""; + json? nillableField = (); + json...; +|}; + +type JsonRecord12 record {| + json j1; + json defaultableField = ""; + json? nillableField = (); + json requiredField; + json...; +|}; + +type JsonRecord13 record {| + json defaultableField = ""; + json? nillableField = (); + json...; +|}; + +type JsonRecord14 record {| + json defaultableField = ""; + json? nillableField = (); + json requiredField; + json...; +|}; + +type AnydataRecord1 record { + anydata anydata1; + anydata anydata2; + anydata anydata3; +}; + +type AnydataRecord2 record {| + anydata anydata1; + anydata anydata2; + anydata anydata3; +|}; + +type AnydataRecord3 record {| + anydata anydata1; + anydata anydata4; +|}; + +type AnydataRecord4 record { + anydata anydata1; + anydata anydata4; +}; + +type AnydataRecord5 record { + anydata anydata1; + anydata anydata4; + anydata defaultableField = ""; + anydata? nillableField = (); +}; + +type AnydataRecord6 record {| + anydata anydata1; + anydata anydata4; + anydata defaultableField = ""; + anydata? nillableField = (); +|}; + +type AnydataRecord7 record { + anydata anydata1; + anydata anydata4; + anydata defaultableField = ""; + anydata? nillableField = (); + anydata requiredField; +}; + +type AnydataRecord8 record {| + anydata anydata1; + anydata anydata4; + anydata defaultableField = ""; + anydata? nillableField = (); + anydata requiredField; +|}; + +type AnydataRecord9 record {| + anydata anydata1; + anydata anydata2; + anydata...; +|}; + +type AnydataRecord10 record {| + anydata...; +|}; + +type AnydataRecord11 record {| + anydata anydata1; + anydata defaultableField = ""; + anydata? nillableField = (); + anydata...; +|}; + +type AnydataRecord12 record {| + anydata anydata1; + anydata defaultableField = ""; + anydata? nillableField = (); + anydata requiredField; + anydata...; +|}; + +type AnydataRecord13 record {| + anydata defaultableField = ""; + anydata? nillableField = (); + anydata...; +|}; + +type AnydataRecord14 record {| + anydata defaultableField = ""; + anydata? nillableField = (); + anydata requiredField; + anydata...; +|}; + +type CustomRecord1 record { + int i1; + int i2; + string s1; + string s2; + boolean b1; + boolean b2; + () n1; + () n2; + float f1; + float f2; + decimal d1; + decimal d2; +}; + +type CustomRecord2 record {| + int i1; + int i2; + string s1; + string s2; + boolean b1; + boolean b2; + () n1; + () n2; + float f1; + float f2; + decimal d1; + decimal d2; +|}; + +type CustomRecord3 record {| + int i1; + string s1; + boolean b1; + () n1; + float f1; + decimal d1; +|}; + +type CustomRecord4 record { + int i1; + string s1; + boolean b1; + () n1; + float f1; + decimal d1; +}; + +type CustomRecord5 record { + int i1; + string s1; + boolean b1; + () n1; + float f1; + decimal d1; + string defaultableField = ""; + string? nillableField = (); +}; + +type CustomRecord6 record {| + int i1; + string s1; + boolean b1; + () n1; + float f1; + decimal d1; + anydata defaultableField = ""; + anydata? nillableField = (); +|}; + +type CustomRecord7 record { + int i1; + string s1; + boolean b1; + () n1; + float f1; + decimal d1; + anydata defaultableField = ""; + anydata? nillableField = (); + anydata requiredField; +}; + +type CustomRecord8 record {| + int i1; + string s1; + boolean b1; + () n1; + float f1; + decimal d1; + anydata defaultableField = ""; + anydata? nillableField = (); + anydata requiredField; +|}; + +type CustomRecord9 record {| + int i1; + string s1; + boolean b1; + () n1; + float f1; + decimal d1; + string...; +|}; + +type CustomRecord10 record {| + string...; +|}; + +type CustomRecord11 record {| + int i1; + string s1; + boolean b1; + () n1; + float f1; + decimal d1; + anydata defaultableField = ""; + anydata? nillableField = (); + string...; +|}; + +type CustomRecord12 record {| + int i1; + string s1; + boolean b1; + () n1; + float f1; + decimal d1; + anydata defaultableField = ""; + anydata? nillableField = (); + anydata requiredField; + string...; +|}; + +type CustomRecord13 record {| + anydata defaultableField = ""; + anydata? nillableField = (); + string...; +|}; + +type CustomRecord14 record {| + anydata defaultableField = ""; + anydata? nillableField = (); + anydata requiredField; + string...; +|}; + +type CustomRecord15 record {| + string '1; + string '2; +|}; + +type CustomRecord16 record {| + string '1; + string '2; + string '3; + string '4; +|}; + +type CustomRecord17 record { + string '1; + string '2; +}; + +type CustomRecord18 record { + string '1; + string '2; + string '3; + string '4; +}; + +type CustomRecord19 record { + string '1; + string '2; + string '3 = ""; + string '4 = ""; +}; + +type CustomRecord20 record { + string '1; +}; + +type CustomRecord21 record {| + string '1; + json...; +|}; + +type CustomRecord22 record {| + string '1; + string...; +|}; + +type CustomRecord23 record {| + string '1; + string a = ""; + string...; +|}; + +type CustomRecord24 record {| + string '1; + string '2 = ""; + string...; +|}; + +type CustomRecord25 record {| + int '1; + string...; +|}; + +type CustomRecord26 record {| + string '1; + int...; +|}; + +type CustomRecord27 record {| + int i1; + string s1; + boolean b1; + () n1; + float f1; + decimal d1; + anydata a1; + json j1; + anydata defaultableField = ""; + anydata? nillableField = (); + string...; +|}; + +type CustomRecord28 record { + string '1; +}; + +type CustomRecord29 record { + int '1; +}; + +type CustomRecord30 record {| + string '1; + string '2; + string '3; + string '4; + string '5; + string '6; +|}; + +type CustomRecord31 record {| + string '1; + string '6; +|}; + +type CustomRecord32 record {| + int '1; +|}; + +type CustomRecord33 record {| + string '1; + string '2; + string '3; + string '4; + string '5; + string '6; +|}; + +type CustomRecord34 record { + string '1; + string '6; + string '5 = ""; +}; + +type CustomRecord35 record { + string '1; + string '6; + string '9 = ""; +}; + +type CustomRecord36 record {| + string '1; + string '6; + string '9 = ""; +|}; + +type CustomRecord37 record {| + string '1; + string '6; + string '5 = ""; +|}; + +type CustomRecord38 record {| + string '1; + string '2; + string '3; + string '4; + string '5; + string '6; + string ...; +|}; + +type CustomRecord39 record {| + string '1; + string '2; + string '3; + string '4; + string '5; + string '6; + json ...; +|}; + +type CustomRecord40 record {| + string '5; + string '6; + json ...; +|}; + +type CustomRecord41 record {| + json ...; +|}; + +type CustomRecord42 record {| + int '1; + string '2; + boolean '3; + decimal '4; + float '5; + () '6; +|}; + +type CustomRecord43 record { + int '1; + string '2; + boolean '3; + decimal '4; + float '5; + () '6; +}; + +type CustomRecord44 record {| + int '1; + string '2; + boolean '3; + decimal '4; + float '5; + () '6; + string ...; +|}; + +type CustomRecord45 record {| + int H1; + string H2; + boolean H3; + decimal H4; + float H5; + () H6; +|}; + +type CustomRecord46 record { + int H1; + string H2; + boolean H3; + decimal H4; + float H5; + () H6; +}; + +type CustomRecord47 record {| + int H1; + string H2; + boolean H3; + decimal H4; + float H5; + () H6; + string ...; +|}; + +type CustomRecord48 record { + string H1; + string H2; + string H3; + string H4; + string H5; + string H6; +}; + +type CustomRecord49 record {| + string H1; + string H2; + string H3; + string H4; + string H5; + string H6; +|}; + +type CustomRecord50 record { + int H1; + float H4; +}; + +type CustomRecord51 record {| + int H1; + float H4; +|}; + +type CustomRecord52 record {| + string H1; + string H4; + string ...; +|}; + +type CustomRecord53 record {| + int H1; + float H4; + decimal ...; +|}; + +type CustomRecord54 record {| + string H1 = ""; + string H4; + string '1; +|}; + +type CustomRecord55 record {| + string H1 = ""; + string H4 = ""; + int '1 = 10; +|}; + +type CustomRecord56 record { + string H1 = ""; + string H4 = ""; + anydata '1 = 10; +}; + +type BooleanTuple1 [boolean, boolean, boolean, boolean]; + +type BooleanTuple2 [boolean, boolean]; + +type BooleanTuple3 [boolean, boolean...]; + +type BooleanTuple4 [boolean...]; + +type NillableBooleanTuple5 [boolean?, boolean?, boolean?, boolean?, boolean?]; + +type NillableBooleanTuple6 [boolean?, boolean?]; + +type NillableBooleanTuple7 [boolean?, boolean?, boolean?...]; + +type NillableBooleanTuple8 [boolean?...]; + +type NillableIntBooleanTuple9 [int|boolean?, int|boolean?...]; + +type NilTuple1 [(), (), ()]; + +type NilTuple2 [(), ()]; + +type NilTuple3 [(), ()...]; + +type NilTuple4 [()...]; + +type IntegerTuple1 [int, int, int, int, int, int]; + +type IntegerTuple2 [int, int]; + +type IntegerTuple3 [int, int...]; + +type IntegerTuple4 [int...]; + +type FloatTuple1 [float, float, float, float, float, float, float]; + +type FloatTuple2 [float, float]; + +type FloatTuple3 [float, float...]; + +type FloatTuple4 [float...]; + +type DecimalTuple1 [decimal, decimal, decimal, decimal]; + +type DecimalTuple2 [decimal, decimal]; + +type DecimalTuple3 [decimal, decimal...]; + +type DecimalTuple4 [decimal...]; + +type StringTuple1 [string, string, string, string]; + +type StringTuple2 [string, string]; + +type StringTuple3 [string, string...]; + +type StringTuple4 [string...]; + +type AnydataTuple1 [anydata, anydata, anydata, anydata, anydata, + anydata, anydata, anydata, anydata, anydata, anydata, anydata, + anydata, anydata, anydata, anydata, anydata, anydata, anydata, + anydata, anydata, anydata, anydata]; + +type AnydataTuple2 [anydata, anydata]; + +type AnydataTuple3 [anydata, anydata...]; + +type AnydataTuple4 [anydata...]; + +type JsonTuple1 [json, json, json, json, json, json, json, json, + json, json, json, json, json, json, json, json, json, json, + json, json, json, json, json]; + +type JsonTuple2 [json, json]; + +type JsonTuple3 [json, json...]; + +type JsonTuple4 [json...]; + +type CustomTuple1 [string, int, decimal, float, (), boolean, anydata, json, string, int, decimal, float, (), boolean, anydata, json]; + +type CustomTuple2 [string, int, decimal, float, (), boolean, anydata, json]; + +type CustomTuple3 [string, int, decimal, float, (), boolean, anydata, json, string...]; + +type CustomTuple4 [string...]; + +type CustomTuple5 [string, int, decimal, float, (), boolean, anydata, json, anydata...]; + +type CustomTuple6 [anydata...]; + +type CustomTuple7 [int, string, boolean, (), float, decimal, json, anydata, string...]; + +type CustomTuple8 [int, string, boolean, (), float, decimal, json, anydata, int...]; + +type IntegerArray1 int[]; + +type IntegerArray2 int[2]; + +type IntegerArray3 int[]; + +type IntegerArray4 int[2]; + +type IntegerArray5 int[3]; + +type IntegerArray6 int[4]; + +type StringArray string[]; + +type NillableStringArray string?[]; + +type NillableIntOrUnionStringArray (int|string?)[]; + +type StringArray1 string[]; + +type StringArray2 string[2]; + +type StringArray3 string[]; + +type StringArray4 string[2]; + +type StringArray5 string[3]; + +type StringArray6 string[4]; + +type FloatArray1 float[]; + +type FloatArray2 float[2]; + +type FloatArray3 float[]; + +type FloatArray4 float[2]; + +type FloatArray5 float[3]; + +type FloatArray6 float[4]; + +type DecimalArray1 decimal[]; + +type DecimalArray2 decimal[2]; + +type DecimalArray3 decimal[]; + +type DecimalArray4 decimal[2]; + +type DecimalArray5 decimal[3]; + +type DecimalArray6 decimal[4]; + +type BooleanArray boolean[]; + +type NillableBooleanArray boolean?[]; + +type NillableIntOrUnionBooleanArray (int|boolean?)[]; + +type BooleanArray2 boolean[2]; + +type BooleanArray3 boolean[3]; + +type BooleanArray4 boolean[]; + +type BooleanArray5 boolean[2]; + +type BooleanArray6 boolean[4]; + +type NilArray1 ()[]; + +type NilArray2 ()[2]; + +type NilArray3 ()[]; + +type NilArray4 ()[2]; + +type NilArray5 ()[3]; + +type NilArray6 ()[4]; + +type JsonArray1 json[]; + +type JsonArray2 json[2]; + +type JsonArray3 json[]; + +type JsonArray4 json[2]; + +type JsonArray5 json[3]; + +type JsonArray6 json[4]; + +type AnydataArray1 anydata[]; + +type AnydataArray2 anydata[2]; + +type AnydataArray3 anydata[]; + +type AnydataArray4 anydata[2]; + +type AnydataArray5 anydata[3]; + +type AnydataArray6 anydata[4]; + +type CustomArray1 CustomTuple2[]; + +type CustomArray2 CustomTuple2[2]; + +type CustomArray3 CustomTuple2[]; + +type CustomArray4 CustomTuple2[2]; + +type CustomArray5 CustomTuple2[3]; + +type CustomArray6 CustomTuple2[4]; + +type IntegerMap map; + +type StringMap map; + +type NillableIntUnionStringMap map; + +type IntUnionStringMap map; + +type DecimalMap map; + +type FloatMap map; + +type BooleanMap map; + +type NillableBooleanMap map; + +type NillableIntUnionBooleanMap map; + +type IntUnionBooleanMap map; + +type NilMap map<()>; + +type JsonMap map; + +type AnydataMap map; + +type CustomMap map; + +type BooleanRecord1Array BooleanRecord1[]; + +type ClosedBooleanRecord1Array BooleanRecord1[3]; + +type BooleanRecord2Array BooleanRecord2[]; + +type ClosedBooleanRecord2Array BooleanRecord2[3]; + +type BooleanRecord3Array BooleanRecord3[]; + +type ClosedBooleanRecord3Array BooleanRecord3[3]; + +type BooleanRecord4Array BooleanRecord4[]; + +type ClosedBooleanRecord4Array BooleanRecord4[3]; + +type BooleanRecord5Array BooleanRecord5[]; + +type ClosedBooleanRecord5Array BooleanRecord5[3]; + +type BooleanRecord6Array BooleanRecord6[]; + +type ClosedBooleanRecord6Array BooleanRecord6[3]; + +type BooleanRecord7Array BooleanRecord7[]; + +type ClosedBooleanRecord7Array BooleanRecord7[3]; + +type BooleanRecord8Array BooleanRecord8[]; + +type ClosedBooleanRecord8Array BooleanRecord8[3]; + +type BooleanRecord9Array BooleanRecord9[]; + +type ClosedBooleanRecord9Array BooleanRecord9[3]; + +type BooleanRecord10Array BooleanRecord10[]; + +type ClosedBooleanRecord10Array BooleanRecord10[3]; + +type BooleanRecord11Array BooleanRecord11[]; + +type ClosedBooleanRecord11Array BooleanRecord11[3]; + +type BooleanRecord12Array BooleanRecord12[]; + +type ClosedBooleanRecord12Array BooleanRecord12[3]; + +type BooleanRecord13Array BooleanRecord13[]; + +type ClosedBooleanRecord13Array BooleanRecord13[3]; + +type BooleanRecord14Array BooleanRecord14[]; + +type ClosedBooleanRecord14Array BooleanRecord14[3]; + +type BooleanRecord15Array BooleanRecord15[]; + +type ClosedBooleanRecord15Array BooleanRecord15[3]; + +type BooleanRecord16Array BooleanRecord16[]; + +type ClosedBooleanRecord16Array BooleanRecord16[3]; + +type BooleanRecord17Array BooleanRecord17[]; + +type ClosedBooleanRecord17Array BooleanRecord17[3]; + +type BooleanRecord18Array BooleanRecord18[]; + +type ClosedBooleanRecord18Array BooleanRecord18[3]; + +type NilRecord1Array NilRecord1[]; + +type ClosedNilRecord1Array NilRecord1[3]; + +type NilRecord2Array NilRecord2[]; + +type ClosedNilRecord2Array NilRecord2[3]; + +type NilRecord3Array NilRecord3[]; + +type ClosedNilRecord3Array NilRecord3[3]; + +type NilRecord4Array NilRecord4[]; + +type ClosedNilRecord4Array NilRecord4[3]; + +type NilRecord5Array NilRecord5[]; + +type ClosedNilRecord5Array NilRecord5[3]; + +type NilRecord6Array NilRecord6[]; + +type ClosedNilRecord6Array NilRecord6[3]; + +type NilRecord7Array NilRecord7[]; + +type ClosedNilRecord7Array NilRecord7[3]; + +type NilRecord8Array NilRecord8[]; + +type ClosedNilRecord8Array NilRecord8[3]; + +type NilRecord9Array NilRecord9[]; + +type ClosedNilRecord9Array NilRecord9[3]; + +type NilRecord10Array NilRecord10[]; + +type ClosedNilRecord10Array NilRecord10[3]; + +type NilRecord11Array NilRecord11[]; + +type ClosedNilRecord11Array NilRecord11[3]; + +type NilRecord12Array NilRecord12[]; + +type ClosedNilRecord12Array NilRecord12[3]; + +type NilRecord13Array NilRecord13[]; + +type ClosedNilRecord13Array NilRecord13[3]; + +type NilRecord14Array NilRecord14[]; + +type ClosedNilRecord14Array NilRecord14[3]; + +type IntegerRecord1Array IntegerRecord1[]; + +type ClosedIntegerRecord1Array IntegerRecord1[3]; + +type IntegerRecord2Array IntegerRecord2[]; + +type ClosedIntegerRecord2Array IntegerRecord2[3]; + +type IntegerRecord3Array IntegerRecord3[]; + +type ClosedIntegerRecord3Array IntegerRecord3[3]; + +type IntegerRecord4Array IntegerRecord4[]; + +type ClosedIntegerRecord4Array IntegerRecord4[3]; + +type IntegerRecord5Array IntegerRecord5[]; + +type ClosedIntegerRecord5Array IntegerRecord5[3]; + +type IntegerRecord6Array IntegerRecord6[]; + +type ClosedIntegerRecord6Array IntegerRecord6[3]; + +type IntegerRecord7Array IntegerRecord7[]; + +type ClosedIntegerRecord7Array IntegerRecord7[3]; + +type IntegerRecord8Array IntegerRecord8[]; + +type ClosedIntegerRecord8Array IntegerRecord8[3]; + +type IntegerRecord9Array IntegerRecord9[]; + +type ClosedIntegerRecord9Array IntegerRecord9[3]; + +type IntegerRecord10Array IntegerRecord10[]; + +type ClosedIntegerRecord10Array IntegerRecord10[3]; + +type IntegerRecord11Array IntegerRecord11[]; + +type ClosedIntegerRecord11Array IntegerRecord11[3]; + +type IntegerRecord12Array IntegerRecord12[]; + +type ClosedIntegerRecord12Array IntegerRecord12[3]; + +type IntegerRecord13Array IntegerRecord13[]; + +type ClosedIntegerRecord13Array IntegerRecord13[3]; + +type IntegerRecord14Array IntegerRecord14[]; + +type ClosedIntegerRecord14Array IntegerRecord14[3]; + +type FloatRecord1Array FloatRecord1[]; + +type ClosedFloatRecord1Array FloatRecord1[3]; + +type FloatRecord2Array FloatRecord2[]; + +type ClosedFloatRecord2Array FloatRecord2[3]; + +type FloatRecord3Array FloatRecord3[]; + +type ClosedFloatRecord3Array FloatRecord3[3]; + +type FloatRecord4Array FloatRecord4[]; + +type ClosedFloatRecord4Array FloatRecord4[3]; + +type FloatRecord5Array FloatRecord5[]; + +type ClosedFloatRecord5Array FloatRecord5[3]; + +type FloatRecord6Array FloatRecord6[]; + +type ClosedFloatRecord6Array FloatRecord6[3]; + +type FloatRecord7Array FloatRecord7[]; + +type ClosedFloatRecord7Array FloatRecord7[3]; + +type FloatRecord8Array FloatRecord8[]; + +type ClosedFloatRecord8Array FloatRecord8[3]; + +type FloatRecord9Array FloatRecord9[]; + +type ClosedFloatRecord9Array FloatRecord9[3]; + +type FloatRecord10Array FloatRecord10[]; + +type ClosedFloatRecord10Array FloatRecord10[3]; + +type FloatRecord11Array FloatRecord11[]; + +type ClosedFloatRecord11Array FloatRecord11[3]; + +type FloatRecord12Array FloatRecord12[]; + +type ClosedFloatRecord12Array FloatRecord12[3]; + +type FloatRecord13Array FloatRecord13[]; + +type ClosedFloatRecord13Array FloatRecord13[3]; + +type FloatRecord14Array FloatRecord14[]; + +type ClosedFloatRecord14Array FloatRecord14[3]; + +type DecimalRecord1Array DecimalRecord1[]; + +type ClosedDecimalRecord1Array DecimalRecord1[3]; + +type DecimalRecord2Array DecimalRecord2[]; + +type ClosedDecimalRecord2Array DecimalRecord2[3]; + +type DecimalRecord3Array DecimalRecord3[]; + +type ClosedDecimalRecord3Array DecimalRecord3[3]; + +type DecimalRecord4Array DecimalRecord4[]; + +type ClosedDecimalRecord4Array DecimalRecord4[3]; + +type DecimalRecord5Array DecimalRecord5[]; + +type ClosedDecimalRecord5Array DecimalRecord5[3]; + +type DecimalRecord6Array DecimalRecord6[]; + +type ClosedDecimalRecord6Array DecimalRecord6[3]; + +type DecimalRecord7Array DecimalRecord7[]; + +type ClosedDecimalRecord7Array DecimalRecord7[3]; + +type DecimalRecord8Array DecimalRecord8[]; + +type ClosedDecimalRecord8Array DecimalRecord8[3]; + +type DecimalRecord9Array DecimalRecord9[]; + +type ClosedDecimalRecord9Array DecimalRecord9[3]; + +type DecimalRecord10Array DecimalRecord10[]; + +type ClosedDecimalRecord10Array DecimalRecord10[3]; + +type DecimalRecord11Array DecimalRecord11[]; + +type ClosedDecimalRecord11Array DecimalRecord11[3]; + +type DecimalRecord12Array DecimalRecord12[]; + +type ClosedDecimalRecord12Array DecimalRecord12[3]; + +type DecimalRecord13Array DecimalRecord13[]; + +type ClosedDecimalRecord13Array DecimalRecord13[3]; + +type DecimalRecord14Array DecimalRecord14[]; + +type ClosedDecimalRecord14Array DecimalRecord14[3]; + +type StringRecord1Array StringRecord1[]; + +type ClosedStringRecord1Array StringRecord1[3]; + +type StringRecord2Array StringRecord2[]; + +type ClosedStringRecord2Array StringRecord2[3]; + +type StringRecord3Array StringRecord3[]; + +type ClosedStringRecord3Array StringRecord3[3]; + +type StringRecord4Array StringRecord4[]; + +type ClosedStringRecord4Array StringRecord4[3]; + +type StringRecord5Array StringRecord5[]; + +type ClosedStringRecord5Array StringRecord5[3]; + +type StringRecord6Array StringRecord6[]; + +type ClosedStringRecord6Array StringRecord6[3]; + +type StringRecord7Array StringRecord7[]; + +type ClosedStringRecord7Array StringRecord7[3]; + +type StringRecord8Array StringRecord8[]; + +type ClosedStringRecord8Array StringRecord8[3]; + +type StringRecord9Array StringRecord9[]; + +type ClosedStringRecord9Array StringRecord9[3]; + +type StringRecord10Array StringRecord10[]; + +type ClosedStringRecord10Array StringRecord10[3]; + +type StringRecord11Array StringRecord11[]; + +type ClosedStringRecord11Array StringRecord11[3]; + +type StringRecord12Array StringRecord12[]; + +type ClosedStringRecord12Array StringRecord12[3]; + +type StringRecord13Array StringRecord13[]; + +type ClosedStringRecord13Array StringRecord13[3]; + +type StringRecord14Array StringRecord14[]; + +type ClosedStringRecord14Array StringRecord14[3]; + +type StringRecord15Array StringRecord15[]; + +type StringRecord16Array StringRecord16[]; + +type StringRecord17Array StringRecord17[]; + +type StringRecord18Array StringRecord18[]; + +type StringRecord19Array StringRecord19[]; + +type StringRecord20Array StringRecord20[]; + +type StringRecord21Array StringRecord21[]; + +type StringRecord22Array StringRecord22[]; + +type StringRecord23Array StringRecord23[]; + +type JsonRecord1Array JsonRecord1[]; + +type ClosedJsonRecord1Array JsonRecord1[3]; + +type JsonRecord2Array JsonRecord2[]; + +type ClosedJsonRecord2Array JsonRecord2[3]; + +type JsonRecord3Array JsonRecord3[]; + +type ClosedJsonRecord3Array JsonRecord3[3]; + +type JsonRecord4Array JsonRecord4[]; + +type ClosedJsonRecord4Array JsonRecord4[3]; + +type JsonRecord5Array JsonRecord5[]; + +type ClosedJsonRecord5Array JsonRecord5[3]; + +type JsonRecord6Array JsonRecord6[]; + +type ClosedJsonRecord6Array JsonRecord6[3]; + +type JsonRecord7Array JsonRecord7[]; + +type ClosedJsonRecord7Array JsonRecord7[3]; + +type JsonRecord8Array JsonRecord8[]; + +type ClosedJsonRecord8Array JsonRecord8[3]; + +type JsonRecord9Array JsonRecord9[]; + +type ClosedJsonRecord9Array JsonRecord9[3]; + +type JsonRecord10Array JsonRecord10[]; + +type ClosedJsonRecord10Array JsonRecord10[3]; + +type JsonRecord11Array JsonRecord11[]; + +type ClosedJsonRecord11Array JsonRecord11[3]; + +type JsonRecord12Array JsonRecord12[]; + +type ClosedJsonRecord12Array JsonRecord12[3]; + +type JsonRecord13Array JsonRecord13[]; + +type ClosedJsonRecord13Array JsonRecord13[3]; + +type JsonRecord14Array JsonRecord14[]; + +type ClosedJsonRecord14Array JsonRecord14[3]; + +type AnydataRecord1Array AnydataRecord1[]; + +type ClosedAnydataRecord1Array AnydataRecord1[3]; + +type AnydataRecord2Array AnydataRecord2[]; + +type ClosedAnydataRecord2Array AnydataRecord2[3]; + +type AnydataRecord3Array AnydataRecord3[]; + +type ClosedAnydataRecord3Array AnydataRecord3[3]; + +type AnydataRecord4Array AnydataRecord4[]; + +type ClosedAnydataRecord4Array AnydataRecord4[3]; + +type AnydataRecord5Array AnydataRecord5[]; + +type ClosedAnydataRecord5Array AnydataRecord5[3]; + +type AnydataRecord6Array AnydataRecord6[]; + +type ClosedAnydataRecord6Array AnydataRecord6[3]; + +type AnydataRecord7Array AnydataRecord7[]; + +type ClosedAnydataRecord7Array AnydataRecord7[3]; + +type AnydataRecord8Array AnydataRecord8[]; + +type ClosedAnydataRecord8Array AnydataRecord8[3]; + +type AnydataRecord9Array AnydataRecord9[]; + +type ClosedAnydataRecord9Array AnydataRecord9[3]; + +type AnydataRecord10Array AnydataRecord10[]; + +type ClosedAnydataRecord10Array AnydataRecord10[3]; + +type AnydataRecord11Array AnydataRecord11[]; + +type ClosedAnydataRecord11Array AnydataRecord11[3]; + +type AnydataRecord12Array AnydataRecord12[]; + +type ClosedAnydataRecord12Array AnydataRecord12[3]; + +type AnydataRecord13Array AnydataRecord13[]; + +type ClosedAnydataRecord13Array AnydataRecord13[3]; + +type AnydataRecord14Array AnydataRecord14[]; + +type ClosedAnydataRecord14Array AnydataRecord14[3]; + +type CustomRecord1Array CustomRecord1[]; + +type ClosedCustomRecord1Array CustomRecord1[3]; + +type CustomRecord2Array CustomRecord2[]; + +type ClosedCustomRecord2Array CustomRecord2[3]; + +type CustomRecord3Array CustomRecord3[]; + +type ClosedCustomRecord3Array CustomRecord3[3]; + +type CustomRecord4Array CustomRecord4[]; + +type ClosedCustomRecord4Array CustomRecord4[3]; + +type CustomRecord5Array CustomRecord5[]; + +type ClosedCustomRecord5Array CustomRecord5[3]; + +type CustomRecord6Array CustomRecord6[]; + +type ClosedCustomRecord6Array CustomRecord6[3]; + +type CustomRecord7Array CustomRecord7[]; + +type ClosedCustomRecord7Array CustomRecord7[3]; + +type CustomRecord8Array CustomRecord8[]; + +type ClosedCustomRecord8Array CustomRecord8[3]; + +type CustomRecord9Array CustomRecord9[]; + +type ClosedCustomRecord9Array CustomRecord9[3]; + +type CustomRecord10Array CustomRecord10[]; + +type ClosedCustomRecord10Array CustomRecord10[3]; + +type CustomRecord11Array CustomRecord11[]; + +type ClosedCustomRecord11Array CustomRecord11[3]; + +type CustomRecord12Array CustomRecord12[]; + +type ClosedCustomRecord12Array CustomRecord12[3]; + +type CustomRecord13Array CustomRecord13[]; + +type ClosedCustomRecord13Array CustomRecord13[3]; + +type CustomRecord14Array CustomRecord14[]; + +type ClosedCustomRecord14Array CustomRecord14[3]; + +type CustomRecord15Array CustomRecord15[]; + +type CustomRecord16Array CustomRecord16[]; + +type CustomRecord17Array CustomRecord17[]; + +type CustomRecord18Array CustomRecord18[]; + +type CustomRecord19Array CustomRecord19[]; + +type CustomRecord20Array CustomRecord20[]; + +type CustomRecord21Array CustomRecord21[]; + +type CustomRecord22Array CustomRecord22[]; + +type CustomRecord23Array CustomRecord23[]; + +type CustomRecord24Array CustomRecord24[]; + +type CustomRecord25Array CustomRecord25[]; + +type CustomRecord26Array CustomRecord26[]; + +type CustomRecord27Array CustomRecord27[]; +type CustomRecord28Array CustomRecord28[]; +type CustomRecord29Array CustomRecord29[]; +type CustomRecord30Array CustomRecord30[]; +type CustomRecord31Array CustomRecord31[]; +type CustomRecord32Array CustomRecord32[]; +type CustomRecord33Array CustomRecord33[]; +type CustomRecord34Array CustomRecord34[]; +type CustomRecord35Array CustomRecord35[]; +type CustomRecord36Array CustomRecord36[]; +type CustomRecord37Array CustomRecord37[]; +type CustomRecord38Array CustomRecord38[]; +type CustomRecord39Array CustomRecord39[]; +type CustomRecord40Array CustomRecord40[]; +type CustomRecord41Array CustomRecord41[]; +type CustomRecord42Array CustomRecord42[]; +type CustomRecord43Array CustomRecord43[]; +type CustomRecord44Array CustomRecord44[]; +type CustomRecord45Array CustomRecord45[]; +type CustomRecord46Array CustomRecord46[]; +type CustomRecord47Array CustomRecord47[]; +type CustomRecord48Array CustomRecord48[]; +type CustomRecord49Array CustomRecord49[]; +type CustomRecord50Array CustomRecord50[]; +type CustomRecord51Array CustomRecord51[]; +type CustomRecord52Array CustomRecord52[]; +type CustomRecord53Array CustomRecord53[]; +type CustomRecord54Array CustomRecord54[]; +type CustomRecord55Array CustomRecord55[]; +type CustomRecord56Array CustomRecord56[]; + +type BooleanTuple1Array BooleanTuple1[]; + +type ClosedBooleanTuple1Array BooleanTuple1[3]; + +type BooleanTuple2Array BooleanTuple2[]; + +type ClosedBooleanTuple2Array BooleanTuple2[3]; + +type BooleanTuple3Array BooleanTuple3[]; + +type ClosedBooleanTuple3Array BooleanTuple3[3]; + +type BooleanTuple4Array BooleanTuple4[]; + +type ClosedBooleanTuple4Array BooleanTuple4[3]; + +type NillableBooleanTuple5Array NillableBooleanTuple5[]; + +type NillableBooleanTuple6Array NillableBooleanTuple6[]; + +type NillableBooleanTuple7Array NillableBooleanTuple7[]; + +type NillableBooleanTuple8Array NillableBooleanTuple8[]; + +type NillableIntBooleanTuple9Array NillableIntBooleanTuple9[]; + +type NilTuple1Array NilTuple1[]; + +type ClosedNilTuple1Array NilTuple1[3]; + +type NilTuple2Array NilTuple2[]; + +type ClosedNilTuple2Array NilTuple2[3]; + +type NilTuple3Array NilTuple3[]; + +type ClosedNilTuple3Array NilTuple3[3]; + +type NilTuple4Array NilTuple4[]; + +type ClosedNilTuple4Array NilTuple4[3]; + +type IntegerTuple1Array IntegerTuple1[]; + +type ClosedIntegerTuple1Array IntegerTuple1[3]; + +type IntegerTuple2Array IntegerTuple2[]; + +type ClosedIntegerTuple2Array IntegerTuple2[3]; + +type IntegerTuple3Array IntegerTuple3[]; + +type ClosedIntegerTuple3Array IntegerTuple3[3]; + +type IntegerTuple4Array IntegerTuple4[]; + +type ClosedIntegerTuple4Array IntegerTuple4[3]; + +type FloatTuple1Array FloatTuple1[]; + +type ClosedFloatTuple1Array FloatTuple1[3]; + +type FloatTuple2Array FloatTuple2[]; + +type ClosedFloatTuple2Array FloatTuple2[3]; + +type FloatTuple3Array FloatTuple3[]; + +type ClosedFloatTuple3Array FloatTuple3[3]; + +type FloatTuple4Array FloatTuple4[]; + +type ClosedFloatTuple4Array FloatTuple4[3]; + +type DecimalTuple1Array DecimalTuple1[]; + +type ClosedDecimalTuple1Array DecimalTuple1[3]; + +type DecimalTuple2Array DecimalTuple2[]; + +type ClosedDecimalTuple2Array DecimalTuple2[3]; + +type DecimalTuple3Array DecimalTuple3[]; + +type ClosedDecimalTuple3Array DecimalTuple3[3]; + +type DecimalTuple4Array DecimalTuple4[]; + +type ClosedDecimalTuple4Array DecimalTuple4[3]; + +type StringTuple1Array StringTuple1[]; + +type ClosedStringTuple1Array StringTuple1[3]; + +type StringTuple2Array StringTuple2[]; + +type ClosedStringTuple2Array StringTuple2[3]; + +type StringTuple3Array StringTuple3[]; + +type ClosedStringTuple3Array StringTuple3[3]; + +type StringTuple4Array StringTuple4[]; + +type ClosedStringTuple4Array StringTuple4[3]; + +type AnydataTuple1Array AnydataTuple1[]; + +type ClosedAnydataTuple1Array AnydataTuple1[3]; + +type AnydataTuple2Array AnydataTuple2[]; + +type ClosedAnydataTuple2Array AnydataTuple2[3]; + +type AnydataTuple3Array AnydataTuple3[]; + +type ClosedAnydataTuple3Array AnydataTuple3[3]; + +type AnydataTuple4Array AnydataTuple4[]; + +type ClosedAnydataTuple4Array AnydataTuple4[3]; + +type JsonTuple1Array JsonTuple1[]; + +type ClosedJsonTuple1Array JsonTuple1[3]; + +type JsonTuple2Array JsonTuple2[]; + +type ClosedJsonTuple2Array JsonTuple2[3]; + +type JsonTuple3Array JsonTuple3[]; + +type ClosedJsonTuple3Array JsonTuple3[3]; + +type JsonTuple4Array JsonTuple4[]; + +type ClosedJsonTuple4Array JsonTuple4[3]; + +type CustomTuple1Array CustomTuple1[]; + +type ClosedCustomTuple1Array CustomTuple1[3]; + +type CustomTuple2Array CustomTuple2[]; + +type ClosedCustomTuple2Array CustomTuple2[3]; + +type CustomTuple3Array CustomTuple3[]; + +type ClosedCustomTuple3Array CustomTuple3[3]; + +type CustomTuple4Array CustomTuple4[]; + +type ClosedCustomTuple4Array CustomTuple4[3]; + +type CustomTuple5Array CustomTuple5[]; + +type ClosedCustomTuple5Array CustomTuple5[3]; + +type CustomTuple6Array CustomTuple6[]; + +type CustomTuple7Array CustomTuple7[]; + +type CustomTuple8Array CustomTuple8[]; + +type ClosedCustomTuple6Array CustomTuple6[3]; + +type IntegerArray1Array IntegerArray1[]; + +type ClosedIntegerArray1Array IntegerArray1[3]; + +type IntegerArray2Array IntegerArray2[]; + +type ClosedIntegerArray2Array IntegerArray2[3]; + +type IntegerArray3Array IntegerArray3[]; + +type ClosedIntegerArray3Array IntegerArray3[3]; + +type IntegerArray4Array IntegerArray4[]; + +type ClosedIntegerArray4Array IntegerArray4[3]; + +type IntegerArray5Array IntegerArray5[]; + +type ClosedIntegerArray5Array IntegerArray5[3]; + +type IntegerArray6Array IntegerArray5[]; + +type ClosedIntegerArray6Array IntegerArray5[3]; + +type StringArray1Array StringArray1[]; + +type StringArrayArray StringArray[]; + +type NillableStringArrayArray NillableStringArray[]; + +type NillableIntOrUnionStringArrayArray NillableIntOrUnionStringArray[]; + +type ClosedStringArray1Array StringArray1[3]; + +type StringArray2Array StringArray2[]; + +type ClosedStringArray2Array StringArray2[3]; + +type StringArray3Array StringArray3[]; + +type ClosedStringArray3Array StringArray3[3]; + +type StringArray4Array StringArray4[]; + +type ClosedStringArray4Array StringArray4[3]; + +type StringArray5Array StringArray5[]; + +type ClosedStringArray5Array StringArray5[3]; + +type StringArray6Array StringArray5[]; + +type ClosedStringArray6Array StringArray5[3]; + +type FloatArray1Array FloatArray1[]; + +type ClosedFloatArray1Array FloatArray1[3]; + +type FloatArray2Array FloatArray2[]; + +type ClosedFloatArray2Array FloatArray2[3]; + +type FloatArray3Array FloatArray3[]; + +type ClosedFloatArray3Array FloatArray3[3]; + +type FloatArray4Array FloatArray4[]; + +type ClosedFloatArray4Array FloatArray4[3]; + +type FloatArray5Array FloatArray5[]; + +type ClosedFloatArray5Array FloatArray5[3]; + +type FloatArray6Array FloatArray5[]; + +type ClosedFloatArray6Array FloatArray5[3]; + +type DecimalArray1Array DecimalArray1[]; + +type ClosedDecimalArray1Array DecimalArray1[3]; + +type DecimalArray2Array DecimalArray2[]; + +type ClosedDecimalArray2Array DecimalArray2[3]; + +type DecimalArray3Array DecimalArray3[]; + +type ClosedDecimalArray3Array DecimalArray3[3]; + +type DecimalArray4Array DecimalArray4[]; + +type ClosedDecimalArray4Array DecimalArray4[3]; + +type DecimalArray5Array DecimalArray5[]; + +type ClosedDecimalArray5Array DecimalArray5[3]; + +type DecimalArray6Array DecimalArray5[]; + +type ClosedDecimalArray6Array DecimalArray5[3]; + +type BooleanArrayArray BooleanArray[]; + +type ClosedBooleanArrayArray BooleanArray[3]; + +type NillableBooleanArrayArray NillableBooleanArray[]; + +type NillableIntOrUnionBooleanArrayArray NillableIntOrUnionBooleanArray[]; + +type BooleanArray2Array BooleanArray2[]; + +type ClosedBooleanArray2Array BooleanArray2[3]; + +type BooleanArray3Array BooleanArray3[]; + +type ClosedBooleanArray3Array BooleanArray3[3]; + +type BooleanArray4Array BooleanArray4[]; + +type ClosedBooleanArray4Array BooleanArray4[3]; + +type BooleanArray5Array BooleanArray5[]; + +type ClosedBooleanArray5Array BooleanArray5[3]; + +type BooleanArray6Array BooleanArray5[]; + +type ClosedBooleanArray6Array BooleanArray5[3]; + +type NilArray1Array NilArray1[]; + +type ClosedNilArray1Array NilArray1[3]; + +type NilArray2Array NilArray2[]; + +type ClosedNilArray2Array NilArray2[3]; + +type NilArray3Array NilArray3[]; + +type ClosedNilArray3Array NilArray3[3]; + +type NilArray4Array NilArray4[]; + +type ClosedNilArray4Array NilArray4[3]; + +type NilArray5Array NilArray5[]; + +type ClosedNilArray5Array NilArray5[3]; + +type NilArray6Array NilArray5[]; + +type ClosedNilArray6Array NilArray5[3]; + +type JsonArray1Array JsonArray1[]; + +type ClosedJsonArray1Array JsonArray1[3]; + +type JsonArray2Array JsonArray2[]; + +type ClosedJsonArray2Array JsonArray2[3]; + +type JsonArray3Array JsonArray3[]; + +type ClosedJsonArray3Array JsonArray3[3]; + +type JsonArray4Array JsonArray4[]; + +type ClosedJsonArray4Array JsonArray4[3]; + +type JsonArray5Array JsonArray5[]; + +type ClosedJsonArray5Array JsonArray5[3]; + +type JsonArray6Array JsonArray5[]; + +type ClosedJsonArray6Array JsonArray5[3]; + +type AnydataArray1Array AnydataArray1[]; + +type ClosedAnydataArray1Array AnydataArray1[3]; + +type AnydataArray2Array AnydataArray2[]; + +type ClosedAnydataArray2Array AnydataArray2[3]; + +type AnydataArray3Array AnydataArray3[]; + +type ClosedAnydataArray3Array AnydataArray3[3]; + +type AnydataArray4Array AnydataArray4[]; + +type ClosedAnydataArray4Array AnydataArray4[3]; + +type AnydataArray5Array AnydataArray5[]; + +type ClosedAnydataArray5Array AnydataArray5[3]; + +type AnydataArray6Array AnydataArray5[]; + +type ClosedAnydataArray6Array AnydataArray5[3]; + +type CustomArray1Array CustomArray1[]; + +type ClosedCustomArray1Array CustomArray1[3]; + +type CustomArray2Array CustomArray2[]; + +type ClosedCustomArray2Array CustomArray2[3]; + +type CustomArray3Array CustomArray3[]; + +type ClosedCustomArray3Array CustomArray3[3]; + +type CustomArray4Array CustomArray4[]; + +type ClosedCustomArray4Array CustomArray4[3]; + +type CustomArray5Array CustomArray5[]; + +type ClosedCustomArray5Array CustomArray5[3]; + +type CustomArray6Array CustomArray5[]; + +type ClosedCustomArray6Array CustomArray5[3]; + +type IntegerMapArray IntegerMap[]; + +type ClosedIntegerMapArray IntegerMap[3]; + +type StringMapArray StringMap[]; + +type NillableIntUnionStringMapArray NillableIntUnionStringMap[]; + +type IntUnionStringMapArray IntUnionStringMap[]; + +type ClosedStringMapArray StringMap[3]; + +type DecimalMapArray DecimalMap[]; + +type ClosedDecimalMapArray DecimalMap[3]; + +type FloatMapArray FloatMap[]; + +type ClosedFloatMapArray FloatMap[3]; + +type BooleanMapArray BooleanMap[]; + +type NillableBooleanMapArray NillableBooleanMap[]; + +type NillableIntUnionBooleanMapArray NillableIntUnionBooleanMap[]; + +type IntUnionBooleanMapArray IntUnionBooleanMap[]; + +type ClosedBooleanMapArray BooleanMap[3]; + +type NilMapArray NilMap[]; + +type ClosedNilMapArray NilMap[3]; + +type JsonMapArray JsonMap[]; + +type ClosedJsonMapArray JsonMap[3]; + +type AnydataMapArray AnydataMap[]; + +type ClosedAnydataMapArray AnydataMap[3]; + +type CustomMapArray CustomMap[]; + +type ClosedCustomMapArray CustomMap[3]; diff --git a/ballerina-tests/unicode-tests/.gitignore b/ballerina-tests/unicode-tests/.gitignore new file mode 100644 index 0000000..d5fc29a --- /dev/null +++ b/ballerina-tests/unicode-tests/.gitignore @@ -0,0 +1,11 @@ +# Ballerina generates this directory during the compilation of a package. +# It contains compiler-generated artifacts and the final executable if this is an application package. +target/ + +# Ballerina maintains the compiler-generated source code here. +# Remove this if you want to commit generated sources. +generated/ + +# Contains configuration values used during development time. +# See https://ballerina.io/learn/provide-values-to-configurable-variables/ for more details. +Config.toml diff --git a/ballerina-tests/unicode-tests/Ballerina.toml b/ballerina-tests/unicode-tests/Ballerina.toml new file mode 100644 index 0000000..b2ec347 --- /dev/null +++ b/ballerina-tests/unicode-tests/Ballerina.toml @@ -0,0 +1,13 @@ +[package] +org = "ballerina" +name = "unicode_tests" +version = "0.1.0" + +[[dependency]] +org = "ballerina" +name = "csv_commons" +repository = "local" +version = "0.1.0" + +[platform.java17] +graalvmCompatible = true diff --git a/ballerina-tests/unicode-tests/tests/escape_character_test.bal b/ballerina-tests/unicode-tests/tests/escape_character_test.bal new file mode 100644 index 0000000..cee018f --- /dev/null +++ b/ballerina-tests/unicode-tests/tests/escape_character_test.bal @@ -0,0 +1,55 @@ +import ballerina/data.csv as csv; +import ballerina/test; + +@test:Config +function testEscapedCharactres() returns error? { + string csvString = string `a, b + quote\"\"quoted\"quote, 1 + backslash\\backslash, 2 + newline\nnewline, 3 + tab\ttab, 5 + unicode\u0061unicode, 6 + slash\/slash, 9 + quoted string \\'abc\\', 10`; + + record{string a; int b;}[]|csv:Error rec = csv:parseStringToRecord(csvString); + test:assertEquals(rec, [ + {a: string `quote""quoted"quote`, b: 1}, + {a: string `backslash${"\\"}backslash`, b: 2}, + {a: string `newline${"\n"}newline`, b: 3}, + {a: string `tab${"\t"}tab`, b: 5}, + {a: string `unicodeaunicode`, b: 6}, + {a: string `slash/slash`, b: 9}, + {a: string `quoted string \'abc\'`, b: 10} + ]); +} + +@test:Config +function testEscapedCharactres2() returns error? { + string csvString = string `a, b + backspace\bbackspace, 7`; + + record{string a; int b;}[]|csv:Error rec = csv:parseStringToRecord(csvString); + test:assertTrue(rec is record{string a; int b;}[]); +} + +@test:Config +function testEscapedCharactres3() returns error? { + string csvString = string ` a c, b + carriage return\r carriage return, 4`; + + record{}[]|csv:Error rec = csv:parseStringToRecord(csvString); + test:assertEquals(rec, [ + {"a c": string `carriage return${"\r"} carriage return`, b: 4} + ]); +} + +@test:Config +function testEscapedCharactres4() returns error? { + string csvString = string `a, b + form feed\f form feed, 8`; + + record{string a; int b;}[]|csv:Error rec = csv:parseStringToRecord(csvString); + test:assertTrue(rec is record {string a; int b;}[]); + // TODO: Add tests after supports \f by Ballerina +} diff --git a/ballerina-tests/union-type-tests/.gitignore b/ballerina-tests/union-type-tests/.gitignore new file mode 100644 index 0000000..d5fc29a --- /dev/null +++ b/ballerina-tests/union-type-tests/.gitignore @@ -0,0 +1,11 @@ +# Ballerina generates this directory during the compilation of a package. +# It contains compiler-generated artifacts and the final executable if this is an application package. +target/ + +# Ballerina maintains the compiler-generated source code here. +# Remove this if you want to commit generated sources. +generated/ + +# Contains configuration values used during development time. +# See https://ballerina.io/learn/provide-values-to-configurable-variables/ for more details. +Config.toml diff --git a/ballerina-tests/union-type-tests/Ballerina.toml b/ballerina-tests/union-type-tests/Ballerina.toml new file mode 100644 index 0000000..5d819d3 --- /dev/null +++ b/ballerina-tests/union-type-tests/Ballerina.toml @@ -0,0 +1,13 @@ +[package] +org = "ballerina" +name = "union_type_tests" +version = "0.1.0" + +[[dependency]] +org = "ballerina" +name = "csv_commons" +repository = "local" +version = "0.1.0" + +[platform.java17] +graalvmCompatible = true diff --git a/ballerina-tests/union-type-tests/Dependencies.toml b/ballerina-tests/union-type-tests/Dependencies.toml new file mode 100644 index 0000000..3eb4395 --- /dev/null +++ b/ballerina-tests/union-type-tests/Dependencies.toml @@ -0,0 +1,98 @@ +# AUTO-GENERATED FILE. DO NOT MODIFY. + +# This file is auto-generated by Ballerina for managing dependency versions. +# It should not be modified by hand. + +[ballerina] +dependencies-toml-version = "2" +distribution-version = "2201.9.0" + +[[package]] +org = "ballerina" +name = "csv_commons" +version = "0.1.0" +scope = "testOnly" +modules = [ + {org = "ballerina", packageName = "csv_commons", moduleName = "csv_commons"} +] + +[[package]] +org = "ballerina" +name = "data.csv" +version = "0.1.0" +scope = "testOnly" +dependencies = [ + {org = "ballerina", name = "jballerina.java"} +] +modules = [ + {org = "ballerina", packageName = "data.csv", moduleName = "data.csv"} +] + +[[package]] +org = "ballerina" +name = "jballerina.java" +version = "0.0.0" +scope = "testOnly" + +[[package]] +org = "ballerina" +name = "lang.__internal" +version = "0.0.0" +scope = "testOnly" +dependencies = [ + {org = "ballerina", name = "jballerina.java"}, + {org = "ballerina", name = "lang.object"} +] + +[[package]] +org = "ballerina" +name = "lang.array" +version = "0.0.0" +scope = "testOnly" +dependencies = [ + {org = "ballerina", name = "jballerina.java"}, + {org = "ballerina", name = "lang.__internal"} +] + +[[package]] +org = "ballerina" +name = "lang.error" +version = "0.0.0" +scope = "testOnly" +dependencies = [ + {org = "ballerina", name = "jballerina.java"} +] + +[[package]] +org = "ballerina" +name = "lang.object" +version = "0.0.0" +scope = "testOnly" + +[[package]] +org = "ballerina" +name = "test" +version = "0.0.0" +scope = "testOnly" +dependencies = [ + {org = "ballerina", name = "jballerina.java"}, + {org = "ballerina", name = "lang.array"}, + {org = "ballerina", name = "lang.error"} +] +modules = [ + {org = "ballerina", packageName = "test", moduleName = "test"} +] + +[[package]] +org = "ballerina" +name = "union_type_tests" +version = "0.1.0" +dependencies = [ + {org = "ballerina", name = "csv_commons"}, + {org = "ballerina", name = "data.csv"}, + {org = "ballerina", name = "test"} +] +modules = [ + {org = "ballerina", packageName = "union_type_tests", moduleName = "union_type_tests"} +] + diff --git a/ballerina-tests/union-type-tests/tests/test_data_values.bal b/ballerina-tests/union-type-tests/tests/test_data_values.bal new file mode 100644 index 0000000..360a493 --- /dev/null +++ b/ballerina-tests/union-type-tests/tests/test_data_values.bal @@ -0,0 +1,256 @@ +boolean b1 = true; +false b2 = false; +boolean? b3 = (); +boolean|int b4 = false; + +() n1 = (); +int? n2 = (); +() n3 = null; + +int i1 = 1; +int i2 = -2; +int i3 = int:MAX_VALUE; +int i4 = int:MIN_VALUE; +int i5 = 0; +2 i6 = 2; +int? i7 = (); +int|string i8 = 100; + +float f1 = 2.234; +float f2 = -3.21f; +float f3 = 0; +float f4 = float:Infinity; +float f5 = -float:Infinity; +float f6 = float:NaN; +2.3f f7 = 2.3; +float? f8 = (); +float|decimal f9 = 1.21; + +decimal d1 = 2.234; +decimal d2 = -3.21d; +decimal d3 = 0; +2.3d d4 = 2.3; +decimal? d5 = (); +decimal|int d6 = 1.21; + +string s1 = "string"; +string s2 = ""; +string:Char s3 = "a"; + +map bm1 = {b1, b2}; +map bm2 = {b1, b2, b3, n1, n3}; +map bm3 = {b1, b2, b3, b4, i1}; +map<()> bm4 = {n1, n3}; +map bm5 = {b1, b2, b3, b4:true}; + +map m5 = {i1, i2, i3, i4, i5, i6}; +map m6 = {f1, f2, f3, f4, f5, f6, f7}; +map m7 = {d1, d2, d3, d4}; +map m8 = {d1, f1, f9, f10: 1.23}; +map m9 = {s1, s2, s3}; +map m10 = {b1, b2, b3, b4, n1, n2, n3, i1, i2, i3, i4, i5, i6, i7, i8, f1, f2, f3, f4, f5, f6, f7, f8}; +map m11 = {b1, b2, b3, b4, n1, n2, n3, i1, i2, i3, i4, i5, i6, i7, i8, f1, f2, f3, f4, f5, f6, f7, f8}; + +boolean[] arr1 = [b1, b2]; +boolean?[] arr2 = [b1, b2, b3, n1, n3]; +(boolean|int?)[] arr3 = [b1, b2, b3, b4, i1]; +()[] arr4 = [n1, n3]; +int[] arr5 = [i1, i2, i3, i4, i5, i6]; +float[] arr6 = [f1, f2, f3, f4, f5, f6, f7]; +decimal[] arr7 = [d1, d2, d3, d4]; +(decimal|float)[] arr8 = [d1, f1, f9, 1.23]; +string[] arr9 = [s1, s2, s3]; +anydata[] arr10 = [b1, b2, b3, b4, n1, n2, n3, i1, i2, i3, i4, i5, i6, i7, i8, f1, f2, f3, f4, f5, f6, f7, f8]; +json[] arr11 = [b1, b2, b3, b4, n1, n2, n3, i1, i2, i3, i4, i5, i6, i7, i8, f1, f2, f3, f4, f5, f6, f7, f8]; + +[boolean, boolean] bt1 = [b1, b2]; +[boolean, boolean, boolean, boolean] bt2 = [b1, b2, b1, b2]; +[boolean?, boolean?, boolean?, boolean?, boolean?] bt3 = [b1, b2, b3, n1, n3]; +[boolean|int?, boolean|int?, boolean|int?, boolean|int?, boolean|int?] bt4 = [b1, b2, b3, b4, i1]; +[boolean...] bt5 = [b1, b2]; + +[string, string] st1 = [s1, s2]; +[string, string, string, string] st2 = [s1, s2, s3, s2]; +[string...] st3 = [s1, s2]; +[string, string, string...] st4 = [s1, s2, s3, s2]; + +[string?, string?, string?, string?, string?] st5 = [s1, s2, s3, n1, n3]; +[string|int?, string|int?, string|int?, string|int?, string|int?] st6 = [s1, s2, s3, n1, i1]; +[string?...] st7 = [s1, s2]; +[string...] st8 = []; +[string, string, string] st9 = [s1, s2, s3]; + +[(), ()] tup4 = [n1, n3]; +[int, int, int, int, int, int] tup5 = [i1, i2, i3, i4, i5, i6]; +[float, float, float, float, float, float, float] tup6 = [f1, f2, f3, f4, f5, f6, f7]; +[decimal, decimal, decimal, decimal] tup7 = [d1, d2, d3, d4]; +[decimal|float, decimal|float, decimal|float, decimal|float] tup8 = [d1, f1, f9, 1.23]; +[string, string, string] tup9 = [s1, s2, s3]; +[anydata, anydata, anydata, anydata, anydata, anydata, anydata, anydata, + anydata, anydata, anydata, anydata, anydata, anydata, anydata, anydata, + anydata, anydata, anydata, anydata, anydata, anydata, anydata] tup10 = [b1, b2, b3, b4, + n1, n2, n3, i1, i2, i3, i4, i5, i6, i7, i8, f1, f2, f3, f4, f5, f6, f7, f8]; +[json, json, json, json, json, json, json, json, json, json, json, json, + json, json, json, json, json, json, json, json, json, json, json] tup11 = + [b1, b2, b3, b4, n1, n2, n3, i1, i2, i3, i4, i5, i6, i7, i8, f1, + f2, f3, f4, f5, f6, f7, f8]; +[string, string, int, int, boolean, boolean, (), (), decimal, decimal, float, float] tup12 = [ + s1, s2, i1, i2, b1, b2, n1, n3, d1, d2, f1, f2 +]; + +[boolean, boolean...] restTup1 = [b1, b2]; +[boolean?, boolean?, boolean?...] restTup2 = [b1, b2, b3, n1, n3]; +[boolean|int?...] restTup3 = [b1, b2, b3, b4, i1]; +[(), ()...] restTup4 = [n1, n3]; +[int...] restTup5 = [i1, i2, i3, i4, i5, i6]; +[float...] restTup6 = [f1, f2, f3, f4, f5, f6, f7]; +[decimal...] restTup7 = [d1, d2, d3, d4]; +[decimal|float, decimal|float...] restTup8 = [d1, f1, f9, 1.23]; +[string...] restTup9 = [s1, s2, s3]; +[anydata...] restTup10 = [b1, b2, b3, b4, n1, n2, n3, i1, i2, i3, i4, i5, i6, i7, i8, f1, f2, f3, f4, f5, f6, f7, f8]; +[json, json, json...] restTup11 = [b1, b2, b3, b4, n1, n2, n3, i1, i2, i3, i4, i5, i6, i7, i8, f1, f2, f3, f4, f5, f6, f7, f8]; +[string, string, int, int, boolean, boolean, (), (), decimal, decimal, float, float...] restTup12 = [ + s1, s2, i1, i2, b1, b2, n1, n3, d1, d2, f1, f2, f2, f2 +]; + +var booleanRecordArray = [ + {b1, b2, b3, b4}, {b1, b2, b3, b4} +]; + +var booleanRecordArray2 = [ + {},{} +]; + +string csvStringWithBooleanValues1 = string `b1,b2,b3,b4 +true,false,true,false +true,false, true,false +true,false,true,false +`; + +string csvStringWithBooleanValues2 = string `b1,b2,b3,b4,b5 +true,false, true,false,true +true,false, true,false,true`; + +string csvStringWithBooleanValues3 = string `b1,b2,b3 +${" "}${"\t"} +true, false,true +${" "} + TRUE, FALSE,() +${" "} + +true, true,FALSE + +`; + +string csvStringWithBooleanValues4 = string `b1,b2,b3,b4 + true,(), (),false + true,(), null,false + +`; + +string csvStringWithBooleanValues5 = string `b1,b2,b3,b4 + +true,false,true,2 + +true,false,true,3 +`; + +string csvStringWithBooleanValues6 = string `b2,b3 +(),() + +`; + +string csvStringWithBooleanValues7 = string `b1,b2,b3,b4 +${b1},${b2},(),${b4} +`; + +string csvStringData1 = string ` + a, b, c, d, e, f + 1, string1, true, 2.234, 2.234, () + 2, string2, false, 0, 0, null + 3, string3, false, 1.23, 1.23, () + 4, string4, true, -6.51, -6.51, () + 5, string5, true, 3, 3, ()`; + +string csvStringData2 = string ` + hello, hello, (), 12, true, 12.34 + // comment + + a, b, c, d, e, f + + + 1, string1, true, 2.234, 2.234, () + 2, string2, false, 0, 0, null + 3, string3, false, 1.23, 1.23, () + 4, string4, true, -6.51, -6.51, () + 5, string5, true, 3, 3, ()`; + +string csvStringData3 = string ` + a, b, c, d, e, f + + + + 1, string1, true, 2.234, 2.234, () + 2, string2, false, 0, 0, null + 3, string3, false, 1.23, 1.23, () + + 4, string4, true, -6.51, -6.51, () + 5, string5, true, 3, 3, ()`; + +string csvStringData4 = string ` + 1, string1, true, 2.234, 2.234, () + 2, string2, false, 0, 0, null + 3, string3, false, 1.23, 1.23, () + 4, string4, true, -6.51, -6.51, () + 5, string5, true, 3, 3, ()`; + +string csvStringData5 = string ` + + + + 1, string1, true, 2.234, 2.234, () + 2, string2, false, 0, 0, null + + 3, string3, false, 1.23, 1.23, () + 4, string4, true, -6.51, -6.51, () + + 5, string5, true, 3, 3, ()`; + +string csvStringData6 = string ` + + 1, string1, true, 2.234, 2.234, () + 2, string2, false, 0, 0, null + + 3, string3, false, 1.23, 1.23, () + 4, string4, true, -6.51, -6.51, () + + 5, string5, true, 3, 3, ()`; + +string csvStringData7 = string ` + a@ b@ c@ d@ e@ f + 1@ string@ true@ 2.234@ -3.21@ () + 2@ s,tring@ true@ 2.234@ -3.21@ null + 3@ stri,ng@ true@ 2.234@ -3.21@ () + 4@ string@ true@ 2.234@ -3.21@ () + 5@ string@ true@ 2.234@ -3.21@ ()`; +string csvStringData8 = string ` + a@ b@ c@ d@ e@ f + + + + 1@ stri,ng@ true@ 2.234@ -3.21@ () + 2@ string@ true@ 2.234@ ()@-3.21 + 3@ string@ true@ 2.234@ -3.21@ null + + 4@ s,tring@ true@ 2.234@ -3.21@ () + 5@ string@ true@ 2.234@ -3.21@ ()`; + +string csvStringData9 = string ` + + 1@ string@ true@ 2.234@ -3.21@ () + 2@ string@ true@ 2.234@ -3.21@ null + + 3@ string@ true@ 2.234@ -3.21@ () + 4@ string@ true@ 2.234@ ()@-3.21 + + 5@ string@ true@ 2.234@ -3.21@ null`; diff --git a/ballerina-tests/union-type-tests/tests/test_with_intersection_types.bal b/ballerina-tests/union-type-tests/tests/test_with_intersection_types.bal new file mode 100644 index 0000000..141fce7 --- /dev/null +++ b/ballerina-tests/union-type-tests/tests/test_with_intersection_types.bal @@ -0,0 +1,159 @@ +import ballerina/data.csv as csv; +import ballerina/test; + +@test:Config +function testIntersectionExpectedTypes() returns error? { + (int[] & readonly)[]|csv:Error a = csv:parseStringToList(string `a,b + 1,2 + 4,5`); + test:assertTrue(a is (int[] & readonly)[]); + test:assertEquals(a, [[1, 2], [4, 5]]); + + ([string, string])[] & readonly|csv:Error a2 = csv:parseStringToList(string `a,b + a,a + c,c`); + test:assertTrue(a2 is [string, string][] & readonly); + test:assertEquals(a2, [["a", "a"], ["c", "c"]]); + + (record{int a; string b;} & readonly)[]|csv:Error a3 = csv:parseStringToRecord(string `a,b + 1,2 + 4,5`); + test:assertTrue(a3 is (record{int a; string b;} & readonly)[]); + test:assertEquals(a3, [{a: 1, b: "2"}, {a: 4, b: "5"}]); + + record{|string...;|}[] & readonly|csv:Error a4 = csv:parseStringToRecord(string `a,b + a,a + c,c`); + test:assertTrue(a4 is record{|string...;|}[] & readonly); + test:assertEquals(a4, [{a: "a", b: "a"}, {a: "c", b: "c"}]); + + ([int] & readonly)[]|csv:Error a5 = csv:parseStringToList(string `a,b + 1,2 + 4,5`); + test:assertTrue(a5 is ([int] & readonly)[]); + test:assertEquals(a5, [[1], [4]]); + + ([string, string])[] & readonly|csv:Error a6 = csv:parseStringToList(string `a,b + a,a + c,c`); + test:assertTrue(a6 is [string, string][] & readonly); + test:assertEquals(a6, [["a", "a"], ["c", "c"]]); + + (record{int a; string b;} & readonly)[]|csv:Error a7 = csv:parseStringToRecord(string `a,b + 1,2 + 4,5`); + test:assertTrue(a7 is record{int a; string b;}[] & readonly); + test:assertEquals(a7, [{a: 1, b: "2"}, {a: 4, b: "5"}]); + + map[] & readonly|csv:Error a8 = csv:parseStringToRecord(string `a,b + a,a + c,c`); + test:assertTrue(a8 is map[] & readonly); + test:assertEquals(a8, [{a: "a", b: "a"}, {a: "c", b: "c"}]); + + (((int[] & readonly)|([string, string] & readonly)) & readonly)[]|csv:Error a9 = csv:parseStringToList(string `a,b + 1,2 + a,a`); + test:assertTrue(a9 is (((int[] & readonly)|([string, string] & readonly)) & readonly)[]); + test:assertEquals(a9, [[1, 2], ["a", "a"]]); + + ((record {string a; string b;} & readonly)|(record {int a; int b;} & readonly))[] + & readonly|csv:Error a10 = csv:parseStringToRecord(string `a,b + a,a + 1,2`); + test:assertTrue(a10 is ((record {string a; string b;} & readonly)|(record {int a; int b;} & readonly))[] & readonly); + test:assertEquals(a10, [{a: "a", b: "a"}, {a: "1", b: "2"}]); +} + +@test:Config +function testIntersectionExpectedTypes2() returns error? { + (int[] & readonly)[]|csv:Error a = csv:parseRecordAsListType([{"a": 1, "b": 2}, {"a": 4, "b": 5}], ["a", "b"], {}); + test:assertTrue(a is (int[] & readonly)[]); + test:assertEquals(a, [[1, 2], [4, 5]]); + + ([string, string])[] & readonly|csv:Error a2 = csv:parseRecordAsListType([{"a": "a", "b": "a"}, {"a": "c", "b": "c"}], ["a", "b"], {}); + test:assertTrue(a2 is [string, string][] & readonly); + test:assertEquals(a2, [["a", "a"], ["c", "c"]]); + + (record{int a; string b;} & readonly)[]|csv:Error a3 = csv:parseRecordAsRecordType([{"a": 1, "b": "2"}, {"a": 4, "b": "5"}], {}); + test:assertTrue(a3 is (record{int a; string b;} & readonly)[]); + test:assertEquals(a3, [{a: 1, b: "2"}, {a: 4, b: "5"}]); + + record{|string...;|}[] & readonly|csv:Error a4 = csv:parseRecordAsRecordType([{"a": "a", "b": "a"}, {"a": "c", "b": "c"}], {}); + test:assertTrue(a4 is record{|string...;|}[] & readonly); + test:assertEquals(a4, [{a: "a", b: "a"}, {a: "c", b: "c"}]); + + ([int] & readonly)[]|csv:Error a5 = csv:parseRecordAsListType([{"a": 1, "b": 2}, {"a": 4, "b": 5}], ["a", "b"], {}); + test:assertTrue(a5 is ([int] & readonly)[]); + test:assertEquals(a5, [[1], [4]]); + + ([string, string])[] & readonly|csv:Error a6 = csv:parseRecordAsListType([{"a": "a", "b": "a"}, {"a": "c", "b": "c"}], ["a", "b"], {}); + test:assertTrue(a6 is [string, string][] & readonly); + test:assertEquals(a6, [["a", "a"], ["c", "c"]]); + + (record{int a; string b;} & readonly)[]|csv:Error a7 = csv:parseRecordAsRecordType([{"a": 1, "b": "2"}, {"a": 4, "b": "5"}], {}); + test:assertTrue(a7 is record{int a; string b;}[] & readonly); + test:assertEquals(a7, [{a: 1, b: "2"}, {a: 4, b: "5"}]); + + map[] & readonly|csv:Error a8 = csv:parseRecordAsRecordType([{"a": "a", "b": "a"}, {"a": "c", "b": "c"}], {}); + test:assertTrue(a8 is map[] & readonly); + test:assertEquals(a8, [{a: "a", b: "a"}, {a: "c", b: "c"}]); + + (((int[] & readonly)|([string, string] & readonly)) & readonly)[]|csv:Error a9 = csv:parseRecordAsListType([{"a": 1, "b": 2}, {"a": "a", "b": "b"}], ["a", "b"], {}); + test:assertTrue(a9 is (((int[] & readonly)|([string, string] & readonly)) & readonly)[]); + test:assertEquals(a9, [[1, 2], ["a", "b"]]); + + ((record {string a; string b;} & readonly)|(record {int a; int b;} & readonly))[] + & readonly|csv:Error a10 = csv:parseRecordAsRecordType([{"a": "a", "b": "a"}, {"a": 1, "b": 2}], {}); + test:assertTrue(a10 is ((record {string a; string b;} & readonly)|(record {int a; int b;} & readonly))[] & readonly); + test:assertEquals(a10, [{a: "a", b: "a"}, {a: 1, b: 2}]); +} + +@test:Config +function testIntersectionExpectedTypes3() returns error? { + (int[] & readonly)[]|csv:Error a = csv:parseListAsListType([["1", "2"], ["4", "5"]], {}); + test:assertTrue(a is (int[] & readonly)[]); + test:assertEquals(a, [[1, 2], [4, 5]]); + + ([string, string])[] & readonly|csv:Error a2 = csv:parseListAsListType([["a", "a"], ["c", "c"]], {}); + test:assertTrue(a2 is [string, string][] & readonly); + test:assertEquals(a2, [["a", "a"], ["c", "c"]]); + + (record{int a; string b;} & readonly)[]|csv:Error a3 = csv:parseListAsRecordType([["1", "2"], ["4", "5"]], ["a", "b"], {}); + test:assertTrue(a3 is (record{int a; string b;} & readonly)[]); + test:assertEquals(a3, [{a: 1, b: "2"}, {a: 4, b: "5"}]); + + record{|string...;|}[] & readonly|csv:Error a4 = csv:parseListAsRecordType([["a", "a"], ["c", "c"]], ["a", "b"], {}); + test:assertTrue(a4 is record{|string...;|}[] & readonly); + test:assertEquals(a4, [{a: "a", b: "a"}, {a: "c", b: "c"}]); + + ([int] & readonly)[]|csv:Error a5 = csv:parseListAsListType([["1", "2"], ["4", "5"]], {}); + test:assertTrue(a5 is ([int] & readonly)[]); + test:assertEquals(a5, [[1], [4]]); + + ([string, string])[] & readonly|csv:Error a6 = csv:parseListAsListType([["a", "a"], ["c", "c"]], {}); + test:assertTrue(a6 is [string, string][] & readonly); + test:assertEquals(a6, [["a", "a"], ["c", "c"]]); + + (record{int a; string b;} & readonly)[]|csv:Error a7 = csv:parseListAsRecordType([["1", "2"], ["4", "5"]], ["a", "b"], {}); + test:assertTrue(a7 is record{int a; string b;}[] & readonly); + test:assertEquals(a7, [{a: 1, b: "2"}, {a: 4, b: "5"}]); + + map[] & readonly|csv:Error a8 = csv:parseListAsRecordType([["a", "a"], ["c", "c"]], ["a", "b"], {}); + test:assertTrue(a8 is map[] & readonly); + test:assertEquals(a8, [{a: "a", b: "a"}, {a: "c", b: "c"}]); + + (((int[] & readonly)|([string, string] & readonly)) & readonly)[]|csv:Error a9 = csv:parseListAsListType([["1", "2"], ["a", "b"]], {}); + test:assertTrue(a9 is (((int[] & readonly)|([string, string] & readonly)) & readonly)[]); + test:assertEquals(a9, [[1, 2], ["a", "b"]]); + + ((record {string a; string b;} & readonly)|(record {int a; int b;} & readonly))[] + & readonly|csv:Error a10 = csv:parseListAsRecordType([["a", "a"], ["1", "2"]], ["a", "b"], {}); + test:assertTrue(a10 is ((record {string a; string b;} & readonly)|(record {int a; int b;} & readonly))[] & readonly); + test:assertEquals(a10, [{a: "a", b: "a"}, {a: "1", b: "2"}]); + + ((record {int a; int b;} & readonly)|(record {string a; string b;} & readonly))[] + & readonly|csv:Error a11 = csv:parseListAsRecordType([["a", "a"], ["1", "2"]], ["a", "b"], {}); + test:assertTrue(a11 is ((record {string a; string b;} & readonly)|(record {int a; int b;} & readonly))[] & readonly); + test:assertEquals(a11, [{a: "a", b: "a"}, {a: 1, b: 2}]); +} diff --git a/ballerina-tests/union-type-tests/tests/test_with_singleton_test.bal b/ballerina-tests/union-type-tests/tests/test_with_singleton_test.bal new file mode 100644 index 0000000..495180a --- /dev/null +++ b/ballerina-tests/union-type-tests/tests/test_with_singleton_test.bal @@ -0,0 +1,203 @@ +import ballerina/data.csv as csv; +import ballerina/test; +import ballerina/csv_commons as common; + +type Singleton 1; + +@test:Config +function testSingletonExpectedTypes() returns error? { + 1[][]|csv:Error a = csv:parseStringToList(string `a, b, c + 1, 1, 1 + 1, 1,1 `); + test:assertEquals(a, [[1, 1, 1], [1, 1, 1]]); + + record {1|2 a; 1 b;}[]|csv:Error a2 = csv:parseStringToRecord(string `a, b, c + 1, 1, 1 + 1, 1,1 `); + test:assertEquals(a2, [{a: 1, b: 1, c: 1}, {a: 1, b: 1, c: 1}]); + + record {|1 a; 1|2...;|}[]|csv:Error a3 = csv:parseStringToRecord(string `a, b, c + 1, 1, 1 + 1, 1,1 `); + test:assertEquals(a3, [{a: 1, b: 1, c: 1}, {a: 1, b: 1, c: 1}]); + + [Singleton, Singleton...][]|csv:Error a4 = csv:parseStringToList(string `a, b, c + 1, 1, 1 + 1, 1,1 `); + test:assertEquals(a4, [[1, 1, 1], [1, 1, 1]]); + + record {|1|"a" a; 1 b;|}[]|csv:Error a5 = csv:parseStringToRecord(string `a, b, c + 1, 1, 1 + 1, 1,1 `); + test:assertEquals(a5, [{a: 1, b: 1}, {a: 1, b: 1}]); + + [Singleton, Singleton][]|csv:Error a6 = csv:parseStringToList(string `a, b, c + 1, 1, 1 + 1, 1,1 `); + test:assertEquals(a6, [[1, 1], [1, 1]]); + + record {|"a"|"c" a; "b" b;|}[]|csv:Error a7 = csv:parseStringToRecord(string `a, b, c + a, c, 1 + 1, 1,1 `); + test:assertTrue(a7 is csv:Error); + test:assertEquals((a7).message(), common:generateErrorMessageForInvalidCast("c", "\"b\"")); + + ["a"|"d", "b"][]|csv:Error a8 = csv:parseStringToList(string `a, b, c + a, b, 1 + c, b,1 `); + test:assertTrue(a8 is csv:Error); + test:assertEquals((a8).message(), common:generateErrorMessageForInvalidCast("c", "(\"a\"|\"d\")")); +} + +@test:Config +function testSingletonExpectedTypes2() returns error? { + 1[][]|csv:Error a = csv:parseStringToList(string `a, b, c + 1, 1, 1 + 1, 1,1 `); + test:assertEquals(a, [[1, 1, 1], [1, 1, 1]]); + + record {1|2 a; 1 b;}[]|csv:Error a2 = csv:parseStringToRecord(string `a, b, c + 1, 1, 1 + 1, 1,1 `); + test:assertEquals(a2, [{a: 1, b: 1, c: 1}, {a: 1, b: 1, c: 1}]); + + record {|1 a; 1|2...;|}[]|csv:Error a3 = csv:parseStringToRecord(string `a, b, c + 1, 1, 1 + 1, 1,1 `); + test:assertEquals(a3, [{a: 1, b: 1, c: 1}, {a: 1, b: 1, c: 1}]); + + [Singleton, Singleton...][]|csv:Error a4 = csv:parseStringToList(string `a, b, c + 1, 1, 1 + 1, 1,1 `); + test:assertEquals(a4, [[1, 1, 1], [1, 1, 1]]); + + record {|1|"a" a; 1 b;|}[]|csv:Error a5 = csv:parseStringToRecord(string `a, b, c + 1, 1, 1 + 1, 1,1 `); + test:assertEquals(a5, [{a: 1, b: 1}, {a: 1, b: 1}]); + + [Singleton, Singleton][]|csv:Error a6 = csv:parseStringToList(string `a, b, c + 1, 1, 1 + 1, 1,1 `); + test:assertEquals(a6, [[1, 1], [1, 1]]); + + record {|"a"|"c" a; "b" b;|}[]|csv:Error a7 = csv:parseStringToRecord(string `a, b, c + a, c, 1 + 1, 1,1 `); + test:assertTrue(a7 is csv:Error); + test:assertEquals((a7).message(), common:generateErrorMessageForInvalidCast("c", "\"b\"")); + + ["a"|"d", "b"][]|csv:Error a8 = csv:parseStringToList(string `a, b, c + a, b, 1 + c, b,1 `); + test:assertTrue(a8 is csv:Error); + test:assertEquals((a8).message(), common:generateErrorMessageForInvalidCast("c", "(\"a\"|\"d\")")); +} + +type SubType byte|int:Signed8|int:Signed16|int:Signed32|string:Char|int:Unsigned8|int:Unsigned16|int:Unsigned32; + +type SubtypeRecord record { + byte a; int:Signed8 c; int:Signed16 d; int:Signed32 e; + string:Char f; int:Unsigned8 g; int:Unsigned16 h; int:Unsigned32 i; +}; + +type SubtypeRecord2 record {| + byte a; int:Signed8 c; +|}; + +type SubtypeRecord3 record {| + SubType...; +|}; + +type SubtypeTuple [ + byte, int:Signed8, int:Signed16, int:Signed32, + string:Char, int:Unsigned8, int:Unsigned16, int:Unsigned32 +]; + +type SubtypeTuple2 [SubType, SubType]; + +type SubtypeTuple3 [SubType...]; + +@test:Config +function testSubtypeExpectedTypes() returns error? { + var value1 = [{a: 1, c: 1, d: 1, e: 1, f: "a", g: 1, h: 1, i: 1}, + {a: 1, c: 1, d: 1, e: 1, f: "a", g: 1, h: 1, i: 1}]; + var value2 = [["1", "1", "1", "1", "a", "1", "1", "1"], + ["1", "1", "1", "1", "a", "1", "1", "1"]]; + var value3 = [[1, 1, 1, 1, "a", 1, 1, 1], + [1, 1, 1, 1, "a", 1, 1, 1]]; + + SubtypeRecord[]|csv:Error a = csv:parseStringToRecord(string `a, c, d, e, f, g, h, i + 1, 1, 1, 1, a, 1, 1, 1 + 1, 1, 1, 1, a, 1, 1, 1 `); + test:assertEquals(a, value1); + + SubtypeRecord2[]|csv:Error a2 = csv:parseStringToRecord(string `a, c, d, e, f, g, h, i + 1, 1, 1, 1, a, 1, 1, 1 + 1, 1, 1, 1, a, 1, 1, 1 `); + + test:assertEquals(a2, [{a: 1, c: 1}, {a: 1, c: 1}]); + + SubtypeRecord3[]|csv:Error a3 = csv:parseStringToRecord(string `a, c, d, e, f, g, h, i + 1, 1, 1, 1, a, 1, 1, 1 + 1, 1, 1, 1, a, 1, 1, 1 `); + test:assertEquals(a3, value1); + + SubtypeTuple[]|csv:Error a4 = csv:parseStringToList(string `a, c, d, e, f, g, h, i + 1, 1, 1, 1, a, 1, 1, 1 + 1, 1, 1, 1, a, 1, 1, 1 `); + test:assertEquals(a4, value3); + + SubtypeTuple2[]|csv:Error a5 = csv:parseStringToList(string `a, c, d, e, f, g, h, i + 1, 1, 1, 1, a, 1, 1, 1 + 1, 1, 1, 1, a, 1, 1, 1 `); + test:assertEquals(a5, [[1, 1], [1, 1]]); + + SubtypeTuple3[]|csv:Error a6 = csv:parseStringToList(string `a, c, d, e, f, g, h, i + 1, 1, 1, 1, a, 1, 1, 1 + 1, 1, 1, 1, a, 1, 1, 1 `); + test:assertEquals(a6, value3); + + SubtypeRecord[]|csv:Error a7 = csv:parseRecordAsRecordType(value1, {}); + test:assertEquals(a7, value1); + + SubtypeRecord2[]|csv:Error a8 = csv:parseRecordAsRecordType(value1, {}); + + test:assertEquals(a8, [{a: 1, c: 1}, {a: 1, c: 1}]); + + SubtypeRecord3[]|csv:Error a9 = csv:parseRecordAsRecordType(value1, {}); + test:assertEquals(a9, value1); + + SubtypeTuple[]|csv:Error a10 = csv:parseRecordAsListType(value1, + ["a", "c", "d", "e", "f", "g", "h", "i"], {}); + test:assertEquals(a10, value3); + + SubtypeTuple2[]|csv:Error a11 = csv:parseRecordAsListType(value1, + ["a", "c", "d", "e", "f", "g", "h", "i"], {}); + test:assertEquals(a11, [[1, 1], [1, 1]]); + + SubtypeTuple3[]|csv:Error a12 = csv:parseRecordAsListType(value1, + ["a", "c", "d", "e", "f", "g", "h", "i"], {}); + test:assertEquals(a12, value3); + + SubtypeRecord[]|csv:Error a13 = csv:parseListAsRecordType(value2, + ["a", "c", "d", "e", "f", "g", "h", "i"], {}); + test:assertEquals(a13, value1); + + SubtypeRecord2[]|csv:Error a14 = csv:parseListAsRecordType(value2, + ["a", "c", "d", "e", "f", "g", "h", "i"], {}); + test:assertEquals(a14, [{a: 1, c: 1}, {a: 1, c: 1}]); + + SubtypeRecord3[]|csv:Error a15 = csv:parseListAsRecordType(value2, + ["a", "c", "d", "e", "f", "g", "h", "i"], {}); + test:assertEquals(a15, value1); + + SubtypeTuple[]|csv:Error a16 = csv:parseListAsListType(value2, {}); + test:assertEquals(a16, value3); + + SubtypeTuple2[]|csv:Error a17 = csv:parseListAsListType(value2, {}); + test:assertEquals(a17, [[1, 1], [1, 1]]); + + SubtypeTuple3[]|csv:Error a18 = csv:parseListAsListType(value2, {}); + test:assertEquals(a18, value3); +} diff --git a/ballerina-tests/union-type-tests/tests/test_with_union_types.bal b/ballerina-tests/union-type-tests/tests/test_with_union_types.bal new file mode 100644 index 0000000..10fc22a --- /dev/null +++ b/ballerina-tests/union-type-tests/tests/test_with_union_types.bal @@ -0,0 +1,1042 @@ +import ballerina/data.csv as csv; +import ballerina/test; + +type RecA record {int a; string b; boolean c; decimal d; float e; () f;}; +type RecB record {|string...;|}; +type RecC record {int a; int b; int c;}; +type TupA [int, string, boolean, decimal, float, ()]; +type TupB [int...]; +type TupC [int, int, int]; + +@test:Config +function testParseToStringWithUnionExpectedTypes() returns error? { + (RecA|RecC)[]|csv:Error csv1op1 = csv:parseStringToRecord(csvStringData1, {header: 1}); + test:assertEquals(csv1op1, [ + {a: 1, b: "string1", c: true, d: 2.234, e: 2.234, f: ()}, + {a: 2, b: "string2", c: false, d: 0, e: 0, f: ()}, + {a: 3, b: "string3", c: false, d: 1.23, e: 1.23, f: ()}, + {a: 4, b: "string4", c: true, d: -6.51, e: -6.51, f: ()}, + {a: 5, b: "string5", c: true, d: 3, e: 3.0, f: ()} + ]); + + (RecA|RecC)[]|csv:Error csv1op2 = csv:parseStringToRecord(csvStringData1, {header: 1, skipLines: [2, 4]}); + test:assertTrue(csv1op2 is (RecA|RecC)[]); + test:assertEquals(csv1op2, [ + {a: 1, b: "string1", c: true, d: 2.234, e: 2.234, f: ()}, + {a: 3, b: "string3", c: false, d: 1.23, e: 1.23, f: ()}, + {a: 5, b: "string5", c: true, d: 3, e: 3.0, f: ()} + ]); + + (RecC|RecA)[]|csv:Error csv1op3 = csv:parseStringToRecord(csvStringData1, {header: 1, skipLines: [2, 4]}); + test:assertEquals(csv1op3, [ + {a: 1, b: "string1", c: true, d: 2.234, e: 2.234, f: ()}, + {a: 3, b: "string3", c: false, d: 1.23, e: 1.23, f: ()}, + {a: 5, b: "string5", c: true, d: 3, e: 3.0, f: ()} + ]); + + (RecB|RecA)[]|csv:Error csv1op4 = csv:parseStringToRecord(csvStringData1, {header: 1, skipLines: [2, 4]}); + test:assertEquals(csv1op4, [ + {a: "1", b: "string1", c: "true", d: "2.234", e: "2.234", f: "()"}, + {a: "3", b: "string3", c: "false", d: "1.23", e: "1.23", f: "()"}, + {a: "5", b: "string5", c: "true", d: "3", e: "3", f: "()"} + ]); + + (RecA|RecB)[]|csv:Error csv1op5 = csv:parseStringToRecord(csvStringData1, {header: 1, skipLines: [2, 4]}); + test:assertEquals(csv1op5, [ + {a: 1, b: "string1", c: true, d: 2.234, e: 2.234, f: ()}, + {a: 3, b: "string3", c: false, d: 1.23, e: 1.23, f: ()}, + {a: 5, b: "string5", c: true, d: 3, e: 3.0, f: ()} + ]); + + (record{|int a;|}|record{|string b;|})[]|csv:Error csv1op6 = csv:parseStringToRecord(csvStringData1, {header: 1, skipLines: [2, 4]}); + test:assertEquals(csv1op6, [ + {a: 1}, + {a: 3}, + {a: 5} + ]); + + (record{|string b;|}|record{|int a;|})[]|csv:Error csv1op7 = csv:parseStringToRecord(csvStringData1, {header: 1, skipLines: [2, 4]}); + test:assertEquals(csv1op7, [ + {b: "string1"}, + {b: "string3"}, + {b: "string5"} + ]); + + (record{|string...;|}|record{|int...;|})[]|csv:Error csv1op8 = csv:parseStringToRecord(csvStringData1, {header: 1}); + test:assertEquals(csv1op8, [ + {a: "1", b: "string1", c: "true", d: "2.234", e: "2.234", f: "()"}, + {a: "2", b: "string2", c: "false", d: "0", e: "0", f: "null"}, + {a: "3", b: "string3", c: "false", d: "1.23", e: "1.23", f: "()"}, + {a: "4", b: "string4", c: "true", d: "-6.51", e: "-6.51", f: "()"}, + {a: "5", b: "string5", c: "true", d: "3", e: "3", f: "()"} + ]); + + (record{|int...;|}|record{|string...;|})[]|csv:Error csv1op9 = csv:parseStringToRecord(csvStringData1, {header: 1}); + test:assertEquals(csv1op9, [ + {a: 1}, + {a: 2, d: 0, e: 0}, + {a: 3}, + {a: 4}, + {a: 5, d: 3, e: 3} + ]); + + (record{|int a; string...;|}|record{|string a; int...;|})[]|csv:Error csv1op10 = csv:parseStringToRecord(csvStringData1, {header: 1}); + test:assertEquals(csv1op10, [ + {a: 1, b: "string1", c: "true", d: "2.234", e: "2.234", f: "()"}, + {a: 2, b: "string2", c: "false", d: "0", e: "0", f: "null"}, + {a: 3, b: "string3", c: "false", d: "1.23", e: "1.23", f: "()"}, + {a: 4, b: "string4", c: "true", d: "-6.51", e: "-6.51", f: "()"}, + {a: 5, b: "string5", c: "true", d: "3", e: "3", f: "()"} + ]); + + (record{|string a; int...;|}|record{|int a; string...;|})[]|csv:Error csv1op11 = csv:parseStringToRecord(csvStringData1, {header: 1}); + test:assertEquals(csv1op11, [ + {a: "1"}, + {a: "2", d: 0, e: 0}, + {a: "3"}, + {a: "4"}, + {a: "5", d: 3, e: 3} + ]); + + (record{|int a; int b;|}|record{|string a; string...;|})[]|csv:Error csv1op12 = csv:parseStringToRecord(string ` + a,b + 1, 2 + a, b`, {header: 1}); + test:assertEquals(csv1op12, [ + {a: 1, b: 2}, + {a: "a", b: "b"} + ]); + + ([int, int]|[string, string])[]|csv:Error csv1op13 = csv:parseStringToList(string ` + a,b + 1, 2 + a, b`, {header: 1}); + test:assertEquals(csv1op13, [ + [1, 2], + ["a", "b"] + ]); +} + +@test:Config +function testParseToStringWithUnionExpectedTypes2() returns error? { + record{int a; string b; boolean c; decimal d; float e; () f;}[] value = [ + {a: 1, b: "string1", c: true, d: 2.234, e: 2.234, f: ()}, + {a: 2, b: "string2", c: false, d: 0, e: 0, f: ()}, + {a: 3, b: "string3", c: false, d: 1.23, e: 1.23, f: ()}, + {a: 4, b: "string4", c: true, d: -6.51, e: -6.51, f: ()}, + {a: 5, b: "string5", c: true, d: 3, e: 3.0, f: ()} + ]; + + (RecA|RecC)[]|csv:Error csv1op1 = csv:parseRecordAsRecordType(value, {}); + test:assertEquals(csv1op1, [ + {a: 1, b: "string1", c: true, d: 2.234, e: 2.234, f: ()}, + {a: 2, b: "string2", c: false, d: 0, e: 0, f: ()}, + {a: 3, b: "string3", c: false, d: 1.23, e: 1.23, f: ()}, + {a: 4, b: "string4", c: true, d: -6.51, e: -6.51, f: ()}, + {a: 5, b: "string5", c: true, d: 3, e: 3.0, f: ()} + ]); + + (RecA|RecC)[]|csv:Error csv1op2 = csv:parseRecordAsRecordType(value, {skipLines: [2, 4]}); + test:assertTrue(csv1op2 is (RecA|RecC)[]); + test:assertEquals(csv1op2, [ + {a: 1, b: "string1", c: true, d: 2.234, e: 2.234, f: ()}, + {a: 3, b: "string3", c: false, d: 1.23, e: 1.23, f: ()}, + {a: 5, b: "string5", c: true, d: 3, e: 3.0, f: ()} + ]); + + (RecC|RecA)[]|csv:Error csv1op3 = csv:parseRecordAsRecordType(value, {skipLines: [2, 4]}); + test:assertEquals(csv1op3, [ + {a: 1, b: "string1", c: true, d: 2.234, e: 2.234, f: ()}, + {a: 3, b: "string3", c: false, d: 1.23, e: 1.23, f: ()}, + {a: 5, b: "string5", c: true, d: 3, e: 3.0, f: ()} + ]); + + (RecB|RecA)[]|csv:Error csv1op4 = csv:parseRecordAsRecordType(value, {skipLines: [2, 4]}); + test:assertEquals(csv1op4, [ + {b: "string1"}, + {b: "string3"}, + {b: "string5"} + ]); + + (RecA|RecB)[]|csv:Error csv1op5 = csv:parseRecordAsRecordType(value, {skipLines: [2, 4]}); + test:assertEquals(csv1op5, [ + {a: 1, b: "string1", c: true, d: 2.234, e: 2.234, f: ()}, + {a: 3, b: "string3", c: false, d: 1.23, e: 1.23, f: ()}, + {a: 5, b: "string5", c: true, d: 3, e: 3.0, f: ()} + ]); + + (record{|int a;|}|record{|string b;|})[]|csv:Error csv1op6 = csv:parseRecordAsRecordType(value, {skipLines: [2, 4]}); + test:assertEquals(csv1op6, [ + {a: 1}, + {a: 3}, + {a: 5} + ]); + + (record{|string b;|}|record{|int a;|})[]|csv:Error csv1op7 = csv:parseRecordAsRecordType(value, {skipLines: [2, 4]}); + test:assertEquals(csv1op7, [ + {b: "string1"}, + {b: "string3"}, + {b: "string5"} + ]); + + (record{|string...;|}|record{|int...;|})[]|csv:Error csv1op8 = csv:parseRecordAsRecordType(value, {}); + test:assertEquals(csv1op8, [ + {b: "string1"}, + {b: "string2"}, + {b: "string3"}, + {b: "string4"}, + {b: "string5"} + ]); + + (record{|int...;|}|record{|string...;|})[]|csv:Error csv1op9 = csv:parseRecordAsRecordType(value, {}); + test:assertEquals(csv1op9, [ + {a: 1, d: 2, e: 2}, + {a: 2, d: 0, e: 0}, + {a: 3, d: 1, e: 1}, + {a: 4, d: -7, e: -7}, + {a: 5, d: 3, e: 3} + ]); + + (record{|int a; string...;|}|record{|string a; int...;|})[]|csv:Error csv1op10 = csv:parseRecordAsRecordType(value, {}); + test:assertEquals(csv1op10, [ + {a: 1, b: "string1"}, + {a: 2, b: "string2"}, + {a: 3, b: "string3"}, + {a: 4, b: "string4"}, + {a: 5, b: "string5"} + ]); + + (record{|string a; int...;|}|record{|int a; string...;|})[]|csv:Error csv1op11 = csv:parseRecordAsRecordType(value, {}); + test:assertEquals(csv1op11, [ + {a: 1, b: "string1"}, + {a: 2, b: "string2"}, + {a: 3, b: "string3"}, + {a: 4, b: "string4"}, + {a: 5, b: "string5"} + ]); + + (record{|string a; int...;|}|record{|string a; string...;|})[]|csv:Error csv1op12 = csv:parseRecordAsRecordType(value, {}); + test:assertTrue(csv1op12 is csv:Error); + test:assertEquals((csv1op12).message(), "The source value cannot convert in to the '(union_type_tests:record {| string a; int...; |}|union_type_tests:record {| string a; string...; |})[]'"); + + (record{|int a; int...;|}|record{|string a; string...;|})[]|csv:Error csv1op13 = csv:parseRecordAsRecordType([{"a": 1, "b": 2}, {"a": "a", "b": "b"}], {}); + test:assertEquals(csv1op13, [ + {a: 1, b: 2}, + {a: "a", b: "b"} + ]); +} + +@test:Config +function testParseToStringWithUnionExpectedTypes3() returns error? { + string[][] value = [ + ["1", "string1", "true", "2.234", "2.234", "()"], + ["2", "string2", "false", "0", "0", "()"], + ["3", "string3", "false", "1.23", "1.23", "()"], + ["4", "string4", "true", "-6.51", "-6.51", "()"], + ["5", "string5", "true", "3", "3.0", "()"] + ]; + + (RecA|RecC)[]|csv:Error csv1op1 = csv:parseListAsRecordType(value, ["a", "b", "c", "d", "e", "f"], {}); + test:assertEquals(csv1op1, [ + {a: 1, b: "string1", c: true, d: 2.234, e: 2.234, f: ()}, + {a: 2, b: "string2", c: false, d: 0, e: 0, f: ()}, + {a: 3, b: "string3", c: false, d: 1.23, e: 1.23, f: ()}, + {a: 4, b: "string4", c: true, d: -6.51, e: -6.51, f: ()}, + {a: 5, b: "string5", c: true, d: 3, e: 3.0, f: ()} + ]); + + (RecA|RecC)[]|csv:Error csv1op2 = csv:parseListAsRecordType(value, ["a", "b", "c", "d", "e", "f"], {skipLines: [2, 4]}); + test:assertTrue(csv1op2 is (RecA|RecC)[]); + test:assertEquals(csv1op2, [ + {a: 1, b: "string1", c: true, d: 2.234, e: 2.234, f: ()}, + {a: 3, b: "string3", c: false, d: 1.23, e: 1.23, f: ()}, + {a: 5, b: "string5", c: true, d: 3, e: 3.0, f: ()} + ]); + + (RecC|RecA)[]|csv:Error csv1op3 = csv:parseListAsRecordType(value, ["a", "b", "c", "d", "e", "f"], {skipLines: [2, 4]}); + test:assertEquals(csv1op3, [ + {a: 1, b: "string1", c: true, d: 2.234, e: 2.234, f: ()}, + {a: 3, b: "string3", c: false, d: 1.23, e: 1.23, f: ()}, + {a: 5, b: "string5", c: true, d: 3, e: 3.0, f: ()} + ]); + + (RecB|RecA)[]|csv:Error csv1op4 = csv:parseListAsRecordType(value, ["a", "b", "c", "d", "e", "f"], {skipLines: [2, 4]}); + test:assertEquals(csv1op4, [ + {a: "1", b: "string1", c: "true", d: "2.234", e: "2.234", f: "()"}, + {a: "3", b: "string3", c: "false", d: "1.23", e: "1.23", f: "()"}, + {a: "5", b: "string5", c: "true", d: "3", e: "3.0", f: "()"} + ]); + + (RecA|RecB)[]|csv:Error csv1op5 = csv:parseListAsRecordType(value, ["a", "b", "c", "d", "e", "f"], {skipLines: [2, 4]}); + test:assertEquals(csv1op5, [ + {a: 1, b: "string1", c: true, d: 2.234, e: 2.234, f: ()}, + {a: 3, b: "string3", c: false, d: 1.23, e: 1.23, f: ()}, + {a: 5, b: "string5", c: true, d: 3, e: 3.0, f: ()} + ]); + + (record{|int a;|}|record{|string b;|})[]|csv:Error csv1op6 = csv:parseListAsRecordType(value, ["a", "b", "c", "d", "e", "f"], {skipLines: [2, 4]}); + test:assertEquals(csv1op6, [ + {a: 1}, + {a: 3}, + {a: 5} + ]); + + (record{|string b;|}|record{|int a;|})[]|csv:Error csv1op7 = csv:parseListAsRecordType(value, ["a", "b", "c", "d", "e", "f"], {skipLines: [2, 4]}); + test:assertEquals(csv1op7, [ + {b: "string1"}, + {b: "string3"}, + {b: "string5"} + ]); + + (record{|string...;|}|record{|int...;|})[]|csv:Error csv1op8 = csv:parseListAsRecordType(value, ["a", "b", "c", "d", "e", "f"], {skipLines: [4, 2]}); + test:assertEquals(csv1op8, [ + {a: "1", b: "string1", c: "true", d: "2.234", e: "2.234", f: "()"}, + {a: "3", b: "string3", c: "false", d: "1.23", e: "1.23", f: "()"}, + {a: "5", b: "string5", c: "true", d: "3", e: "3.0", f: "()"} + ]); + + (record{|int...;|}|record{|string...;|})[]|csv:Error csv1op9 = csv:parseListAsRecordType(value, ["a", "b", "c", "d", "e", "f"], {stringConversion: true}); + test:assertEquals(csv1op9, [ + {a: 1}, + {a: 2, d: 0, e: 0}, + {a: 3}, + {a: 4}, + {a: 5, d: 3} + ]); + + (record{|int...;|}|record{|string...;|})[]|csv:Error csv1op9_2 = csv:parseListAsRecordType(value, ["a", "b", "c", "d", "e", "f"], {stringConversion: false}); + test:assertEquals(csv1op9_2, [ + {}, + {}, + {}, + {}, + {} + ]); + + (record{|int a; string...;|}|record{|string a; int...;|})[]|csv:Error csv1op10 = csv:parseListAsRecordType(value, ["a", "b", "c", "d", "e", "f"], {skipLines: [2, -1, 4]}); + test:assertEquals(csv1op10, [ + {a: 1, b: "string1", c: "true", d: "2.234", e: "2.234", f: "()"}, + {a: 3, b: "string3", c: "false", d: "1.23", e: "1.23", f: "()"}, + {a: 5, b: "string5", c: "true", d: "3", e: "3.0", f: "()"} + ]); + + (record{|string a; int...;|}|record{|int a; string...;|})[]|csv:Error csv1op11 = csv:parseListAsRecordType(value, ["a", "b", "c", "d", "e", "f"], {}); + test:assertEquals(csv1op11, [ + {a: "1"}, + {a: "2", d: 0, e: 0}, + {a: "3"}, + {a: "4"}, + {a: "5", d: 3} + ]); + + (record{|int a; int...;|}|record{|int a; string...;|})[]|csv:Error csv1op12 = csv:parseListAsRecordType(value, ["a", "b", "c", "d", "e", "f"], {stringConversion: false}); + test:assertTrue(csv1op12 is csv:Error); + test:assertEquals((csv1op12).message(), "The source value cannot convert in to the '(union_type_tests:record {| int a; int...; |}|union_type_tests:record {| int a; string...; |})[]'"); + + (record{|int a; int...;|}|record{|string a; string...;|})[]|csv:Error csv1op13 = csv:parseListAsRecordType([["1", "2"], ["a", "b"]], ["a", "b"], {}); + test:assertEquals(csv1op13, [ + {a: 1, b: 2}, + {a: "a", b: "b"} + ]); +} + + +@test:Config +function testParseToStringWithUnionExpectedTypes4() returns error? { + record{int a; string b; boolean c; decimal d; float e; () f;}[] value = [ + {a: 1, b: "string1", c: true, d: 2.234, e: 2.234, f: ()}, + {a: 2, b: "string2", c: false, d: 0, e: 0, f: ()}, + {a: 3, b: "string3", c: false, d: 1.23, e: 1.23, f: ()}, + {a: 4, b: "string4", c: true, d: -6.51, e: -6.51, f: ()}, + {a: 5, b: "string5", c: true, d: 3, e: 3.0, f: ()} + ]; + + (TupA|TupC)[]|csv:Error csv1op1 = csv:parseRecordAsListType(value, ["a", "b", "c", "d", "e", "f"], {}); + test:assertEquals(csv1op1, [ + [1, "string1", true, 2.234, 2.234, ()], + [2, "string2", false, 0, 0, ()], + [3, "string3", false, 1.23, 1.23, ()], + [4, "string4", true, -6.51, -6.51, ()], + [5, "string5", true, 3, 3.0, ()] + ]); + + (TupA|TupC)[]|csv:Error csv1op2 = csv:parseRecordAsListType(value, ["a", "b", "c", "d", "e", "f"], {skipLines: [2, 4]}); + test:assertTrue(csv1op2 is (TupA|TupC)[]); + test:assertEquals(csv1op2, [ + [1, "string1", true, 2.234, 2.234, ()], + [3, "string3", false, 1.23, 1.23, ()], + [5, "string5", true, 3, 3.0, ()] + ]); + + (TupC|TupA)[]|csv:Error csv1op3 = csv:parseRecordAsListType(value, ["a", "b", "c", "d", "e", "f"], {skipLines: [2, 4]}); + test:assertEquals(csv1op3, [ + [1, "string1", true, 2.234, 2.234, ()], + [3, "string3", false, 1.23, 1.23, ()], + [5, "string5", true, 3, 3.0, ()] + ]); + + (TupB|TupA)[]|csv:Error csv1op4 = csv:parseRecordAsListType(value, ["a", "b", "c", "d", "e", "f"], {skipLines: [2, 4]}); + test:assertEquals(csv1op4, [ + [1, "string1", true, 2.234, 2.234, ()], + [3, "string3", false, 1.23, 1.23, ()], + [5, "string5", true, 3, 3.0, ()] + ]); + + (TupB|[boolean])[]|csv:Error csv1op4_2 = csv:parseRecordAsListType(value, ["a", "b", "c", "d", "e", "f"], {skipLines: [2, 4]}); + test:assertTrue(csv1op4_2 is csv:Error); + test:assertEquals((csv1op4_2).message(), "The source value cannot convert in to the '(union_type_tests:TupB|[boolean])[]'"); + + (TupA|TupB)[]|csv:Error csv1op5 = csv:parseRecordAsListType(value, ["a", "b", "c", "d", "e", "f"], {skipLines: [2, 4]}); + test:assertEquals(csv1op5, [ + [1, "string1", true, 2.234, 2.234, ()], + [3, "string3", false, 1.23, 1.23, ()], + [5, "string5", true, 3, 3.0, ()] + ]); + + ([int]|[string])[]|csv:Error csv1op6 = csv:parseRecordAsListType(value, ["a", "b", "c", "d", "e", "f"], {skipLines: [2, 4]}); + test:assertEquals(csv1op6, [ + [1], + [3], + [5] + ]); + + ([string]|[int])[]|csv:Error csv1op7 = csv:parseRecordAsListType(value, ["a", "b", "c", "d", "e", "f"], {skipLines: [2, 4]}); + test:assertEquals(csv1op7, [ + [1], + [3], + [5] + ]); + + ([string...]|[int...])[]|csv:Error csv1op8 = csv:parseRecordAsListType(value, ["a", "b", "c", "d", "e", "f"], {}); + test:assertTrue(csv1op8 is csv:Error); + test:assertEquals((csv1op8).message(), "The source value cannot convert in to the '([string...]|[int...])[]'"); + + ([int...]|[string...])[]|csv:Error csv1op9 = csv:parseRecordAsListType(value, ["a", "b", "c", "d", "e", "f"], {}); + test:assertTrue(csv1op9 is csv:Error); + test:assertEquals((csv1op9).message(), "The source value cannot convert in to the '([int...]|[string...])[]'"); + + ([int, string...]|[string, int...])[]|csv:Error csv1op10 = csv:parseRecordAsListType(value, ["a", "b", "c", "d", "e", "f"], {}); + test:assertTrue(csv1op10 is csv:Error); + test:assertEquals((csv1op10).message(), "The source value cannot convert in to the '([int,string...]|[string,int...])[]'"); + + ([string, int...]|[int, string...])[]|csv:Error csv1op11 = csv:parseRecordAsListType(value, ["a", "b", "c", "d", "e", "f"], {}); + test:assertTrue(csv1op11 is csv:Error); + test:assertEquals((csv1op11).message(), "The source value cannot convert in to the '([string,int...]|[int,string...])[]'"); + + ([string, int...]|[string, string...])[]|csv:Error csv1op12 = csv:parseRecordAsListType(value, ["a", "b", "c", "d", "e", "f"], {}); + test:assertTrue(csv1op12 is csv:Error); + test:assertEquals((csv1op12).message(), "The source value cannot convert in to the '([string,int...]|[string,string...])[]'"); + + ([int, int...]|[string, string...])[]|csv:Error csv1op13 = csv:parseRecordAsListType([{"a": 1, "b": 2}, {"a": "a", "b": "b"}], ["a", "b"], {}); + test:assertEquals(csv1op13, [ + [1, 2], + ["a", "b"] + ]); +} + +@test:Config +function testParseToStringWithUnionExpectedTypes5() returns error? { + string[][] value = [ + ["1", "string1", "true", "2.234", "2.234", "()"], + ["2", "string2", "false", "0", "0", "()"], + ["3", "string3", "false", "1.23", "1.23", "()"], + ["4", "string4", "true", "-6.51", "-6.51", "()"], + ["5", "string5", "true", "3", "3.0", "()"] + ]; + + (TupA|TupC)[]|csv:Error csv1op1 = csv:parseListAsListType(value, {}); + test:assertEquals(csv1op1, [ + [1, "string1", true, 2.234, 2.234, ()], + [2, "string2", false, 0, 0, ()], + [3, "string3", false, 1.23, 1.23, ()], + [4, "string4", true, -6.51, -6.51, ()], + [5, "string5", true, 3, 3.0, ()] + ]); + + (TupA|TupC)[]|csv:Error csv1op2 = csv:parseListAsListType(value, {skipLines: [2, 4]}); + test:assertTrue(csv1op2 is (TupA|TupC)[]); + test:assertEquals(csv1op2, [ + [1, "string1", true, 2.234, 2.234, ()], + [3, "string3", false, 1.23, 1.23, ()], + [5, "string5", true, 3, 3.0, ()] + ]); + + (TupC|TupA)[]|csv:Error csv1op3 = csv:parseListAsListType(value, {skipLines: [2, 4]}); + test:assertEquals(csv1op3, [ + [1, "string1", true, 2.234, 2.234, ()], + [3, "string3", false, 1.23, 1.23, ()], + [5, "string5", true, 3, 3.0, ()] + ]); + + (TupB|TupA)[]|csv:Error csv1op4 = csv:parseListAsListType(value, {skipLines: [2, 4]}); + test:assertEquals(csv1op4, [ + [1, "string1", true, 2.234, 2.234, ()], + [3, "string3", false, 1.23, 1.23, ()], + [5, "string5", true, 3, 3.0, ()] + ]); + + (TupB|[boolean])[]|csv:Error csv1op4_2 = csv:parseListAsListType(value, {skipLines: [2, 4]}); + test:assertTrue(csv1op4_2 is csv:Error); + test:assertEquals((csv1op4_2).message(), "The source value cannot convert in to the '(union_type_tests:TupB|[boolean])[]'"); + + (TupA|TupB)[]|csv:Error csv1op5 = csv:parseListAsListType(value, {skipLines: [2, 4]}); + test:assertEquals(csv1op5, [ + [1, "string1", true, 2.234, 2.234, ()], + [3, "string3", false, 1.23, 1.23, ()], + [5, "string5", true, 3, 3.0, ()] + ]); + + ([int]|[string])[]|csv:Error csv1op6 = csv:parseListAsListType(value, {skipLines: [2, 4]}); + test:assertEquals(csv1op6, [ + [1], + [3], + [5] + ]); + + ([string]|[int])[]|csv:Error csv1op7 = csv:parseListAsListType(value, {skipLines: [2, 4]}); + test:assertEquals(csv1op7, [ + ["1"], + ["3"], + ["5"] + ]); + + ([boolean...]|[int...])[]|csv:Error csv1op8 = csv:parseListAsListType(value, {stringConversion: false}); + test:assertTrue(csv1op8 is csv:Error); + test:assertEquals((csv1op8).message(), "The source value cannot convert in to the '([boolean...]|[int...])[]'"); + + ([string...]|[int...])[]|csv:Error csv1op8_2 = csv:parseListAsListType(value, {}); + test:assertEquals(csv1op8_2, value); + + ([int...]|[string...])[]|csv:Error csv1op9 = csv:parseListAsListType(value, {}); + test:assertEquals(csv1op9, value); + + ([int, string...]|[string, int...])[]|csv:Error csv1op10 = csv:parseListAsListType(value, {}); + test:assertEquals(csv1op10, [ + [1, "string1", "true", "2.234", "2.234", "()"], + [2, "string2", "false", "0", "0", "()"], + [3, "string3", "false", "1.23", "1.23", "()"], + [4, "string4", "true", "-6.51", "-6.51", "()"], + [5, "string5", "true", "3", "3.0", "()"] + ]); + + ([string, int...]|[int, string...])[]|csv:Error csv1op11 = csv:parseListAsListType(value, {}); + test:assertEquals(csv1op11, [ + [1, "string1", "true", "2.234", "2.234", "()"], + [2, "string2", "false", "0", "0", "()"], + [3, "string3", "false", "1.23", "1.23", "()"], + [4, "string4", "true", "-6.51", "-6.51", "()"], + [5, "string5", "true", "3", "3.0", "()"] + ]); + + ([string, int...]|[string, string...])[]|csv:Error csv1op12 = csv:parseListAsListType(value, {}); + test:assertEquals(csv1op12, value); + + ([int, int...]|[string, string...])[]|csv:Error csv1op13 = csv:parseListAsListType([["1", "2"], ["a", "b"]], {}); + test:assertEquals(csv1op13, [ + [1, 2], + ["a", "b"] + ]); +} + +@test:Config +function testParseToStringWithUnionExpectedTypes6() returns error? { + RecA[]|RecC[]|csv:Error csv1op1 = csv:parseStringToRecord(csvStringData1, {header: 1}); + test:assertEquals(csv1op1, [ + {a: 1, b: "string1", c: true, d: 2.234, e: 2.234, f: ()}, + {a: 2, b: "string2", c: false, d: 0, e: 0, f: ()}, + {a: 3, b: "string3", c: false, d: 1.23, e: 1.23, f: ()}, + {a: 4, b: "string4", c: true, d: -6.51, e: -6.51, f: ()}, + {a: 5, b: "string5", c: true, d: 3, e: 3.0, f: ()} + ]); + + RecA[]|RecC[]|csv:Error csv1op2 = csv:parseStringToRecord(csvStringData1, {header: 1, skipLines: [2, 4]}); + test:assertTrue(csv1op2 is RecA[]|RecC[]); + test:assertEquals(csv1op2, [ + {a: 1, b: "string1", c: true, d: 2.234, e: 2.234, f: ()}, + {a: 3, b: "string3", c: false, d: 1.23, e: 1.23, f: ()}, + {a: 5, b: "string5", c: true, d: 3, e: 3.0, f: ()} + ]); + + RecC[]|RecA[]|csv:Error csv1op3 = csv:parseStringToRecord(csvStringData1, {header: 1, skipLines: [2, 4]}); + test:assertEquals(csv1op3, [ + {a: 1, b: "string1", c: true, d: 2.234, e: 2.234, f: ()}, + {a: 3, b: "string3", c: false, d: 1.23, e: 1.23, f: ()}, + {a: 5, b: "string5", c: true, d: 3, e: 3.0, f: ()} + ]); + + RecB[]|RecA[]|csv:Error csv1op4 = csv:parseStringToRecord(csvStringData1, {header: 1, skipLines: [2, 4]}); + test:assertEquals(csv1op4, [ + {a: "1", b: "string1", c: "true", d: "2.234", e: "2.234", f: "()"}, + {a: "3", b: "string3", c: "false", d: "1.23", e: "1.23", f: "()"}, + {a: "5", b: "string5", c: "true", d: "3", e: "3", f: "()"} + ]); + + RecA[]|RecB[]|csv:Error csv1op5 = csv:parseStringToRecord(csvStringData1, {header: 1, skipLines: [2, 4]}); + test:assertEquals(csv1op5, [ + {a: 1, b: "string1", c: true, d: 2.234, e: 2.234, f: ()}, + {a: 3, b: "string3", c: false, d: 1.23, e: 1.23, f: ()}, + {a: 5, b: "string5", c: true, d: 3, e: 3.0, f: ()} + ]); + + record{|int a;|}[]|record{|string b;|}[]|csv:Error csv1op6 = csv:parseStringToRecord(csvStringData1, {header: 1, skipLines: [2, 4]}); + test:assertEquals(csv1op6, [ + {a: 1}, + {a: 3}, + {a: 5} + ]); + + record{|string b;|}[]|record{|int a;|}[]|csv:Error csv1op7 = csv:parseStringToRecord(csvStringData1, {header: 1, skipLines: [2, 4]}); + test:assertEquals(csv1op7, [ + {b: "string1"}, + {b: "string3"}, + {b: "string5"} + ]); + + record{|string...;|}[]|record{|int...;|}[]|csv:Error csv1op8 = csv:parseStringToRecord(csvStringData1, {header: 1}); + test:assertEquals(csv1op8, [ + {a: "1", b: "string1", c: "true", d: "2.234", e: "2.234", f: "()"}, + {a: "2", b: "string2", c: "false", d: "0", e: "0", f: "null"}, + {a: "3", b: "string3", c: "false", d: "1.23", e: "1.23", f: "()"}, + {a: "4", b: "string4", c: "true", d: "-6.51", e: "-6.51", f: "()"}, + {a: "5", b: "string5", c: "true", d: "3", e: "3", f: "()"} + ]); + + record{|int...;|}[]|record{|string...;|}[]|csv:Error csv1op9 = csv:parseStringToRecord(csvStringData1, {header: 1}); + test:assertEquals(csv1op9, [ + {a: 1}, + {a: 2, d: 0, e: 0}, + {a: 3}, + {a: 4}, + {a: 5, d: 3, e: 3} + ]); + + record{|int a; string...;|}[]|record{|string a; int...;|}[]|csv:Error csv1op10 = csv:parseStringToRecord(csvStringData1, {header: 1}); + test:assertEquals(csv1op10, [ + {a: 1, b: "string1", c: "true", d: "2.234", e: "2.234", f: "()"}, + {a: 2, b: "string2", c: "false", d: "0", e: "0", f: "null"}, + {a: 3, b: "string3", c: "false", d: "1.23", e: "1.23", f: "()"}, + {a: 4, b: "string4", c: "true", d: "-6.51", e: "-6.51", f: "()"}, + {a: 5, b: "string5", c: "true", d: "3", e: "3", f: "()"} + ]); + + record{|string a; int...;|}[]|record{|int a; string...;|}[]|csv:Error csv1op11 = csv:parseStringToRecord(csvStringData1, {header: 1}); + test:assertEquals(csv1op11, [ + {a: "1"}, + {a: "2", d: 0, e: 0}, + {a: "3"}, + {a: "4"}, + {a: "5", d: 3, e: 3} + ]); + + record{|int a; int b;|}[]|record{|string a; string...;|}[]|csv:Error csv1op12 = csv:parseStringToRecord(string ` + a,b + 1, 2 + a, b`, {header: 1}); + test:assertEquals(csv1op12, [ + {a: "1", b: "2"}, + {a: "a", b: "b"} + ]); +} + +@test:Config +function testParseToStringWithUnionExpectedTypes7() returns error? { + record{int a; string b; boolean c; decimal d; float e; () f;}[] value = [ + {a: 1, b: "string1", c: true, d: 2.234, e: 2.234, f: ()}, + {a: 2, b: "string2", c: false, d: 0, e: 0, f: ()}, + {a: 3, b: "string3", c: false, d: 1.23, e: 1.23, f: ()}, + {a: 4, b: "string4", c: true, d: -6.51, e: -6.51, f: ()}, + {a: 5, b: "string5", c: true, d: 3, e: 3.0, f: ()} + ]; + + RecA[]|RecC[]|csv:Error csv1op1 = csv:parseRecordAsRecordType(value, {}); + test:assertEquals(csv1op1, [ + {a: 1, b: "string1", c: true, d: 2.234, e: 2.234, f: ()}, + {a: 2, b: "string2", c: false, d: 0, e: 0, f: ()}, + {a: 3, b: "string3", c: false, d: 1.23, e: 1.23, f: ()}, + {a: 4, b: "string4", c: true, d: -6.51, e: -6.51, f: ()}, + {a: 5, b: "string5", c: true, d: 3, e: 3.0, f: ()} + ]); + + RecA[]|RecC[]|csv:Error csv1op2 = csv:parseRecordAsRecordType(value, {skipLines: [2, 4]}); + test:assertTrue(csv1op2 is RecA[]|RecC[]); + test:assertEquals(csv1op2, [ + {a: 1, b: "string1", c: true, d: 2.234, e: 2.234, f: ()}, + {a: 3, b: "string3", c: false, d: 1.23, e: 1.23, f: ()}, + {a: 5, b: "string5", c: true, d: 3, e: 3.0, f: ()} + ]); + + RecC[]|RecA[]|csv:Error csv1op3 = csv:parseRecordAsRecordType(value, {skipLines: [2, 4]}); + test:assertEquals(csv1op3, [ + {a: 1, b: "string1", c: true, d: 2.234, e: 2.234, f: ()}, + {a: 3, b: "string3", c: false, d: 1.23, e: 1.23, f: ()}, + {a: 5, b: "string5", c: true, d: 3, e: 3.0, f: ()} + ]); + + RecB[]|RecA[]|csv:Error csv1op4 = csv:parseRecordAsRecordType(value, {skipLines: [2, 4]}); + test:assertEquals(csv1op4, [ + {b: "string1"}, + {b: "string3"}, + {b: "string5"} + ]); + + RecA[]|RecB[]|csv:Error csv1op5 = csv:parseRecordAsRecordType(value, {skipLines: [2, 4]}); + test:assertEquals(csv1op5, [ + {a: 1, b: "string1", c: true, d: 2.234, e: 2.234, f: ()}, + {a: 3, b: "string3", c: false, d: 1.23, e: 1.23, f: ()}, + {a: 5, b: "string5", c: true, d: 3, e: 3.0, f: ()} + ]); + + record{|int a;|}[]|record{|string b;|}[]|csv:Error csv1op6 = csv:parseRecordAsRecordType(value, {skipLines: [2, 4]}); + test:assertEquals(csv1op6, [ + {a: 1}, + {a: 3}, + {a: 5} + ]); + + record{|string b;|}[]|record{|int a;|}[]|csv:Error csv1op7 = csv:parseRecordAsRecordType(value, {skipLines: [2, 4]}); + test:assertEquals(csv1op7, [ + {b: "string1"}, + {b: "string3"}, + {b: "string5"} + ]); + + record{|string...;|}[]|record{|int...;|}[]|csv:Error csv1op8 = csv:parseRecordAsRecordType(value, {}); + test:assertEquals(csv1op8, [ + {b: "string1"}, + {b: "string2"}, + {b: "string3"}, + {b: "string4"}, + {b: "string5"} + ]); + + record{|int...;|}[]|record{|string...;|}[]|csv:Error csv1op9 = csv:parseRecordAsRecordType(value, {}); + test:assertEquals(csv1op9, [ + {a: 1, d: 2, e: 2}, + {a: 2, d: 0, e: 0}, + {a: 3, d: 1, e: 1}, + {a: 4, d: -7, e: -7}, + {a: 5, d: 3, e: 3} + ]); + + record{|int a; string...;|}[]|record{|string a; int...;|}[]|csv:Error csv1op10 = csv:parseRecordAsRecordType(value, {}); + test:assertEquals(csv1op10, [ + {a: 1, b: "string1"}, + {a: 2, b: "string2"}, + {a: 3, b: "string3"}, + {a: 4, b: "string4"}, + {a: 5, b: "string5"} + ]); + + record{|string a; int...;|}[]|record{|int a; string...;|}[]|csv:Error csv1op11 = csv:parseRecordAsRecordType(value, {}); + test:assertEquals(csv1op11, [ + {a: 1, b: "string1"}, + {a: 2, b: "string2"}, + {a: 3, b: "string3"}, + {a: 4, b: "string4"}, + {a: 5, b: "string5"} + ]); + + record{|string a; int...;|}[]|record{|string a; string...;|}[]|csv:Error csv1op12 = csv:parseRecordAsRecordType(value, {}); + test:assertTrue(csv1op12 is csv:Error); + test:assertEquals((csv1op12).message(), "The source value cannot convert in to the '(union_type_tests:record {| string a; int...; |}[]|union_type_tests:record {| string a; string...; |}[])'"); +} + +@test:Config +function testParseToStringWithUnionExpectedTypes8() returns error? { + string[][] value = [ + ["1", "string1", "true", "2.234", "2.234", "()"], + ["2", "string2", "false", "0", "0", "()"], + ["3", "string3", "false", "1.23", "1.23", "()"], + ["4", "string4", "true", "-6.51", "-6.51", "()"], + ["5", "string5", "true", "3", "3.0", "()"] + ]; + + RecA[]|RecC[]|csv:Error csv1op1 = csv:parseListAsRecordType(value, ["a", "b", "c", "d", "e", "f"], {}); + test:assertEquals(csv1op1, [ + {a: 1, b: "string1", c: true, d: 2.234, e: 2.234, f: ()}, + {a: 2, b: "string2", c: false, d: 0, e: 0, f: ()}, + {a: 3, b: "string3", c: false, d: 1.23, e: 1.23, f: ()}, + {a: 4, b: "string4", c: true, d: -6.51, e: -6.51, f: ()}, + {a: 5, b: "string5", c: true, d: 3, e: 3.0, f: ()} + ]); + + RecA[]|RecC[]|csv:Error csv1op2 = csv:parseListAsRecordType(value, ["a", "b", "c", "d", "e", "f"], {skipLines: [2, 4]}); + test:assertTrue(csv1op2 is RecA[]|RecC[]); + test:assertEquals(csv1op2, [ + {a: 1, b: "string1", c: true, d: 2.234, e: 2.234, f: ()}, + {a: 3, b: "string3", c: false, d: 1.23, e: 1.23, f: ()}, + {a: 5, b: "string5", c: true, d: 3, e: 3.0, f: ()} + ]); + + RecC[]|RecA[]|csv:Error csv1op3 = csv:parseListAsRecordType(value, ["a", "b", "c", "d", "e", "f"], {skipLines: [2, 4]}); + test:assertEquals(csv1op3, [ + {a: 1, b: "string1", c: true, d: 2.234, e: 2.234, f: ()}, + {a: 3, b: "string3", c: false, d: 1.23, e: 1.23, f: ()}, + {a: 5, b: "string5", c: true, d: 3, e: 3.0, f: ()} + ]); + + RecB[]|RecA[]|csv:Error csv1op4 = csv:parseListAsRecordType(value, ["a", "b", "c", "d", "e", "f"], {skipLines: [2, 4]}); + test:assertEquals(csv1op4, [ + {a: "1", b: "string1", c: "true", d: "2.234", e: "2.234", f: "()"}, + {a: "3", b: "string3", c: "false", d: "1.23", e: "1.23", f: "()"}, + {a: "5", b: "string5", c: "true", d: "3", e: "3.0", f: "()"} + ]); + + RecA[]|RecB[]|csv:Error csv1op5 = csv:parseListAsRecordType(value, ["a", "b", "c", "d", "e", "f"], {skipLines: [2, 4]}); + test:assertEquals(csv1op5, [ + {a: 1, b: "string1", c: true, d: 2.234, e: 2.234, f: ()}, + {a: 3, b: "string3", c: false, d: 1.23, e: 1.23, f: ()}, + {a: 5, b: "string5", c: true, d: 3, e: 3.0, f: ()} + ]); + + record{|int a;|}[]|record{|string b;|}[]|csv:Error csv1op6 = csv:parseListAsRecordType(value, ["a", "b", "c", "d", "e", "f"], {skipLines: [2, 4]}); + test:assertEquals(csv1op6, [ + {a: 1}, + {a: 3}, + {a: 5} + ]); + + record{|string b;|}[]|record{|int a;|}[]|csv:Error csv1op7 = csv:parseListAsRecordType(value, ["a", "b", "c", "d", "e", "f"], {skipLines: [2, 4]}); + test:assertEquals(csv1op7, [ + {b: "string1"}, + {b: "string3"}, + {b: "string5"} + ]); + + record{|string...;|}[]|record{|int...;|}[]|csv:Error csv1op8 = csv:parseListAsRecordType(value, ["a", "b", "c", "d", "e", "f"], {skipLines: [4, 2]}); + test:assertEquals(csv1op8, [ + {a: "1", b: "string1", c: "true", d: "2.234", e: "2.234", f: "()"}, + {a: "3", b: "string3", c: "false", d: "1.23", e: "1.23", f: "()"}, + {a: "5", b: "string5", c: "true", d: "3", e: "3.0", f: "()"} + ]); + + record{|int...;|}[]|record{|string...;|}[]|csv:Error csv1op9 = csv:parseListAsRecordType(value, ["a", "b", "c", "d", "e", "f"], {stringConversion: true}); + test:assertEquals(csv1op9, [ + {a: 1}, + {a: 2, d: 0, e: 0}, + {a: 3}, + {a: 4}, + {a: 5, d: 3} + ]); + + record{|int...;|}[]|record{|string...;|}[]|csv:Error csv1op9_2 = csv:parseListAsRecordType(value, ["a", "b", "c", "d", "e", "f"], {stringConversion: false}); + test:assertEquals(csv1op9_2, [ + {}, + {}, + {}, + {}, + {} + ]); + + record{|int a; string...;|}[]|record{|string a; int...;|}[]|csv:Error csv1op10 = csv:parseListAsRecordType(value, ["a", "b", "c", "d", "e", "f"], {skipLines: [2, -1, 4]}); + test:assertEquals(csv1op10, [ + {a: 1, b: "string1", c: "true", d: "2.234", e: "2.234", f: "()"}, + {a: 3, b: "string3", c: "false", d: "1.23", e: "1.23", f: "()"}, + {a: 5, b: "string5", c: "true", d: "3", e: "3.0", f: "()"} + ]); + + record{|string a; int...;|}[]|record{|int a; string...;|}[]|csv:Error csv1op11 = csv:parseListAsRecordType(value, ["a", "b", "c", "d", "e", "f"], {}); + test:assertEquals(csv1op11, [ + {a: "1"}, + {a: "2", d: 0, e: 0}, + {a: "3"}, + {a: "4"}, + {a: "5", d: 3} + ]); + + record{|int a; int...;|}[]|record{|int a; string...;|}[]|csv:Error csv1op12 = csv:parseListAsRecordType(value, ["a", "b", "c", "d", "e", "f"], {stringConversion: false}); + test:assertTrue(csv1op12 is csv:Error); + test:assertEquals((csv1op12).message(), "The source value cannot convert in to the '(union_type_tests:record {| int a; int...; |}[]|union_type_tests:record {| int a; string...; |}[])'"); + + record{|int a; int...;|}[]|record{|string a; string...;|}[]|csv:Error csv1op13 = csv:parseListAsRecordType([["1", "2"], ["a", "b"]], ["a", "b"], {}); + test:assertEquals(csv1op13, [ + {a: "1", b: "2"}, + {a: "a", b: "b"} + ]); +} + + +@test:Config +function testParseToStringWithUnionExpectedTypes9() returns error? { + record{int a; string b; boolean c; decimal d; float e; () f;}[] value = [ + {a: 1, b: "string1", c: true, d: 2.234, e: 2.234, f: ()}, + {a: 2, b: "string2", c: false, d: 0, e: 0, f: ()}, + {a: 3, b: "string3", c: false, d: 1.23, e: 1.23, f: ()}, + {a: 4, b: "string4", c: true, d: -6.51, e: -6.51, f: ()}, + {a: 5, b: "string5", c: true, d: 3, e: 3.0, f: ()} + ]; + + TupA[]|TupC[]|csv:Error csv1op1 = csv:parseRecordAsListType(value, ["a", "b", "c", "d", "e", "f"], {}); + test:assertEquals(csv1op1, [ + [1, "string1", true, 2.234, 2.234, ()], + [2, "string2", false, 0, 0, ()], + [3, "string3", false, 1.23, 1.23, ()], + [4, "string4", true, -6.51, -6.51, ()], + [5, "string5", true, 3, 3.0, ()] + ]); + + TupA[]|TupC[]|csv:Error csv1op2 = csv:parseRecordAsListType(value, ["a", "b", "c", "d", "e", "f"], {skipLines: [2, 4]}); + test:assertTrue(csv1op2 is TupA[]|TupC[]); + test:assertEquals(csv1op2, [ + [1, "string1", true, 2.234, 2.234, ()], + [3, "string3", false, 1.23, 1.23, ()], + [5, "string5", true, 3, 3.0, ()] + ]); + + TupC[]|TupA[]|csv:Error csv1op3 = csv:parseRecordAsListType(value, ["a", "b", "c", "d", "e", "f"], {skipLines: [2, 4]}); + test:assertEquals(csv1op3, [ + [1, "string1", true, 2.234, 2.234, ()], + [3, "string3", false, 1.23, 1.23, ()], + [5, "string5", true, 3, 3.0, ()] + ]); + + TupB[]|TupA[]|csv:Error csv1op4 = csv:parseRecordAsListType(value, ["a", "b", "c", "d", "e", "f"], {skipLines: [2, 4]}); + test:assertEquals(csv1op4, [ + [1, "string1", true, 2.234, 2.234, ()], + [3, "string3", false, 1.23, 1.23, ()], + [5, "string5", true, 3, 3.0, ()] + ]); + + TupB[]|[boolean][]|csv:Error csv1op4_2 = csv:parseRecordAsListType(value, ["a", "b", "c", "d", "e", "f"], {skipLines: [2, 4]}); + test:assertTrue(csv1op4_2 is csv:Error); + test:assertEquals((csv1op4_2).message(), "The source value cannot convert in to the '(union_type_tests:TupB[]|[boolean][])'"); + + TupA[]|TupB[]|csv:Error csv1op5 = csv:parseRecordAsListType(value, ["a", "b", "c", "d", "e", "f"], {skipLines: [2, 4]}); + test:assertEquals(csv1op5, [ + [1, "string1", true, 2.234, 2.234, ()], + [3, "string3", false, 1.23, 1.23, ()], + [5, "string5", true, 3, 3.0, ()] + ]); + + [int][]|[string][]|csv:Error csv1op6 = csv:parseRecordAsListType(value, ["a", "b", "c", "d", "e", "f"], {skipLines: [2, 4]}); + test:assertEquals(csv1op6, [ + [1], + [3], + [5] + ]); + + [string][]|[int][]|csv:Error csv1op7 = csv:parseRecordAsListType(value, ["a", "b", "c", "d", "e", "f"], {skipLines: [2, 4]}); + test:assertEquals(csv1op7, [ + [1], + [3], + [5] + ]); + + [string...][]|[int...][]|csv:Error csv1op8 = csv:parseRecordAsListType(value, ["a", "b", "c", "d", "e", "f"], {}); + test:assertTrue(csv1op8 is csv:Error); + test:assertEquals((csv1op8).message(), "The source value cannot convert in to the '([string...][]|[int...][])'"); + + [int...][]|[string...][]|csv:Error csv1op9 = csv:parseRecordAsListType(value, ["a", "b", "c", "d", "e", "f"], {}); + test:assertTrue(csv1op9 is csv:Error); + test:assertEquals((csv1op9).message(), "The source value cannot convert in to the '([int...][]|[string...][])'"); + + [int, string...][]|[string, int...][]|csv:Error csv1op10 = csv:parseRecordAsListType(value, ["a", "b", "c", "d", "e", "f"], {}); + test:assertTrue(csv1op10 is csv:Error); + test:assertEquals((csv1op10).message(), "The source value cannot convert in to the '([int,string...][]|[string,int...][])'"); + + [string, int...][]|[int, string...][]|csv:Error csv1op11 = csv:parseRecordAsListType(value, ["a", "b", "c", "d", "e", "f"], {}); + test:assertTrue(csv1op11 is csv:Error); + test:assertEquals((csv1op11).message(), "The source value cannot convert in to the '([string,int...][]|[int,string...][])'"); + + [string, int...][]|[string, string...][]|csv:Error csv1op12 = csv:parseRecordAsListType(value, ["a", "b", "c", "d", "e", "f"], {}); + test:assertTrue(csv1op12 is csv:Error); + test:assertEquals((csv1op12).message(), "The source value cannot convert in to the '([string,int...][]|[string,string...][])'"); +} + +@test:Config +function testParseToStringWithUnionExpectedTypes10() returns error? { + string[][] value = [ + ["1", "string1", "true", "2.234", "2.234", "()"], + ["2", "string2", "false", "0", "0", "()"], + ["3", "string3", "false", "1.23", "1.23", "()"], + ["4", "string4", "true", "-6.51", "-6.51", "()"], + ["5", "string5", "true", "3", "3.0", "()"] + ]; + + TupA[]|TupC[]|csv:Error csv1op1 = csv:parseListAsListType(value, {}); + test:assertEquals(csv1op1, [ + [1, "string1", true, 2.234, 2.234, ()], + [2, "string2", false, 0, 0, ()], + [3, "string3", false, 1.23, 1.23, ()], + [4, "string4", true, -6.51, -6.51, ()], + [5, "string5", true, 3, 3.0, ()] + ]); + + TupA[]|TupC[]|csv:Error csv1op2 = csv:parseListAsListType(value, {skipLines: [2, 4]}); + test:assertTrue(csv1op2 is TupA[]|TupC[]); + test:assertEquals(csv1op2, [ + [1, "string1", true, 2.234, 2.234, ()], + [3, "string3", false, 1.23, 1.23, ()], + [5, "string5", true, 3, 3.0, ()] + ]); + + TupC[]|TupA[]|csv:Error csv1op3 = csv:parseListAsListType(value, {skipLines: [2, 4]}); + test:assertEquals(csv1op3, [ + [1, "string1", true, 2.234, 2.234, ()], + [3, "string3", false, 1.23, 1.23, ()], + [5, "string5", true, 3, 3.0, ()] + ]); + + TupB[]|TupA[]|csv:Error csv1op4 = csv:parseListAsListType(value, {skipLines: [2, 4]}); + test:assertEquals(csv1op4, [ + [1, "string1", true, 2.234, 2.234, ()], + [3, "string3", false, 1.23, 1.23, ()], + [5, "string5", true, 3, 3.0, ()] + ]); + + TupB[]|[boolean][]|csv:Error csv1op4_2 = csv:parseListAsListType(value, {skipLines: [2, 4]}); + test:assertTrue(csv1op4_2 is csv:Error); + test:assertEquals((csv1op4_2).message(), "The source value cannot convert in to the '(union_type_tests:TupB[]|[boolean][])'"); + + TupA[]|TupB[]|csv:Error csv1op5 = csv:parseListAsListType(value, {skipLines: [2, 4]}); + test:assertEquals(csv1op5, [ + [1, "string1", true, 2.234, 2.234, ()], + [3, "string3", false, 1.23, 1.23, ()], + [5, "string5", true, 3, 3.0, ()] + ]); + + [int][]|[string][]|csv:Error csv1op6 = csv:parseListAsListType(value, {skipLines: [2, 4]}); + test:assertEquals(csv1op6, [ + [1], + [3], + [5] + ]); + + [string][]|[int][]|csv:Error csv1op7 = csv:parseListAsListType(value, {skipLines: [2, 4]}); + test:assertEquals(csv1op7, [ + ["1"], + ["3"], + ["5"] + ]); + + [boolean...][]|[int...][]|csv:Error csv1op8 = csv:parseListAsListType(value, {stringConversion: false}); + test:assertTrue(csv1op8 is csv:Error); + test:assertEquals((csv1op8).message(), "The source value cannot convert in to the '([boolean...][]|[int...][])'"); + + [string...][]|[int...][]|csv:Error csv1op8_2 = csv:parseListAsListType(value, {}); + test:assertEquals(csv1op8_2, value); + + [int...][]|[string...][]|csv:Error csv1op9 = csv:parseListAsListType(value, {}); + test:assertEquals(csv1op9, value); + + [int, string...][]|[string, int...][]|csv:Error csv1op10 = csv:parseListAsListType(value, {}); + test:assertEquals(csv1op10, [ + [1, "string1", "true", "2.234", "2.234", "()"], + [2, "string2", "false", "0", "0", "()"], + [3, "string3", "false", "1.23", "1.23", "()"], + [4, "string4", "true", "-6.51", "-6.51", "()"], + [5, "string5", "true", "3", "3.0", "()"] + ]); + + [string, int...][]|[int, string...][]|csv:Error csv1op11 = csv:parseListAsListType(value, {}); + test:assertEquals(csv1op11, [ + [1, "string1", "true", "2.234", "2.234", "()"], + [2, "string2", "false", "0", "0", "()"], + [3, "string3", "false", "1.23", "1.23", "()"], + [4, "string4", "true", "-6.51", "-6.51", "()"], + [5, "string5", "true", "3", "3.0", "()"] + ]); + + [string, int...][]|[string, string...][]|csv:Error csv1op12 = csv:parseListAsListType(value, {}); + test:assertEquals(csv1op12, value); +} diff --git a/ballerina-tests/union-type-tests/tests/types.bal b/ballerina-tests/union-type-tests/tests/types.bal new file mode 100644 index 0000000..a2b4b2b --- /dev/null +++ b/ballerina-tests/union-type-tests/tests/types.bal @@ -0,0 +1,2534 @@ +type BooleanRecord1 record { + boolean b1; + boolean|string b2; + boolean|string? b3; + boolean b4; +}; + +type BooleanRecord2 record {| + boolean b1; + boolean|string b2; + boolean|string? b3; + boolean b4; +|}; + +type BooleanRecord3 record {| + boolean b1; + boolean? b3; +|}; + +type BooleanRecord4 record { + boolean b1; + boolean? b3; +}; + +type BooleanRecord5 record { + boolean b1; + boolean? b3; + string defaultableField = ""; + string? nillableField = (); +}; + +type BooleanRecord6 record {| + boolean b1; + boolean? b3; + string defaultableField = ""; + string? nillableField = (); +|}; + +type BooleanRecord7 record { + boolean b1; + boolean? b3; + string defaultableField = ""; + string? nillableField = (); + string requiredField; +}; + +type BooleanRecord8 record {| + boolean b1; + boolean? b3; + string defaultableField = ""; + string? nillableField = (); + string requiredField; +|}; + +type BooleanRecord9 record {| + boolean b1; + boolean? b3; + boolean?...; +|}; + +type BooleanRecord10 record {| + boolean...; +|}; + +type BooleanRecord11 record {| + boolean b1; + string defaultableField = ""; + string? nillableField = (); + boolean?|string...; +|}; + +type BooleanRecord12 record {| + boolean b1; + string defaultableField = ""; + string? nillableField = (); + string requiredField; + boolean...; +|}; + +type BooleanRecord13 record {| + string defaultableField = ""; + string? nillableField = (); + string|boolean...; +|}; + +type BooleanRecord14 record {| + string defaultableField = ""; + string? nillableField = (); + string requiredField; + boolean...; +|}; + +type BooleanRecord15 record {| + int b1; + string defaultableField = ""; + string? nillableField = (); + boolean?...; +|}; + +type BooleanRecord16 record {| + boolean?...; +|}; + +type BooleanRecord17 record {| + int...; +|}; + +type BooleanRecord18 record {| + boolean b2; + int?...; +|}; + +type NilRecord1 record { + () n1; + () n2; + () n3; +}; + +type NilRecord2 record {| + () n1; + () n2; + () n3; +|}; + +type NilRecord3 record {| + () n1; + () n4; +|}; + +type NilRecord4 record { + () n1; + () n4; +}; + +type NilRecord5 record { + () n1; + () n4; + string defaultableField = ""; + string? nillableField = (); +}; + +type NilRecord6 record {| + () n1; + () n4; + string defaultableField = ""; + string? nillableField = (); +|}; + +type NilRecord7 record { + () n1; + () n4; + string defaultableField = ""; + string? nillableField = (); + string requiredField; +}; + +type NilRecord8 record {| + () n1; + () n4; + string defaultableField = ""; + string? nillableField = (); + string requiredField; +|}; + +type NilRecord9 record {| + () n1; + () n2; + ()...; +|}; + +type NilRecord10 record {| + ()...; +|}; + +type NilRecord11 record {| + () n1; + string defaultableField = ""; + string? nillableField = (); + ()...; +|}; + +type NilRecord12 record {| + () n1; + string defaultableField = ""; + string? nillableField = (); + string requiredField; + ()...; +|}; + +type NilRecord13 record {| + string defaultableField = ""; + string? nillableField = (); + ()...; +|}; + +type NilRecord14 record {| + string defaultableField = ""; + string? nillableField = (); + string requiredField; + ()...; +|}; + +type IntegerRecord1 record { + int i1; + int i2; + int i3; + int? i4; + int? i5; + int i6; + int i7; + int? i8; +}; + +type IntegerRecord2 record {| + int i1; + int? i2; + int i3; + int i4; + int? i5; + int i6; + int i7; + int? i8; +|}; + +type IntegerRecord3 record {| + int i1; + int i4; + int i6; +|}; + +type IntegerRecord4 record { + int i1; + int i4; + int i6; +}; + +type IntegerRecord5 record { + int i1; + int i4; + int i6; + string defaultableField = ""; + string? nillableField = (); +}; + +type IntegerRecord6 record {| + int i1; + int i4; + int i6; + string defaultableField = ""; + string? nillableField = (); +|}; + +type IntegerRecord7 record { + int i1; + int i4; + int i6; + string defaultableField = ""; + string? nillableField = (); + string requiredField; +}; + +type IntegerRecord8 record {| + int i1; + int i4; + int i6; + string defaultableField = ""; + string? nillableField = (); + string requiredField; +|}; + +type IntegerRecord9 record {| + int i1; + int i2; + int...; +|}; + +type IntegerRecord10 record {| + int...; +|}; + +type IntegerRecord11 record {| + int i1; + string defaultableField = ""; + string? nillableField = (); + int...; +|}; + +type IntegerRecord12 record {| + int i1; + string defaultableField = ""; + string? nillableField = (); + string requiredField; + int...; +|}; + +type IntegerRecord13 record {| + string defaultableField = ""; + string? nillableField = (); + int...; +|}; + +type IntegerRecord14 record {| + string defaultableField = ""; + string? nillableField = (); + string requiredField; + int...; +|}; + +type FloatRecord1 record { + float f1; + float f2; + float f3; + float f4; + float f5; + float f6; + float f7; + float f8; +}; + +type FloatRecord2 record {| + float f1; + float f2; + float f3; + float f4; + float f5; + float f6; + float f7; + float f8; +|}; + +type FloatRecord3 record {| + float f1; + float f4; + float f7; +|}; + +type FloatRecord4 record { + float f1; + float f4; + float f7; +}; + +type FloatRecord5 record { + float f1; + float f4; + float f7; + string defaultableField = ""; + string? nillableField = (); +}; + +type FloatRecord6 record {| + float f1; + float f4; + float f7; + string defaultableField = ""; + string? nillableField = (); +|}; + +type FloatRecord7 record { + float f1; + float f4; + float f7; + string defaultableField = ""; + string? nillableField = (); + string requiredField; +}; + +type FloatRecord8 record {| + float f1; + float f4; + float f7; + string defaultableField = ""; + string? nillableField = (); + string requiredField; +|}; + +type FloatRecord9 record {| + float f1; + float f2; + float...; +|}; + +type FloatRecord10 record {| + float...; +|}; + +type FloatRecord11 record {| + float f1; + string defaultableField = ""; + string? nillableField = (); + float...; +|}; + +type FloatRecord12 record {| + float f1; + string defaultableField = ""; + string? nillableField = (); + string requiredField; + float...; +|}; + +type FloatRecord13 record {| + string defaultableField = ""; + string? nillableField = (); + float...; +|}; + +type FloatRecord14 record {| + string defaultableField = ""; + string? nillableField = (); + string requiredField; + float...; +|}; + +type DecimalRecord1 record { + decimal d1; + decimal d2; + decimal d3; + decimal d4; + decimal d5; + decimal d6; + decimal d7; + decimal d8; +}; + +type DecimalRecord2 record {| + decimal d1; + decimal d2; + decimal d3; + decimal d4; + decimal d5; + decimal d6; + decimal d7; + decimal d8; +|}; + +type DecimalRecord3 record {| + decimal d1; + decimal d4; + decimal d7; +|}; + +type DecimalRecord4 record { + decimal d1; + decimal d4; + decimal d7; +}; + +type DecimalRecord5 record { + decimal d1; + decimal d4; + decimal d7; + string defaultableField = ""; + string? nillableField = (); +}; + +type DecimalRecord6 record {| + decimal d1; + decimal d4; + decimal d7; + string defaultableField = ""; + string? nillableField = (); +|}; + +type DecimalRecord7 record { + decimal d1; + decimal d4; + decimal d7; + string defaultableField = ""; + string? nillableField = (); + string requiredField; +}; + +type DecimalRecord8 record {| + decimal d1; + decimal d4; + decimal d7; + string defaultableField = ""; + string? nillableField = (); + string requiredField; +|}; + +type DecimalRecord9 record {| + decimal d1; + decimal d2; + decimal...; +|}; + +type DecimalRecord10 record {| + decimal...; +|}; + +type DecimalRecord11 record {| + decimal d1; + string defaultableField = ""; + string? nillableField = (); + decimal...; +|}; + +type DecimalRecord12 record {| + decimal d1; + string defaultableField = ""; + string? nillableField = (); + string requiredField; + decimal...; +|}; + +type DecimalRecord13 record {| + string defaultableField = ""; + string? nillableField = (); + decimal...; +|}; + +type DecimalRecord14 record {| + string defaultableField = ""; + string? nillableField = (); + string requiredField; + decimal...; +|}; + +type StringRecord1 record { + string s1; + string s2; + string s3; +}; + +type StringRecord2 record {| + string s1; + string s2; + string s3; +|}; + +type StringRecord3 record {| + string s1; + string s4; +|}; + +type StringRecord4 record { + string s1; + string s4; +}; + +type StringRecord5 record { + string s1; + string s4; + string defaultableField = ""; + string? nillableField = (); +}; + +type StringRecord6 record {| + string s1; + string s4; + string defaultableField = ""; + string? nillableField = (); +|}; + +type StringRecord7 record { + string s1; + string s4; + string defaultableField = ""; + string? nillableField = (); + string requiredField; +}; + +type StringRecord8 record {| + string s1; + string s4; + string defaultableField = ""; + string? nillableField = (); + string requiredField; +|}; + +type StringRecord9 record {| + string s1; + string s2; + string...; +|}; + +type StringRecord10 record {| + string...; +|}; + +type StringRecord11 record {| + string s1; + string defaultableField = ""; + string? nillableField = (); + string...; +|}; + +type StringRecord12 record {| + string d1; + string defaultableField = ""; + string? nillableField = (); + string requiredField; + string...; +|}; + +type StringRecord13 record {| + string defaultableField = ""; + string? nillableField = (); + string...; +|}; + +type StringRecord14 record {| + string defaultableField = ""; + string? nillableField = (); + string requiredField; + string...; +|}; + +type StringRecord15 record {| + string defaultableField = ""; + string? nillableField = (); + string requiredField; + string...; +|}; + +type StringRecord16 record {| + string?...; +|}; + +type StringRecord17 record {| + int...; +|}; + +type StringRecord18 record {| + string b2; + int?...; +|}; + +type StringRecord19 record { + string s1 = ""; + string s2 = ""; +}; + +type StringRecord20 record {| + string s1 = ""; + string s2 = ""; +|}; + +type StringRecord21 record { +}; + +type StringRecord22 record {| + string s1 = ""; + string s2 = ""; + json...; +|}; + +type StringRecord23 record {| + json...; +|}; + +type JsonRecord1 record { + json j1; + json j2; + json j3; +}; + +type JsonRecord2 record {| + json j1; + json j2; + json j3; +|}; + +type JsonRecord3 record {| + json j1; + json j4; +|}; + +type JsonRecord4 record { + json j1; + json j4; +}; + +type JsonRecord5 record { + json j1; + json j4; + json defaultableField = ""; + json? nillableField = (); +}; + +type JsonRecord6 record {| + json j1; + json j4; + json defaultableField = ""; + json? nillableField = (); +|}; + +type JsonRecord7 record { + json j1; + json j4; + json defaultableField = ""; + json? nillableField = (); + json requiredField; +}; + +type JsonRecord8 record {| + json j1; + json j4; + json defaultableField = ""; + json? nillableField = (); + json requiredField; +|}; + +type JsonRecord9 record {| + json j1; + json j2; + json...; +|}; + +type JsonRecord10 record {| + json...; +|}; + +type JsonRecord11 record {| + json j1; + json defaultableField = ""; + json? nillableField = (); + json...; +|}; + +type JsonRecord12 record {| + json j1; + json defaultableField = ""; + json? nillableField = (); + json requiredField; + json...; +|}; + +type JsonRecord13 record {| + json defaultableField = ""; + json? nillableField = (); + json...; +|}; + +type JsonRecord14 record {| + json defaultableField = ""; + json? nillableField = (); + json requiredField; + json...; +|}; + +type AnydataRecord1 record { + anydata anydata1; + anydata anydata2; + anydata anydata3; +}; + +type AnydataRecord2 record {| + anydata anydata1; + anydata anydata2; + anydata anydata3; +|}; + +type AnydataRecord3 record {| + anydata anydata1; + anydata anydata4; +|}; + +type AnydataRecord4 record { + anydata anydata1; + anydata anydata4; +}; + +type AnydataRecord5 record { + anydata anydata1; + anydata anydata4; + anydata defaultableField = ""; + anydata? nillableField = (); +}; + +type AnydataRecord6 record {| + anydata anydata1; + anydata anydata4; + anydata defaultableField = ""; + anydata? nillableField = (); +|}; + +type AnydataRecord7 record { + anydata anydata1; + anydata anydata4; + anydata defaultableField = ""; + anydata? nillableField = (); + anydata requiredField; +}; + +type AnydataRecord8 record {| + anydata anydata1; + anydata anydata4; + anydata defaultableField = ""; + anydata? nillableField = (); + anydata requiredField; +|}; + +type AnydataRecord9 record {| + anydata anydata1; + anydata anydata2; + anydata...; +|}; + +type AnydataRecord10 record {| + anydata...; +|}; + +type AnydataRecord11 record {| + anydata anydata1; + anydata defaultableField = ""; + anydata? nillableField = (); + anydata...; +|}; + +type AnydataRecord12 record {| + anydata anydata1; + anydata defaultableField = ""; + anydata? nillableField = (); + anydata requiredField; + anydata...; +|}; + +type AnydataRecord13 record {| + anydata defaultableField = ""; + anydata? nillableField = (); + anydata...; +|}; + +type AnydataRecord14 record {| + anydata defaultableField = ""; + anydata? nillableField = (); + anydata requiredField; + anydata...; +|}; + +type CustomRecord1 record { + int i1; + int i2; + string s1; + string s2; + boolean b1; + boolean b2; + () n1; + () n2; + float f1; + float f2; + decimal d1; + decimal d2; +}; + +type CustomRecord2 record {| + int i1; + int i2; + string s1; + string s2; + boolean b1; + boolean b2; + () n1; + () n2; + float f1; + float f2; + decimal d1; + decimal d2; +|}; + +type CustomRecord3 record {| + int i1; + string s1; + boolean b1; + () n1; + float f1; + decimal d1; +|}; + +type CustomRecord4 record { + int i1; + string s1; + boolean b1; + () n1; + float f1; + decimal d1; +}; + +type CustomRecord5 record { + int i1; + string s1; + boolean b1; + () n1; + float f1; + decimal d1; + string defaultableField = ""; + string? nillableField = (); +}; + +type CustomRecord6 record {| + int i1; + string s1; + boolean b1; + () n1; + float f1; + decimal d1; + anydata defaultableField = ""; + anydata? nillableField = (); +|}; + +type CustomRecord7 record { + int i1; + string s1; + boolean b1; + () n1; + float f1; + decimal d1; + anydata defaultableField = ""; + anydata? nillableField = (); + anydata requiredField; +}; + +type CustomRecord8 record {| + int i1; + string s1; + boolean b1; + () n1; + float f1; + decimal d1; + anydata defaultableField = ""; + anydata? nillableField = (); + anydata requiredField; +|}; + +type CustomRecord9 record {| + int i1; + string s1; + boolean b1; + () n1; + float f1; + decimal d1; + string...; +|}; + +type CustomRecord10 record {| + string...; +|}; + +type CustomRecord11 record {| + int i1; + string s1; + boolean b1; + () n1; + float f1; + decimal d1; + anydata defaultableField = ""; + anydata? nillableField = (); + string...; +|}; + +type CustomRecord12 record {| + int i1; + string s1; + boolean b1; + () n1; + float f1; + decimal d1; + anydata defaultableField = ""; + anydata? nillableField = (); + anydata requiredField; + string...; +|}; + +type CustomRecord13 record {| + anydata defaultableField = ""; + anydata? nillableField = (); + string...; +|}; + +type CustomRecord14 record {| + anydata defaultableField = ""; + anydata? nillableField = (); + anydata requiredField; + string...; +|}; + +type CustomRecord15 record {| + string '1; + string '2; +|}; + +type CustomRecord16 record {| + string '1; + string '2; + string '3; + string '4; +|}; + +type CustomRecord17 record { + string '1; + string '2; +}; + +type CustomRecord18 record { + string '1; + string '2; + string '3; + string '4; +}; + +type CustomRecord19 record { + string '1; + string '2; + string '3 = ""; + string '4 = ""; +}; + +type CustomRecord20 record { + string '1; +}; + +type CustomRecord21 record {| + string '1; + json...; +|}; + +type CustomRecord22 record {| + string '1; + string...; +|}; + +type CustomRecord23 record {| + string '1; + string a = ""; + string...; +|}; + +type CustomRecord24 record {| + string '1; + string '2 = ""; + string...; +|}; + +type CustomRecord25 record {| + int '1; + string...; +|}; + +type CustomRecord26 record {| + string '1; + int...; +|}; + +type CustomRecord27 record {| + int i1; + string s1; + boolean b1; + () n1; + float f1; + decimal d1; + anydata a1; + json j1; + anydata defaultableField = ""; + anydata? nillableField = (); + string...; +|}; + +type CustomRecord28 record { + string '1; +}; + +type CustomRecord29 record { + int '1; +}; + +type CustomRecord30 record {| + string '1; + string '2; + string '3; + string '4; + string '5; + string '6; +|}; + +type CustomRecord31 record {| + string '1; + string '6; +|}; + +type CustomRecord32 record {| + int '1; +|}; + +type CustomRecord33 record {| + string '1; + string '2; + string '3; + string '4; + string '5; + string '6; +|}; + +type CustomRecord34 record { + string '1; + string '6; + string '5 = ""; +}; + +type CustomRecord35 record { + string '1; + string '6; + string '9 = ""; +}; + +type CustomRecord36 record {| + string '1; + string '6; + string '9 = ""; +|}; + +type CustomRecord37 record {| + string '1; + string '6; + string '5 = ""; +|}; + +type CustomRecord38 record {| + string '1; + string '2; + string '3; + string '4; + string '5; + string '6; + string ...; +|}; + +type CustomRecord39 record {| + string '1; + string '2; + string '3; + string '4; + string '5; + string '6; + json ...; +|}; + +type CustomRecord40 record {| + string '5; + string '6; + json ...; +|}; + +type CustomRecord41 record {| + json ...; +|}; + +type CustomRecord42 record {| + int '1; + string '2; + boolean '3; + decimal '4; + float '5; + () '6; +|}; + +type CustomRecord43 record { + int '1; + string '2; + boolean '3; + decimal '4; + float '5; + () '6; +}; + +type CustomRecord44 record {| + int '1; + string '2; + boolean '3; + decimal '4; + float '5; + () '6; + string ...; +|}; + +type CustomRecord45 record {| + int H1; + string H2; + boolean H3; + decimal H4; + float H5; + () H6; +|}; + +type CustomRecord46 record { + int H1; + string H2; + boolean H3; + decimal H4; + float H5; + () H6; +}; + +type CustomRecord47 record {| + int H1; + string H2; + boolean H3; + decimal H4; + float H5; + () H6; + string ...; +|}; + +type CustomRecord48 record { + string H1; + string H2; + string H3; + string H4; + string H5; + string H6; +}; + +type CustomRecord49 record {| + string H1; + string H2; + string H3; + string H4; + string H5; + string H6; +|}; + +type CustomRecord50 record { + int H1; + float H4; +}; + +type CustomRecord51 record {| + int H1; + float H4; +|}; + +type CustomRecord52 record {| + string H1; + string H4; + string ...; +|}; + +type CustomRecord53 record {| + int H1; + float H4; + decimal ...; +|}; + +type CustomRecord54 record {| + string H1 = ""; + string H4; + string '1; +|}; + +type CustomRecord55 record {| + string H1 = ""; + string H4 = ""; + int '1 = 10; +|}; + +type CustomRecord56 record { + string H1 = ""; + string H4 = ""; + anydata '1 = 10; +}; + +type BooleanTuple1 [boolean, boolean, boolean, boolean]; + +type BooleanTuple2 [boolean, boolean]; + +type BooleanTuple3 [boolean, boolean...]; + +type BooleanTuple4 [boolean...]; + +type NillableBooleanTuple5 [boolean?, boolean?, boolean?, boolean?, boolean?]; + +type NillableBooleanTuple6 [boolean?, boolean?]; + +type NillableBooleanTuple7 [boolean?, boolean?, boolean?...]; + +type NillableBooleanTuple8 [boolean?...]; + +type NillableIntBooleanTuple9 [int|boolean?, int|boolean?...]; + +type NilTuple1 [(), (), ()]; + +type NilTuple2 [(), ()]; + +type NilTuple3 [(), ()...]; + +type NilTuple4 [()...]; + +type IntegerTuple1 [int, int, int, int, int, int]; + +type IntegerTuple2 [int, int]; + +type IntegerTuple3 [int, int...]; + +type IntegerTuple4 [int...]; + +type FloatTuple1 [float, float, float, float, float, float, float]; + +type FloatTuple2 [float, float]; + +type FloatTuple3 [float, float...]; + +type FloatTuple4 [float...]; + +type DecimalTuple1 [decimal, decimal, decimal, decimal]; + +type DecimalTuple2 [decimal, decimal]; + +type DecimalTuple3 [decimal, decimal...]; + +type DecimalTuple4 [decimal...]; + +type StringTuple1 [string, string, string, string]; + +type StringTuple2 [string, string]; + +type StringTuple3 [string, string...]; + +type StringTuple4 [string...]; + +type AnydataTuple1 [anydata, anydata, anydata, anydata, anydata, + anydata, anydata, anydata, anydata, anydata, anydata, anydata, + anydata, anydata, anydata, anydata, anydata, anydata, anydata, + anydata, anydata, anydata, anydata]; + +type AnydataTuple2 [anydata, anydata]; + +type AnydataTuple3 [anydata, anydata...]; + +type AnydataTuple4 [anydata...]; + +type JsonTuple1 [json, json, json, json, json, json, json, json, + json, json, json, json, json, json, json, json, json, json, + json, json, json, json, json]; + +type JsonTuple2 [json, json]; + +type JsonTuple3 [json, json...]; + +type JsonTuple4 [json...]; + +type CustomTuple1 [string, int, decimal, float, (), boolean, anydata, json, string, int, decimal, float, (), boolean, anydata, json]; + +type CustomTuple2 [string, int, decimal, float, (), boolean, anydata, json]; + +type CustomTuple3 [string, int, decimal, float, (), boolean, anydata, json, string...]; + +type CustomTuple4 [string...]; + +type CustomTuple5 [string, int, decimal, float, (), boolean, anydata, json, anydata...]; + +type CustomTuple6 [anydata...]; + +type CustomTuple7 [int, string, boolean, (), float, decimal, json, anydata, string...]; + +type CustomTuple8 [int, string, boolean, (), float, decimal, json, anydata, int...]; + +type IntegerArray1 int[]; + +type IntegerArray2 int[2]; + +type IntegerArray3 int[]; + +type IntegerArray4 int[2]; + +type IntegerArray5 int[3]; + +type IntegerArray6 int[4]; + +type StringArray string[]; + +type NillableStringArray string?[]; + +type NillableIntOrUnionStringArray (int|string?)[]; + +type StringArray1 string[]; + +type StringArray2 string[2]; + +type StringArray3 string[]; + +type StringArray4 string[2]; + +type StringArray5 string[3]; + +type StringArray6 string[4]; + +type FloatArray1 float[]; + +type FloatArray2 float[2]; + +type FloatArray3 float[]; + +type FloatArray4 float[2]; + +type FloatArray5 float[3]; + +type FloatArray6 float[4]; + +type DecimalArray1 decimal[]; + +type DecimalArray2 decimal[2]; + +type DecimalArray3 decimal[]; + +type DecimalArray4 decimal[2]; + +type DecimalArray5 decimal[3]; + +type DecimalArray6 decimal[4]; + +type BooleanArray boolean[]; + +type NillableBooleanArray boolean?[]; + +type NillableIntOrUnionBooleanArray (int|boolean?)[]; + +type BooleanArray2 boolean[2]; + +type BooleanArray3 boolean[3]; + +type BooleanArray4 boolean[]; + +type BooleanArray5 boolean[2]; + +type BooleanArray6 boolean[4]; + +type NilArray1 ()[]; + +type NilArray2 ()[2]; + +type NilArray3 ()[]; + +type NilArray4 ()[2]; + +type NilArray5 ()[3]; + +type NilArray6 ()[4]; + +type JsonArray1 json[]; + +type JsonArray2 json[2]; + +type JsonArray3 json[]; + +type JsonArray4 json[2]; + +type JsonArray5 json[3]; + +type JsonArray6 json[4]; + +type AnydataArray1 anydata[]; + +type AnydataArray2 anydata[2]; + +type AnydataArray3 anydata[]; + +type AnydataArray4 anydata[2]; + +type AnydataArray5 anydata[3]; + +type AnydataArray6 anydata[4]; + +type CustomArray1 CustomTuple2[]; + +type CustomArray2 CustomTuple2[2]; + +type CustomArray3 CustomTuple2[]; + +type CustomArray4 CustomTuple2[2]; + +type CustomArray5 CustomTuple2[3]; + +type CustomArray6 CustomTuple2[4]; + +type IntegerMap map; + +type StringMap map; + +type NillableIntUnionStringMap map; + +type IntUnionStringMap map; + +type DecimalMap map; + +type FloatMap map; + +type BooleanMap map; + +type NillableBooleanMap map; + +type NillableIntUnionBooleanMap map; + +type IntUnionBooleanMap map; + +type NilMap map<()>; + +type JsonMap map; + +type AnydataMap map; + +type CustomMap map; + +type BooleanRecord1Array BooleanRecord1[]; + +type ClosedBooleanRecord1Array BooleanRecord1[3]; + +type BooleanRecord2Array BooleanRecord2[]; + +type ClosedBooleanRecord2Array BooleanRecord2[3]; + +type BooleanRecord3Array BooleanRecord3[]; + +type ClosedBooleanRecord3Array BooleanRecord3[3]; + +type BooleanRecord4Array BooleanRecord4[]; + +type ClosedBooleanRecord4Array BooleanRecord4[3]; + +type BooleanRecord5Array BooleanRecord5[]; + +type ClosedBooleanRecord5Array BooleanRecord5[3]; + +type BooleanRecord6Array BooleanRecord6[]; + +type ClosedBooleanRecord6Array BooleanRecord6[3]; + +type BooleanRecord7Array BooleanRecord7[]; + +type ClosedBooleanRecord7Array BooleanRecord7[3]; + +type BooleanRecord8Array BooleanRecord8[]; + +type ClosedBooleanRecord8Array BooleanRecord8[3]; + +type BooleanRecord9Array BooleanRecord9[]; + +type ClosedBooleanRecord9Array BooleanRecord9[3]; + +type BooleanRecord10Array BooleanRecord10[]; + +type ClosedBooleanRecord10Array BooleanRecord10[3]; + +type BooleanRecord11Array BooleanRecord11[]; + +type ClosedBooleanRecord11Array BooleanRecord11[3]; + +type BooleanRecord12Array BooleanRecord12[]; + +type ClosedBooleanRecord12Array BooleanRecord12[3]; + +type BooleanRecord13Array BooleanRecord13[]; + +type ClosedBooleanRecord13Array BooleanRecord13[3]; + +type BooleanRecord14Array BooleanRecord14[]; + +type ClosedBooleanRecord14Array BooleanRecord14[3]; + +type BooleanRecord15Array BooleanRecord15[]; + +type ClosedBooleanRecord15Array BooleanRecord15[3]; + +type BooleanRecord16Array BooleanRecord16[]; + +type ClosedBooleanRecord16Array BooleanRecord16[3]; + +type BooleanRecord17Array BooleanRecord17[]; + +type ClosedBooleanRecord17Array BooleanRecord17[3]; + +type BooleanRecord18Array BooleanRecord18[]; + +type ClosedBooleanRecord18Array BooleanRecord18[3]; + +type NilRecord1Array NilRecord1[]; + +type ClosedNilRecord1Array NilRecord1[3]; + +type NilRecord2Array NilRecord2[]; + +type ClosedNilRecord2Array NilRecord2[3]; + +type NilRecord3Array NilRecord3[]; + +type ClosedNilRecord3Array NilRecord3[3]; + +type NilRecord4Array NilRecord4[]; + +type ClosedNilRecord4Array NilRecord4[3]; + +type NilRecord5Array NilRecord5[]; + +type ClosedNilRecord5Array NilRecord5[3]; + +type NilRecord6Array NilRecord6[]; + +type ClosedNilRecord6Array NilRecord6[3]; + +type NilRecord7Array NilRecord7[]; + +type ClosedNilRecord7Array NilRecord7[3]; + +type NilRecord8Array NilRecord8[]; + +type ClosedNilRecord8Array NilRecord8[3]; + +type NilRecord9Array NilRecord9[]; + +type ClosedNilRecord9Array NilRecord9[3]; + +type NilRecord10Array NilRecord10[]; + +type ClosedNilRecord10Array NilRecord10[3]; + +type NilRecord11Array NilRecord11[]; + +type ClosedNilRecord11Array NilRecord11[3]; + +type NilRecord12Array NilRecord12[]; + +type ClosedNilRecord12Array NilRecord12[3]; + +type NilRecord13Array NilRecord13[]; + +type ClosedNilRecord13Array NilRecord13[3]; + +type NilRecord14Array NilRecord14[]; + +type ClosedNilRecord14Array NilRecord14[3]; + +type IntegerRecord1Array IntegerRecord1[]; + +type ClosedIntegerRecord1Array IntegerRecord1[3]; + +type IntegerRecord2Array IntegerRecord2[]; + +type ClosedIntegerRecord2Array IntegerRecord2[3]; + +type IntegerRecord3Array IntegerRecord3[]; + +type ClosedIntegerRecord3Array IntegerRecord3[3]; + +type IntegerRecord4Array IntegerRecord4[]; + +type ClosedIntegerRecord4Array IntegerRecord4[3]; + +type IntegerRecord5Array IntegerRecord5[]; + +type ClosedIntegerRecord5Array IntegerRecord5[3]; + +type IntegerRecord6Array IntegerRecord6[]; + +type ClosedIntegerRecord6Array IntegerRecord6[3]; + +type IntegerRecord7Array IntegerRecord7[]; + +type ClosedIntegerRecord7Array IntegerRecord7[3]; + +type IntegerRecord8Array IntegerRecord8[]; + +type ClosedIntegerRecord8Array IntegerRecord8[3]; + +type IntegerRecord9Array IntegerRecord9[]; + +type ClosedIntegerRecord9Array IntegerRecord9[3]; + +type IntegerRecord10Array IntegerRecord10[]; + +type ClosedIntegerRecord10Array IntegerRecord10[3]; + +type IntegerRecord11Array IntegerRecord11[]; + +type ClosedIntegerRecord11Array IntegerRecord11[3]; + +type IntegerRecord12Array IntegerRecord12[]; + +type ClosedIntegerRecord12Array IntegerRecord12[3]; + +type IntegerRecord13Array IntegerRecord13[]; + +type ClosedIntegerRecord13Array IntegerRecord13[3]; + +type IntegerRecord14Array IntegerRecord14[]; + +type ClosedIntegerRecord14Array IntegerRecord14[3]; + +type FloatRecord1Array FloatRecord1[]; + +type ClosedFloatRecord1Array FloatRecord1[3]; + +type FloatRecord2Array FloatRecord2[]; + +type ClosedFloatRecord2Array FloatRecord2[3]; + +type FloatRecord3Array FloatRecord3[]; + +type ClosedFloatRecord3Array FloatRecord3[3]; + +type FloatRecord4Array FloatRecord4[]; + +type ClosedFloatRecord4Array FloatRecord4[3]; + +type FloatRecord5Array FloatRecord5[]; + +type ClosedFloatRecord5Array FloatRecord5[3]; + +type FloatRecord6Array FloatRecord6[]; + +type ClosedFloatRecord6Array FloatRecord6[3]; + +type FloatRecord7Array FloatRecord7[]; + +type ClosedFloatRecord7Array FloatRecord7[3]; + +type FloatRecord8Array FloatRecord8[]; + +type ClosedFloatRecord8Array FloatRecord8[3]; + +type FloatRecord9Array FloatRecord9[]; + +type ClosedFloatRecord9Array FloatRecord9[3]; + +type FloatRecord10Array FloatRecord10[]; + +type ClosedFloatRecord10Array FloatRecord10[3]; + +type FloatRecord11Array FloatRecord11[]; + +type ClosedFloatRecord11Array FloatRecord11[3]; + +type FloatRecord12Array FloatRecord12[]; + +type ClosedFloatRecord12Array FloatRecord12[3]; + +type FloatRecord13Array FloatRecord13[]; + +type ClosedFloatRecord13Array FloatRecord13[3]; + +type FloatRecord14Array FloatRecord14[]; + +type ClosedFloatRecord14Array FloatRecord14[3]; + +type DecimalRecord1Array DecimalRecord1[]; + +type ClosedDecimalRecord1Array DecimalRecord1[3]; + +type DecimalRecord2Array DecimalRecord2[]; + +type ClosedDecimalRecord2Array DecimalRecord2[3]; + +type DecimalRecord3Array DecimalRecord3[]; + +type ClosedDecimalRecord3Array DecimalRecord3[3]; + +type DecimalRecord4Array DecimalRecord4[]; + +type ClosedDecimalRecord4Array DecimalRecord4[3]; + +type DecimalRecord5Array DecimalRecord5[]; + +type ClosedDecimalRecord5Array DecimalRecord5[3]; + +type DecimalRecord6Array DecimalRecord6[]; + +type ClosedDecimalRecord6Array DecimalRecord6[3]; + +type DecimalRecord7Array DecimalRecord7[]; + +type ClosedDecimalRecord7Array DecimalRecord7[3]; + +type DecimalRecord8Array DecimalRecord8[]; + +type ClosedDecimalRecord8Array DecimalRecord8[3]; + +type DecimalRecord9Array DecimalRecord9[]; + +type ClosedDecimalRecord9Array DecimalRecord9[3]; + +type DecimalRecord10Array DecimalRecord10[]; + +type ClosedDecimalRecord10Array DecimalRecord10[3]; + +type DecimalRecord11Array DecimalRecord11[]; + +type ClosedDecimalRecord11Array DecimalRecord11[3]; + +type DecimalRecord12Array DecimalRecord12[]; + +type ClosedDecimalRecord12Array DecimalRecord12[3]; + +type DecimalRecord13Array DecimalRecord13[]; + +type ClosedDecimalRecord13Array DecimalRecord13[3]; + +type DecimalRecord14Array DecimalRecord14[]; + +type ClosedDecimalRecord14Array DecimalRecord14[3]; + +type StringRecord1Array StringRecord1[]; + +type ClosedStringRecord1Array StringRecord1[3]; + +type StringRecord2Array StringRecord2[]; + +type ClosedStringRecord2Array StringRecord2[3]; + +type StringRecord3Array StringRecord3[]; + +type ClosedStringRecord3Array StringRecord3[3]; + +type StringRecord4Array StringRecord4[]; + +type ClosedStringRecord4Array StringRecord4[3]; + +type StringRecord5Array StringRecord5[]; + +type ClosedStringRecord5Array StringRecord5[3]; + +type StringRecord6Array StringRecord6[]; + +type ClosedStringRecord6Array StringRecord6[3]; + +type StringRecord7Array StringRecord7[]; + +type ClosedStringRecord7Array StringRecord7[3]; + +type StringRecord8Array StringRecord8[]; + +type ClosedStringRecord8Array StringRecord8[3]; + +type StringRecord9Array StringRecord9[]; + +type ClosedStringRecord9Array StringRecord9[3]; + +type StringRecord10Array StringRecord10[]; + +type ClosedStringRecord10Array StringRecord10[3]; + +type StringRecord11Array StringRecord11[]; + +type ClosedStringRecord11Array StringRecord11[3]; + +type StringRecord12Array StringRecord12[]; + +type ClosedStringRecord12Array StringRecord12[3]; + +type StringRecord13Array StringRecord13[]; + +type ClosedStringRecord13Array StringRecord13[3]; + +type StringRecord14Array StringRecord14[]; + +type ClosedStringRecord14Array StringRecord14[3]; + +type StringRecord15Array StringRecord15[]; + +type StringRecord16Array StringRecord16[]; + +type StringRecord17Array StringRecord17[]; + +type StringRecord18Array StringRecord18[]; + +type StringRecord19Array StringRecord19[]; + +type StringRecord20Array StringRecord20[]; + +type StringRecord21Array StringRecord21[]; + +type StringRecord22Array StringRecord22[]; + +type StringRecord23Array StringRecord23[]; + +type JsonRecord1Array JsonRecord1[]; + +type ClosedJsonRecord1Array JsonRecord1[3]; + +type JsonRecord2Array JsonRecord2[]; + +type ClosedJsonRecord2Array JsonRecord2[3]; + +type JsonRecord3Array JsonRecord3[]; + +type ClosedJsonRecord3Array JsonRecord3[3]; + +type JsonRecord4Array JsonRecord4[]; + +type ClosedJsonRecord4Array JsonRecord4[3]; + +type JsonRecord5Array JsonRecord5[]; + +type ClosedJsonRecord5Array JsonRecord5[3]; + +type JsonRecord6Array JsonRecord6[]; + +type ClosedJsonRecord6Array JsonRecord6[3]; + +type JsonRecord7Array JsonRecord7[]; + +type ClosedJsonRecord7Array JsonRecord7[3]; + +type JsonRecord8Array JsonRecord8[]; + +type ClosedJsonRecord8Array JsonRecord8[3]; + +type JsonRecord9Array JsonRecord9[]; + +type ClosedJsonRecord9Array JsonRecord9[3]; + +type JsonRecord10Array JsonRecord10[]; + +type ClosedJsonRecord10Array JsonRecord10[3]; + +type JsonRecord11Array JsonRecord11[]; + +type ClosedJsonRecord11Array JsonRecord11[3]; + +type JsonRecord12Array JsonRecord12[]; + +type ClosedJsonRecord12Array JsonRecord12[3]; + +type JsonRecord13Array JsonRecord13[]; + +type ClosedJsonRecord13Array JsonRecord13[3]; + +type JsonRecord14Array JsonRecord14[]; + +type ClosedJsonRecord14Array JsonRecord14[3]; + +type AnydataRecord1Array AnydataRecord1[]; + +type ClosedAnydataRecord1Array AnydataRecord1[3]; + +type AnydataRecord2Array AnydataRecord2[]; + +type ClosedAnydataRecord2Array AnydataRecord2[3]; + +type AnydataRecord3Array AnydataRecord3[]; + +type ClosedAnydataRecord3Array AnydataRecord3[3]; + +type AnydataRecord4Array AnydataRecord4[]; + +type ClosedAnydataRecord4Array AnydataRecord4[3]; + +type AnydataRecord5Array AnydataRecord5[]; + +type ClosedAnydataRecord5Array AnydataRecord5[3]; + +type AnydataRecord6Array AnydataRecord6[]; + +type ClosedAnydataRecord6Array AnydataRecord6[3]; + +type AnydataRecord7Array AnydataRecord7[]; + +type ClosedAnydataRecord7Array AnydataRecord7[3]; + +type AnydataRecord8Array AnydataRecord8[]; + +type ClosedAnydataRecord8Array AnydataRecord8[3]; + +type AnydataRecord9Array AnydataRecord9[]; + +type ClosedAnydataRecord9Array AnydataRecord9[3]; + +type AnydataRecord10Array AnydataRecord10[]; + +type ClosedAnydataRecord10Array AnydataRecord10[3]; + +type AnydataRecord11Array AnydataRecord11[]; + +type ClosedAnydataRecord11Array AnydataRecord11[3]; + +type AnydataRecord12Array AnydataRecord12[]; + +type ClosedAnydataRecord12Array AnydataRecord12[3]; + +type AnydataRecord13Array AnydataRecord13[]; + +type ClosedAnydataRecord13Array AnydataRecord13[3]; + +type AnydataRecord14Array AnydataRecord14[]; + +type ClosedAnydataRecord14Array AnydataRecord14[3]; + +type CustomRecord1Array CustomRecord1[]; + +type ClosedCustomRecord1Array CustomRecord1[3]; + +type CustomRecord2Array CustomRecord2[]; + +type ClosedCustomRecord2Array CustomRecord2[3]; + +type CustomRecord3Array CustomRecord3[]; + +type ClosedCustomRecord3Array CustomRecord3[3]; + +type CustomRecord4Array CustomRecord4[]; + +type ClosedCustomRecord4Array CustomRecord4[3]; + +type CustomRecord5Array CustomRecord5[]; + +type ClosedCustomRecord5Array CustomRecord5[3]; + +type CustomRecord6Array CustomRecord6[]; + +type ClosedCustomRecord6Array CustomRecord6[3]; + +type CustomRecord7Array CustomRecord7[]; + +type ClosedCustomRecord7Array CustomRecord7[3]; + +type CustomRecord8Array CustomRecord8[]; + +type ClosedCustomRecord8Array CustomRecord8[3]; + +type CustomRecord9Array CustomRecord9[]; + +type ClosedCustomRecord9Array CustomRecord9[3]; + +type CustomRecord10Array CustomRecord10[]; + +type ClosedCustomRecord10Array CustomRecord10[3]; + +type CustomRecord11Array CustomRecord11[]; + +type ClosedCustomRecord11Array CustomRecord11[3]; + +type CustomRecord12Array CustomRecord12[]; + +type ClosedCustomRecord12Array CustomRecord12[3]; + +type CustomRecord13Array CustomRecord13[]; + +type ClosedCustomRecord13Array CustomRecord13[3]; + +type CustomRecord14Array CustomRecord14[]; + +type ClosedCustomRecord14Array CustomRecord14[3]; + +type CustomRecord15Array CustomRecord15[]; + +type CustomRecord16Array CustomRecord16[]; + +type CustomRecord17Array CustomRecord17[]; + +type CustomRecord18Array CustomRecord18[]; + +type CustomRecord19Array CustomRecord19[]; + +type CustomRecord20Array CustomRecord20[]; + +type CustomRecord21Array CustomRecord21[]; + +type CustomRecord22Array CustomRecord22[]; + +type CustomRecord23Array CustomRecord23[]; + +type CustomRecord24Array CustomRecord24[]; + +type CustomRecord25Array CustomRecord25[]; + +type CustomRecord26Array CustomRecord26[]; + +type CustomRecord27Array CustomRecord27[]; +type CustomRecord28Array CustomRecord28[]; +type CustomRecord29Array CustomRecord29[]; +type CustomRecord30Array CustomRecord30[]; +type CustomRecord31Array CustomRecord31[]; +type CustomRecord32Array CustomRecord32[]; +type CustomRecord33Array CustomRecord33[]; +type CustomRecord34Array CustomRecord34[]; +type CustomRecord35Array CustomRecord35[]; +type CustomRecord36Array CustomRecord36[]; +type CustomRecord37Array CustomRecord37[]; +type CustomRecord38Array CustomRecord38[]; +type CustomRecord39Array CustomRecord39[]; +type CustomRecord40Array CustomRecord40[]; +type CustomRecord41Array CustomRecord41[]; +type CustomRecord42Array CustomRecord42[]; +type CustomRecord43Array CustomRecord43[]; +type CustomRecord44Array CustomRecord44[]; +type CustomRecord45Array CustomRecord45[]; +type CustomRecord46Array CustomRecord46[]; +type CustomRecord47Array CustomRecord47[]; +type CustomRecord48Array CustomRecord48[]; +type CustomRecord49Array CustomRecord49[]; +type CustomRecord50Array CustomRecord50[]; +type CustomRecord51Array CustomRecord51[]; +type CustomRecord52Array CustomRecord52[]; +type CustomRecord53Array CustomRecord53[]; +type CustomRecord54Array CustomRecord54[]; +type CustomRecord55Array CustomRecord55[]; +type CustomRecord56Array CustomRecord56[]; + +type BooleanTuple1Array BooleanTuple1[]; + +type ClosedBooleanTuple1Array BooleanTuple1[3]; + +type BooleanTuple2Array BooleanTuple2[]; + +type ClosedBooleanTuple2Array BooleanTuple2[3]; + +type BooleanTuple3Array BooleanTuple3[]; + +type ClosedBooleanTuple3Array BooleanTuple3[3]; + +type BooleanTuple4Array BooleanTuple4[]; + +type ClosedBooleanTuple4Array BooleanTuple4[3]; + +type NillableBooleanTuple5Array NillableBooleanTuple5[]; + +type NillableBooleanTuple6Array NillableBooleanTuple6[]; + +type NillableBooleanTuple7Array NillableBooleanTuple7[]; + +type NillableBooleanTuple8Array NillableBooleanTuple8[]; + +type NillableIntBooleanTuple9Array NillableIntBooleanTuple9[]; + +type NilTuple1Array NilTuple1[]; + +type ClosedNilTuple1Array NilTuple1[3]; + +type NilTuple2Array NilTuple2[]; + +type ClosedNilTuple2Array NilTuple2[3]; + +type NilTuple3Array NilTuple3[]; + +type ClosedNilTuple3Array NilTuple3[3]; + +type NilTuple4Array NilTuple4[]; + +type ClosedNilTuple4Array NilTuple4[3]; + +type IntegerTuple1Array IntegerTuple1[]; + +type ClosedIntegerTuple1Array IntegerTuple1[3]; + +type IntegerTuple2Array IntegerTuple2[]; + +type ClosedIntegerTuple2Array IntegerTuple2[3]; + +type IntegerTuple3Array IntegerTuple3[]; + +type ClosedIntegerTuple3Array IntegerTuple3[3]; + +type IntegerTuple4Array IntegerTuple4[]; + +type ClosedIntegerTuple4Array IntegerTuple4[3]; + +type FloatTuple1Array FloatTuple1[]; + +type ClosedFloatTuple1Array FloatTuple1[3]; + +type FloatTuple2Array FloatTuple2[]; + +type ClosedFloatTuple2Array FloatTuple2[3]; + +type FloatTuple3Array FloatTuple3[]; + +type ClosedFloatTuple3Array FloatTuple3[3]; + +type FloatTuple4Array FloatTuple4[]; + +type ClosedFloatTuple4Array FloatTuple4[3]; + +type DecimalTuple1Array DecimalTuple1[]; + +type ClosedDecimalTuple1Array DecimalTuple1[3]; + +type DecimalTuple2Array DecimalTuple2[]; + +type ClosedDecimalTuple2Array DecimalTuple2[3]; + +type DecimalTuple3Array DecimalTuple3[]; + +type ClosedDecimalTuple3Array DecimalTuple3[3]; + +type DecimalTuple4Array DecimalTuple4[]; + +type ClosedDecimalTuple4Array DecimalTuple4[3]; + +type StringTuple1Array StringTuple1[]; + +type ClosedStringTuple1Array StringTuple1[3]; + +type StringTuple2Array StringTuple2[]; + +type ClosedStringTuple2Array StringTuple2[3]; + +type StringTuple3Array StringTuple3[]; + +type ClosedStringTuple3Array StringTuple3[3]; + +type StringTuple4Array StringTuple4[]; + +type ClosedStringTuple4Array StringTuple4[3]; + +type AnydataTuple1Array AnydataTuple1[]; + +type ClosedAnydataTuple1Array AnydataTuple1[3]; + +type AnydataTuple2Array AnydataTuple2[]; + +type ClosedAnydataTuple2Array AnydataTuple2[3]; + +type AnydataTuple3Array AnydataTuple3[]; + +type ClosedAnydataTuple3Array AnydataTuple3[3]; + +type AnydataTuple4Array AnydataTuple4[]; + +type ClosedAnydataTuple4Array AnydataTuple4[3]; + +type JsonTuple1Array JsonTuple1[]; + +type ClosedJsonTuple1Array JsonTuple1[3]; + +type JsonTuple2Array JsonTuple2[]; + +type ClosedJsonTuple2Array JsonTuple2[3]; + +type JsonTuple3Array JsonTuple3[]; + +type ClosedJsonTuple3Array JsonTuple3[3]; + +type JsonTuple4Array JsonTuple4[]; + +type ClosedJsonTuple4Array JsonTuple4[3]; + +type CustomTuple1Array CustomTuple1[]; + +type ClosedCustomTuple1Array CustomTuple1[3]; + +type CustomTuple2Array CustomTuple2[]; + +type ClosedCustomTuple2Array CustomTuple2[3]; + +type CustomTuple3Array CustomTuple3[]; + +type ClosedCustomTuple3Array CustomTuple3[3]; + +type CustomTuple4Array CustomTuple4[]; + +type ClosedCustomTuple4Array CustomTuple4[3]; + +type CustomTuple5Array CustomTuple5[]; + +type ClosedCustomTuple5Array CustomTuple5[3]; + +type CustomTuple6Array CustomTuple6[]; + +type CustomTuple7Array CustomTuple7[]; + +type CustomTuple8Array CustomTuple8[]; + +type ClosedCustomTuple6Array CustomTuple6[3]; + +type IntegerArray1Array IntegerArray1[]; + +type ClosedIntegerArray1Array IntegerArray1[3]; + +type IntegerArray2Array IntegerArray2[]; + +type ClosedIntegerArray2Array IntegerArray2[3]; + +type IntegerArray3Array IntegerArray3[]; + +type ClosedIntegerArray3Array IntegerArray3[3]; + +type IntegerArray4Array IntegerArray4[]; + +type ClosedIntegerArray4Array IntegerArray4[3]; + +type IntegerArray5Array IntegerArray5[]; + +type ClosedIntegerArray5Array IntegerArray5[3]; + +type IntegerArray6Array IntegerArray5[]; + +type ClosedIntegerArray6Array IntegerArray5[3]; + +type StringArray1Array StringArray1[]; + +type StringArrayArray StringArray[]; + +type NillableStringArrayArray NillableStringArray[]; + +type NillableIntOrUnionStringArrayArray NillableIntOrUnionStringArray[]; + +type ClosedStringArray1Array StringArray1[3]; + +type StringArray2Array StringArray2[]; + +type ClosedStringArray2Array StringArray2[3]; + +type StringArray3Array StringArray3[]; + +type ClosedStringArray3Array StringArray3[3]; + +type StringArray4Array StringArray4[]; + +type ClosedStringArray4Array StringArray4[3]; + +type StringArray5Array StringArray5[]; + +type ClosedStringArray5Array StringArray5[3]; + +type StringArray6Array StringArray5[]; + +type ClosedStringArray6Array StringArray5[3]; + +type FloatArray1Array FloatArray1[]; + +type ClosedFloatArray1Array FloatArray1[3]; + +type FloatArray2Array FloatArray2[]; + +type ClosedFloatArray2Array FloatArray2[3]; + +type FloatArray3Array FloatArray3[]; + +type ClosedFloatArray3Array FloatArray3[3]; + +type FloatArray4Array FloatArray4[]; + +type ClosedFloatArray4Array FloatArray4[3]; + +type FloatArray5Array FloatArray5[]; + +type ClosedFloatArray5Array FloatArray5[3]; + +type FloatArray6Array FloatArray5[]; + +type ClosedFloatArray6Array FloatArray5[3]; + +type DecimalArray1Array DecimalArray1[]; + +type ClosedDecimalArray1Array DecimalArray1[3]; + +type DecimalArray2Array DecimalArray2[]; + +type ClosedDecimalArray2Array DecimalArray2[3]; + +type DecimalArray3Array DecimalArray3[]; + +type ClosedDecimalArray3Array DecimalArray3[3]; + +type DecimalArray4Array DecimalArray4[]; + +type ClosedDecimalArray4Array DecimalArray4[3]; + +type DecimalArray5Array DecimalArray5[]; + +type ClosedDecimalArray5Array DecimalArray5[3]; + +type DecimalArray6Array DecimalArray5[]; + +type ClosedDecimalArray6Array DecimalArray5[3]; + +type BooleanArrayArray BooleanArray[]; + +type ClosedBooleanArrayArray BooleanArray[3]; + +type NillableBooleanArrayArray NillableBooleanArray[]; + +type NillableIntOrUnionBooleanArrayArray NillableIntOrUnionBooleanArray[]; + +type BooleanArray2Array BooleanArray2[]; + +type ClosedBooleanArray2Array BooleanArray2[3]; + +type BooleanArray3Array BooleanArray3[]; + +type ClosedBooleanArray3Array BooleanArray3[3]; + +type BooleanArray4Array BooleanArray4[]; + +type ClosedBooleanArray4Array BooleanArray4[3]; + +type BooleanArray5Array BooleanArray5[]; + +type ClosedBooleanArray5Array BooleanArray5[3]; + +type BooleanArray6Array BooleanArray5[]; + +type ClosedBooleanArray6Array BooleanArray5[3]; + +type NilArray1Array NilArray1[]; + +type ClosedNilArray1Array NilArray1[3]; + +type NilArray2Array NilArray2[]; + +type ClosedNilArray2Array NilArray2[3]; + +type NilArray3Array NilArray3[]; + +type ClosedNilArray3Array NilArray3[3]; + +type NilArray4Array NilArray4[]; + +type ClosedNilArray4Array NilArray4[3]; + +type NilArray5Array NilArray5[]; + +type ClosedNilArray5Array NilArray5[3]; + +type NilArray6Array NilArray5[]; + +type ClosedNilArray6Array NilArray5[3]; + +type JsonArray1Array JsonArray1[]; + +type ClosedJsonArray1Array JsonArray1[3]; + +type JsonArray2Array JsonArray2[]; + +type ClosedJsonArray2Array JsonArray2[3]; + +type JsonArray3Array JsonArray3[]; + +type ClosedJsonArray3Array JsonArray3[3]; + +type JsonArray4Array JsonArray4[]; + +type ClosedJsonArray4Array JsonArray4[3]; + +type JsonArray5Array JsonArray5[]; + +type ClosedJsonArray5Array JsonArray5[3]; + +type JsonArray6Array JsonArray5[]; + +type ClosedJsonArray6Array JsonArray5[3]; + +type AnydataArray1Array AnydataArray1[]; + +type ClosedAnydataArray1Array AnydataArray1[3]; + +type AnydataArray2Array AnydataArray2[]; + +type ClosedAnydataArray2Array AnydataArray2[3]; + +type AnydataArray3Array AnydataArray3[]; + +type ClosedAnydataArray3Array AnydataArray3[3]; + +type AnydataArray4Array AnydataArray4[]; + +type ClosedAnydataArray4Array AnydataArray4[3]; + +type AnydataArray5Array AnydataArray5[]; + +type ClosedAnydataArray5Array AnydataArray5[3]; + +type AnydataArray6Array AnydataArray5[]; + +type ClosedAnydataArray6Array AnydataArray5[3]; + +type CustomArray1Array CustomArray1[]; + +type ClosedCustomArray1Array CustomArray1[3]; + +type CustomArray2Array CustomArray2[]; + +type ClosedCustomArray2Array CustomArray2[3]; + +type CustomArray3Array CustomArray3[]; + +type ClosedCustomArray3Array CustomArray3[3]; + +type CustomArray4Array CustomArray4[]; + +type ClosedCustomArray4Array CustomArray4[3]; + +type CustomArray5Array CustomArray5[]; + +type ClosedCustomArray5Array CustomArray5[3]; + +type CustomArray6Array CustomArray5[]; + +type ClosedCustomArray6Array CustomArray5[3]; + +type IntegerMapArray IntegerMap[]; + +type ClosedIntegerMapArray IntegerMap[3]; + +type StringMapArray StringMap[]; + +type NillableIntUnionStringMapArray NillableIntUnionStringMap[]; + +type IntUnionStringMapArray IntUnionStringMap[]; + +type ClosedStringMapArray StringMap[3]; + +type DecimalMapArray DecimalMap[]; + +type ClosedDecimalMapArray DecimalMap[3]; + +type FloatMapArray FloatMap[]; + +type ClosedFloatMapArray FloatMap[3]; + +type BooleanMapArray BooleanMap[]; + +type NillableBooleanMapArray NillableBooleanMap[]; + +type NillableIntUnionBooleanMapArray NillableIntUnionBooleanMap[]; + +type IntUnionBooleanMapArray IntUnionBooleanMap[]; + +type ClosedBooleanMapArray BooleanMap[3]; + +type NilMapArray NilMap[]; + +type ClosedNilMapArray NilMap[3]; + +type JsonMapArray JsonMap[]; + +type ClosedJsonMapArray JsonMap[3]; + +type AnydataMapArray AnydataMap[]; + +type ClosedAnydataMapArray AnydataMap[3]; + +type CustomMapArray CustomMap[]; + +type ClosedCustomMapArray CustomMap[3]; diff --git a/ballerina-tests/user-config-tests/.gitignore b/ballerina-tests/user-config-tests/.gitignore new file mode 100644 index 0000000..d5fc29a --- /dev/null +++ b/ballerina-tests/user-config-tests/.gitignore @@ -0,0 +1,11 @@ +# Ballerina generates this directory during the compilation of a package. +# It contains compiler-generated artifacts and the final executable if this is an application package. +target/ + +# Ballerina maintains the compiler-generated source code here. +# Remove this if you want to commit generated sources. +generated/ + +# Contains configuration values used during development time. +# See https://ballerina.io/learn/provide-values-to-configurable-variables/ for more details. +Config.toml diff --git a/ballerina-tests/user-config-tests/Ballerina.toml b/ballerina-tests/user-config-tests/Ballerina.toml new file mode 100644 index 0000000..05c5773 --- /dev/null +++ b/ballerina-tests/user-config-tests/Ballerina.toml @@ -0,0 +1,13 @@ +[package] +org = "ballerina" +name = "user_config_tests" +version = "0.1.0" + +[[dependency]] +org = "ballerina" +name = "csv_commons" +repository = "local" +version = "0.1.0" + +[platform.java17] +graalvmCompatible = true diff --git a/ballerina-tests/user-config-tests/Dependencies.toml b/ballerina-tests/user-config-tests/Dependencies.toml new file mode 100644 index 0000000..beb3621 --- /dev/null +++ b/ballerina-tests/user-config-tests/Dependencies.toml @@ -0,0 +1,98 @@ +# AUTO-GENERATED FILE. DO NOT MODIFY. + +# This file is auto-generated by Ballerina for managing dependency versions. +# It should not be modified by hand. + +[ballerina] +dependencies-toml-version = "2" +distribution-version = "2201.9.0" + +[[package]] +org = "ballerina" +name = "csv_commons" +version = "0.1.0" +scope = "testOnly" +modules = [ + {org = "ballerina", packageName = "csv_commons", moduleName = "csv_commons"} +] + +[[package]] +org = "ballerina" +name = "data.csv" +version = "0.1.0" +scope = "testOnly" +dependencies = [ + {org = "ballerina", name = "jballerina.java"} +] +modules = [ + {org = "ballerina", packageName = "data.csv", moduleName = "data.csv"} +] + +[[package]] +org = "ballerina" +name = "jballerina.java" +version = "0.0.0" +scope = "testOnly" + +[[package]] +org = "ballerina" +name = "lang.__internal" +version = "0.0.0" +scope = "testOnly" +dependencies = [ + {org = "ballerina", name = "jballerina.java"}, + {org = "ballerina", name = "lang.object"} +] + +[[package]] +org = "ballerina" +name = "lang.array" +version = "0.0.0" +scope = "testOnly" +dependencies = [ + {org = "ballerina", name = "jballerina.java"}, + {org = "ballerina", name = "lang.__internal"} +] + +[[package]] +org = "ballerina" +name = "lang.error" +version = "0.0.0" +scope = "testOnly" +dependencies = [ + {org = "ballerina", name = "jballerina.java"} +] + +[[package]] +org = "ballerina" +name = "lang.object" +version = "0.0.0" +scope = "testOnly" + +[[package]] +org = "ballerina" +name = "test" +version = "0.0.0" +scope = "testOnly" +dependencies = [ + {org = "ballerina", name = "jballerina.java"}, + {org = "ballerina", name = "lang.array"}, + {org = "ballerina", name = "lang.error"} +] +modules = [ + {org = "ballerina", packageName = "test", moduleName = "test"} +] + +[[package]] +org = "ballerina" +name = "user_config_tests" +version = "0.1.0" +dependencies = [ + {org = "ballerina", name = "csv_commons"}, + {org = "ballerina", name = "data.csv"}, + {org = "ballerina", name = "test"} +] +modules = [ + {org = "ballerina", packageName = "user_config_tests", moduleName = "user_config_tests"} +] + diff --git a/ballerina-tests/user-config-tests/tests/test_data_values.bal b/ballerina-tests/user-config-tests/tests/test_data_values.bal new file mode 100644 index 0000000..360a493 --- /dev/null +++ b/ballerina-tests/user-config-tests/tests/test_data_values.bal @@ -0,0 +1,256 @@ +boolean b1 = true; +false b2 = false; +boolean? b3 = (); +boolean|int b4 = false; + +() n1 = (); +int? n2 = (); +() n3 = null; + +int i1 = 1; +int i2 = -2; +int i3 = int:MAX_VALUE; +int i4 = int:MIN_VALUE; +int i5 = 0; +2 i6 = 2; +int? i7 = (); +int|string i8 = 100; + +float f1 = 2.234; +float f2 = -3.21f; +float f3 = 0; +float f4 = float:Infinity; +float f5 = -float:Infinity; +float f6 = float:NaN; +2.3f f7 = 2.3; +float? f8 = (); +float|decimal f9 = 1.21; + +decimal d1 = 2.234; +decimal d2 = -3.21d; +decimal d3 = 0; +2.3d d4 = 2.3; +decimal? d5 = (); +decimal|int d6 = 1.21; + +string s1 = "string"; +string s2 = ""; +string:Char s3 = "a"; + +map bm1 = {b1, b2}; +map bm2 = {b1, b2, b3, n1, n3}; +map bm3 = {b1, b2, b3, b4, i1}; +map<()> bm4 = {n1, n3}; +map bm5 = {b1, b2, b3, b4:true}; + +map m5 = {i1, i2, i3, i4, i5, i6}; +map m6 = {f1, f2, f3, f4, f5, f6, f7}; +map m7 = {d1, d2, d3, d4}; +map m8 = {d1, f1, f9, f10: 1.23}; +map m9 = {s1, s2, s3}; +map m10 = {b1, b2, b3, b4, n1, n2, n3, i1, i2, i3, i4, i5, i6, i7, i8, f1, f2, f3, f4, f5, f6, f7, f8}; +map m11 = {b1, b2, b3, b4, n1, n2, n3, i1, i2, i3, i4, i5, i6, i7, i8, f1, f2, f3, f4, f5, f6, f7, f8}; + +boolean[] arr1 = [b1, b2]; +boolean?[] arr2 = [b1, b2, b3, n1, n3]; +(boolean|int?)[] arr3 = [b1, b2, b3, b4, i1]; +()[] arr4 = [n1, n3]; +int[] arr5 = [i1, i2, i3, i4, i5, i6]; +float[] arr6 = [f1, f2, f3, f4, f5, f6, f7]; +decimal[] arr7 = [d1, d2, d3, d4]; +(decimal|float)[] arr8 = [d1, f1, f9, 1.23]; +string[] arr9 = [s1, s2, s3]; +anydata[] arr10 = [b1, b2, b3, b4, n1, n2, n3, i1, i2, i3, i4, i5, i6, i7, i8, f1, f2, f3, f4, f5, f6, f7, f8]; +json[] arr11 = [b1, b2, b3, b4, n1, n2, n3, i1, i2, i3, i4, i5, i6, i7, i8, f1, f2, f3, f4, f5, f6, f7, f8]; + +[boolean, boolean] bt1 = [b1, b2]; +[boolean, boolean, boolean, boolean] bt2 = [b1, b2, b1, b2]; +[boolean?, boolean?, boolean?, boolean?, boolean?] bt3 = [b1, b2, b3, n1, n3]; +[boolean|int?, boolean|int?, boolean|int?, boolean|int?, boolean|int?] bt4 = [b1, b2, b3, b4, i1]; +[boolean...] bt5 = [b1, b2]; + +[string, string] st1 = [s1, s2]; +[string, string, string, string] st2 = [s1, s2, s3, s2]; +[string...] st3 = [s1, s2]; +[string, string, string...] st4 = [s1, s2, s3, s2]; + +[string?, string?, string?, string?, string?] st5 = [s1, s2, s3, n1, n3]; +[string|int?, string|int?, string|int?, string|int?, string|int?] st6 = [s1, s2, s3, n1, i1]; +[string?...] st7 = [s1, s2]; +[string...] st8 = []; +[string, string, string] st9 = [s1, s2, s3]; + +[(), ()] tup4 = [n1, n3]; +[int, int, int, int, int, int] tup5 = [i1, i2, i3, i4, i5, i6]; +[float, float, float, float, float, float, float] tup6 = [f1, f2, f3, f4, f5, f6, f7]; +[decimal, decimal, decimal, decimal] tup7 = [d1, d2, d3, d4]; +[decimal|float, decimal|float, decimal|float, decimal|float] tup8 = [d1, f1, f9, 1.23]; +[string, string, string] tup9 = [s1, s2, s3]; +[anydata, anydata, anydata, anydata, anydata, anydata, anydata, anydata, + anydata, anydata, anydata, anydata, anydata, anydata, anydata, anydata, + anydata, anydata, anydata, anydata, anydata, anydata, anydata] tup10 = [b1, b2, b3, b4, + n1, n2, n3, i1, i2, i3, i4, i5, i6, i7, i8, f1, f2, f3, f4, f5, f6, f7, f8]; +[json, json, json, json, json, json, json, json, json, json, json, json, + json, json, json, json, json, json, json, json, json, json, json] tup11 = + [b1, b2, b3, b4, n1, n2, n3, i1, i2, i3, i4, i5, i6, i7, i8, f1, + f2, f3, f4, f5, f6, f7, f8]; +[string, string, int, int, boolean, boolean, (), (), decimal, decimal, float, float] tup12 = [ + s1, s2, i1, i2, b1, b2, n1, n3, d1, d2, f1, f2 +]; + +[boolean, boolean...] restTup1 = [b1, b2]; +[boolean?, boolean?, boolean?...] restTup2 = [b1, b2, b3, n1, n3]; +[boolean|int?...] restTup3 = [b1, b2, b3, b4, i1]; +[(), ()...] restTup4 = [n1, n3]; +[int...] restTup5 = [i1, i2, i3, i4, i5, i6]; +[float...] restTup6 = [f1, f2, f3, f4, f5, f6, f7]; +[decimal...] restTup7 = [d1, d2, d3, d4]; +[decimal|float, decimal|float...] restTup8 = [d1, f1, f9, 1.23]; +[string...] restTup9 = [s1, s2, s3]; +[anydata...] restTup10 = [b1, b2, b3, b4, n1, n2, n3, i1, i2, i3, i4, i5, i6, i7, i8, f1, f2, f3, f4, f5, f6, f7, f8]; +[json, json, json...] restTup11 = [b1, b2, b3, b4, n1, n2, n3, i1, i2, i3, i4, i5, i6, i7, i8, f1, f2, f3, f4, f5, f6, f7, f8]; +[string, string, int, int, boolean, boolean, (), (), decimal, decimal, float, float...] restTup12 = [ + s1, s2, i1, i2, b1, b2, n1, n3, d1, d2, f1, f2, f2, f2 +]; + +var booleanRecordArray = [ + {b1, b2, b3, b4}, {b1, b2, b3, b4} +]; + +var booleanRecordArray2 = [ + {},{} +]; + +string csvStringWithBooleanValues1 = string `b1,b2,b3,b4 +true,false,true,false +true,false, true,false +true,false,true,false +`; + +string csvStringWithBooleanValues2 = string `b1,b2,b3,b4,b5 +true,false, true,false,true +true,false, true,false,true`; + +string csvStringWithBooleanValues3 = string `b1,b2,b3 +${" "}${"\t"} +true, false,true +${" "} + TRUE, FALSE,() +${" "} + +true, true,FALSE + +`; + +string csvStringWithBooleanValues4 = string `b1,b2,b3,b4 + true,(), (),false + true,(), null,false + +`; + +string csvStringWithBooleanValues5 = string `b1,b2,b3,b4 + +true,false,true,2 + +true,false,true,3 +`; + +string csvStringWithBooleanValues6 = string `b2,b3 +(),() + +`; + +string csvStringWithBooleanValues7 = string `b1,b2,b3,b4 +${b1},${b2},(),${b4} +`; + +string csvStringData1 = string ` + a, b, c, d, e, f + 1, string1, true, 2.234, 2.234, () + 2, string2, false, 0, 0, null + 3, string3, false, 1.23, 1.23, () + 4, string4, true, -6.51, -6.51, () + 5, string5, true, 3, 3, ()`; + +string csvStringData2 = string ` + hello, hello, (), 12, true, 12.34 + // comment + + a, b, c, d, e, f + + + 1, string1, true, 2.234, 2.234, () + 2, string2, false, 0, 0, null + 3, string3, false, 1.23, 1.23, () + 4, string4, true, -6.51, -6.51, () + 5, string5, true, 3, 3, ()`; + +string csvStringData3 = string ` + a, b, c, d, e, f + + + + 1, string1, true, 2.234, 2.234, () + 2, string2, false, 0, 0, null + 3, string3, false, 1.23, 1.23, () + + 4, string4, true, -6.51, -6.51, () + 5, string5, true, 3, 3, ()`; + +string csvStringData4 = string ` + 1, string1, true, 2.234, 2.234, () + 2, string2, false, 0, 0, null + 3, string3, false, 1.23, 1.23, () + 4, string4, true, -6.51, -6.51, () + 5, string5, true, 3, 3, ()`; + +string csvStringData5 = string ` + + + + 1, string1, true, 2.234, 2.234, () + 2, string2, false, 0, 0, null + + 3, string3, false, 1.23, 1.23, () + 4, string4, true, -6.51, -6.51, () + + 5, string5, true, 3, 3, ()`; + +string csvStringData6 = string ` + + 1, string1, true, 2.234, 2.234, () + 2, string2, false, 0, 0, null + + 3, string3, false, 1.23, 1.23, () + 4, string4, true, -6.51, -6.51, () + + 5, string5, true, 3, 3, ()`; + +string csvStringData7 = string ` + a@ b@ c@ d@ e@ f + 1@ string@ true@ 2.234@ -3.21@ () + 2@ s,tring@ true@ 2.234@ -3.21@ null + 3@ stri,ng@ true@ 2.234@ -3.21@ () + 4@ string@ true@ 2.234@ -3.21@ () + 5@ string@ true@ 2.234@ -3.21@ ()`; +string csvStringData8 = string ` + a@ b@ c@ d@ e@ f + + + + 1@ stri,ng@ true@ 2.234@ -3.21@ () + 2@ string@ true@ 2.234@ ()@-3.21 + 3@ string@ true@ 2.234@ -3.21@ null + + 4@ s,tring@ true@ 2.234@ -3.21@ () + 5@ string@ true@ 2.234@ -3.21@ ()`; + +string csvStringData9 = string ` + + 1@ string@ true@ 2.234@ -3.21@ () + 2@ string@ true@ 2.234@ -3.21@ null + + 3@ string@ true@ 2.234@ -3.21@ () + 4@ string@ true@ 2.234@ ()@-3.21 + + 5@ string@ true@ 2.234@ -3.21@ null`; diff --git a/ballerina-tests/user-config-tests/tests/types.bal b/ballerina-tests/user-config-tests/tests/types.bal new file mode 100644 index 0000000..7587492 --- /dev/null +++ b/ballerina-tests/user-config-tests/tests/types.bal @@ -0,0 +1,73 @@ +import ballerina/data.csv as csv; + +type RecordWithCustomAnnotation record { + @csv:Name { + value: "c" + } + int a; + int b; +}; + +type RecordWithCustomAnnotation2 record { + @csv:Name { + value: "c" + } + int a?; + @csv:Name { + value: "d" + } + int? b; +}; + +type RecordWithCustomAnnotation3 record {| + @csv:Name { + value: "c" + } + int a?; + @csv:Name { + value: "d" + } + int? b; +|}; + +type RecordWithCustomAnnotation4 record {| + @csv:Name { + value: "c" + } + int a; + @csv:Name { + value: "d" + } + int b; + boolean...; +|}; + +type RecordWithCustomAnnotation5 record { + @csv:Name { + value: "c" + } + int a; + @csv:Name { + value: "d" + } + int b; + @csv:Name { + value: "e" + } + int c; +}; + +type RecordWithCustomAnnotation6 record { + @csv:Name { + value: "c" + } + int a; + @csv:Name { + value: "d" + } + int b; + @csv:Name { + value: "a" + } + int c; +}; diff --git a/ballerina-tests/user-config-tests/tests/user_config_projection_tests.bal b/ballerina-tests/user-config-tests/tests/user_config_projection_tests.bal new file mode 100644 index 0000000..331ca64 --- /dev/null +++ b/ballerina-tests/user-config-tests/tests/user_config_projection_tests.bal @@ -0,0 +1,659 @@ +import ballerina/csv_commons as common; +import ballerina/data.csv as csv; +import ballerina/test; + +@test:Config +function testCustomNameAnnotation() returns error? { + RecordWithCustomAnnotation[]|csv:Error cn1 = csv:parseStringToRecord(string `b,c + 1,3`, {}); + test:assertEquals(cn1, [{b: 1, a: 3}]); + + RecordWithCustomAnnotation[]|csv:Error cn2 = csv:parseStringToRecord(string `c,b + 3,1`, {}); + test:assertEquals(cn2, [{b: 1, a: 3}]); + + RecordWithCustomAnnotation[]|csv:Error cn3 = csv:parseStringToRecord(string `f,c,b,e + 3,3,1,"cde" + 3,3,1,"cde"`, {}); + test:assertEquals(cn3, [{b: 1, a: 3, f: 3, e: "cde"}, {b: 1, a: 3, f: 3, e: "cde"}]); + + RecordWithCustomAnnotation2[]|csv:Error cn4 = csv:parseStringToRecord(string `d,c + 1,3`, {}); + test:assertEquals(cn4, [{b: 1, a: 3}]); + + RecordWithCustomAnnotation2[]|csv:Error cn5 = csv:parseStringToRecord(string `c,d + 3,1`, {}); + test:assertEquals(cn5, [{b: 1, a: 3}]); + + RecordWithCustomAnnotation2[]|csv:Error cn6 = csv:parseStringToRecord(string `c,f,d,e + 3,3,1,"cde" + 3,3,1,"cde"`, {}); + test:assertEquals(cn6, [{b: 1, a: 3, f: 3, e: "cde"}, {b: 1, a: 3, f: 3, e: "cde"}]); + + RecordWithCustomAnnotation2[]|csv:Error cn7 = csv:parseStringToRecord(string `a,b + 3,1`, {}); + test:assertTrue(cn7 is csv:Error); + test:assertEquals((cn7).message(), "Duplicate field found in record fields: 'a'"); + + RecordWithCustomAnnotation2[]|csv:Error cn8 = csv:parseStringToRecord(string ` c,d,a,b + 3,1,4,5`, {}); + test:assertTrue(cn8 is csv:Error); + test:assertEquals((cn8).message(), "Duplicate field found in record fields: 'a'"); + + RecordWithCustomAnnotation3[]|csv:Error cn9 = csv:parseStringToRecord(string `d,c + 1,3`, {}); + test:assertEquals(cn9, [{b: 1, a: 3}]); + + RecordWithCustomAnnotation3[]|csv:Error cn10 = csv:parseStringToRecord(string `c,d + 3,1`, {}); + test:assertEquals(cn10, [{b: 1, a: 3}]); + + RecordWithCustomAnnotation3[]|csv:Error cn11 = csv:parseStringToRecord(string `c,f,d,e + 3,3,1,"cde" + 3,3,1,"cde"`, {}); + test:assertEquals(cn11, [{b: 1, a: 3}, {b: 1, a: 3}]); + + RecordWithCustomAnnotation3[]|csv:Error cn12 = csv:parseStringToRecord(string `a,b + 3,1`, {}); + test:assertTrue(cn12 is csv:Error); + test:assertEquals((cn12).message(), "Duplicate field found in record fields: 'a'"); + + RecordWithCustomAnnotation3[]|csv:Error cn13 = csv:parseStringToRecord(string ` c,d,a,b + 3,1,4,5`, {}); + test:assertTrue(cn13 is csv:Error); + test:assertEquals((cn13).message(), "Duplicate field found in record fields: 'a'"); + + RecordWithCustomAnnotation4[]|csv:Error cn14 = csv:parseStringToRecord(string `d,c,z + 1,3,true`, {}); + test:assertEquals(cn14, [{b: 1, a: 3, z: true}]); + + RecordWithCustomAnnotation4[]|csv:Error cn15 = csv:parseStringToRecord(string `c,d + 3,1`, {}); + test:assertEquals(cn15, [{b: 1, a: 3}]); + + RecordWithCustomAnnotation4[]|csv:Error cn16 = csv:parseStringToRecord(string `c,f,d,e + 3,3,1,"cde" + 3,3,1,"cde"`, {}); + test:assertEquals(cn16, [{b: 1, a: 3}, {b: 1, a: 3}]); + + RecordWithCustomAnnotation4[]|csv:Error cn17 = csv:parseStringToRecord(string `a,b + 3,1`, {}); + test:assertTrue(cn17 is csv:Error); + test:assertEquals((cn17).message(), "Duplicate field found in record fields: 'a'"); + + RecordWithCustomAnnotation4[]|csv:Error cn18 = csv:parseStringToRecord(string ` c,d,a,b + 3,1,4,5`, {}); + test:assertTrue(cn18 is csv:Error); + test:assertEquals((cn18).message(), "Duplicate field found in record fields: 'a'"); + + RecordWithCustomAnnotation5[]|csv:Error cn19 = csv:parseStringToRecord(string ` c,d,a,b + 3,1,4,5`, {}); + test:assertTrue(cn19 is csv:Error); + test:assertEquals((cn19).message(), "Duplicate field found in record fields: 'a'"); + + RecordWithCustomAnnotation5[]|csv:Error cn20 = csv:parseStringToRecord(string ` c,d,e + 3,1,4 + 3,1,4`, {}); + test:assertEquals(cn20, [{a: 3, b: 1, c: 4}, {a: 3, b: 1, c: 4}]); + + RecordWithCustomAnnotation6[]|csv:Error cn21 = csv:parseStringToRecord(string ` c,d,a + 3,1,4 + 3,1,4`, {}); + test:assertEquals(cn21, [{a: 3, b: 1, c: 4}, {a: 3, b: 1, c: 4}]); + + RecordWithCustomAnnotation[]|csv:Error cnrr1 = csv:parseRecordAsRecordType([{"b": 1, "c": 3}], {}); + test:assertEquals(cnrr1, [{b: 1, a: 3}]); + + RecordWithCustomAnnotation[]|csv:Error cnrr2 = csv:parseRecordAsRecordType([{"c": 3, "b": 1}], {}); + test:assertEquals(cnrr2, [{b: 1, a: 3}]); + + RecordWithCustomAnnotation[]|csv:Error cnrr3 = csv:parseRecordAsRecordType( + [{"f": 3, "c": 3, "b": 1, "e": "cde"}, {"f": 3, "c": 3, "b": 1, "e": "cde"}], {}); + test:assertEquals(cnrr3, [{b: 1, a: 3, f: 3, e: "cde"}, {b: 1, a: 3, f: 3, e: "cde"}]); + + RecordWithCustomAnnotation2[]|csv:Error cnrr4 = csv:parseRecordAsRecordType([{"d": 1, "c": 3}], {}); + test:assertEquals(cnrr4, [{b: 1, a: 3}]); + + RecordWithCustomAnnotation2[]|csv:Error cnrr5 = csv:parseRecordAsRecordType([{"c": 3, "d": 1}], {}); + test:assertEquals(cnrr5, [{b: 1, a: 3}]); + + RecordWithCustomAnnotation2[]|csv:Error cnrr6 = csv:parseRecordAsRecordType( + [{"c": 3, "f": 3, "d": 1, "e": "cde"}, {"c": 3, "f": 3, "d": 1, "e": "cde"}], {}); + test:assertEquals(cnrr6, [{b: 1, a: 3, f: 3, e: "cde"}, {b: 1, a: 3, f: 3, e: "cde"}]); + + RecordWithCustomAnnotation2[]|csv:Error cnrr7 = csv:parseRecordAsRecordType([{"a":3, "b": 1}], {}); + test:assertTrue(cnrr7 is csv:Error); + test:assertEquals((cnrr7).message(), "Duplicate field found in record fields: 'a'"); + + RecordWithCustomAnnotation2[]|csv:Error cnrr8 = csv:parseRecordAsRecordType([{"c": 3, "d": 1, "a": 4, "b": 5}], {}); + test:assertTrue(cnrr8 is csv:Error); + test:assertEquals((cnrr8).message(), "Duplicate field found in record fields: 'a'"); + + RecordWithCustomAnnotation3[]|csv:Error cnrr9 = csv:parseRecordAsRecordType([{"d": 1, "c": 3}], {}); + test:assertEquals(cnrr9, [{b: 1, a: 3}]); + + RecordWithCustomAnnotation3[]|csv:Error cnrr10 = csv:parseRecordAsRecordType([{"c": 3, "d": 1}], {}); + test:assertEquals(cnrr10, [{b: 1, a: 3}]); + + RecordWithCustomAnnotation3[]|csv:Error cnrr11 = csv:parseRecordAsRecordType( + [{"c": 3, "f": 3, "d": 1, "e": "cde"}, {"c": 3, "f": 3, "d": 1, "e": "cde"}], {}); + test:assertEquals(cnrr11, [{b: 1, a: 3}, {b: 1, a: 3}]); + + RecordWithCustomAnnotation3[]|csv:Error cnrr12 = csv:parseRecordAsRecordType([{"a": 3, "b": 1}], {}); + test:assertTrue(cnrr12 is csv:Error); + test:assertEquals((cnrr12).message(), "Duplicate field found in record fields: 'a'"); + + RecordWithCustomAnnotation3[]|csv:Error cnrr13 = csv:parseRecordAsRecordType([{"c": 3, "d": 1, "a": 4, "b": 5}], {}); + test:assertTrue(cnrr13 is csv:Error); + test:assertEquals((cnrr13).message(), "Duplicate field found in record fields: 'a'"); + + RecordWithCustomAnnotation4[]|csv:Error cnrr14 = csv:parseRecordAsRecordType([{"d": 1, "c": 3, "z": true}], {}); + test:assertEquals(cnrr14, [{b: 1, a: 3, z: true}]); + + RecordWithCustomAnnotation4[]|csv:Error cnrr15 = csv:parseRecordAsRecordType([{"c": 3, "d": 1}], {}); + test:assertEquals(cnrr15, [{b: 1, a: 3}]); + + RecordWithCustomAnnotation4[]|csv:Error cnrr16 = csv:parseRecordAsRecordType( + [{"c": 3, "f": 3, "d": 1, "e": "cde"}, {"c": 3, "f": 3, "d": 1, "e": "cde"}], {}); + test:assertEquals(cnrr16, [{b: 1, a: 3}, {b: 1, a: 3}]); + + RecordWithCustomAnnotation5[]|csv:Error cnrr20 = csv:parseRecordAsRecordType( + [{"c": 3, "d": 1, "e": 4}, {"c": 3, "d": 1, "e": 4}], {}); + test:assertEquals(cnrr20, [{a: 3, b: 1, c: 4}, {a: 3, b: 1, c: 4}]); + + RecordWithCustomAnnotation6[]|csv:Error cnrr21 = csv:parseRecordAsRecordType( + [{"c": 3, "d": 1, "a": 4}, {"c": 3, "d": 1, "a": 4}], {}); + test:assertEquals(cnrr21, [{a: 3, b: 1, c: 4}, {a: 3, b: 1, c: 4}]); +} + +@test:Config +function testCustomNameAnnotation2() returns error? { + RecordWithCustomAnnotation[]|csv:Error cntr1 = csv:parseListAsRecordType([["1", "3"]], ["b", "c"], {}); + test:assertEquals(cntr1, [{b: 1, a: 3}]); + + RecordWithCustomAnnotation[]|csv:Error cntr2 = csv:parseListAsRecordType([["3", "1"]], ["c", "b"], {}); + test:assertEquals(cntr2, [{b: 1, a: 3}]); + + RecordWithCustomAnnotation[]|csv:Error cntr3 = csv:parseListAsRecordType( + [["3", "3", "1", "cde"], ["3", "3", "1", "cde"]], ["f", "c", "b", "e"], {}); + test:assertEquals(cntr3, [{b: 1, a: 3, f: 3, e: "cde"}, {b: 1, a: 3, f: 3, e: "cde"}]); + + RecordWithCustomAnnotation2[]|csv:Error cntr4 = csv:parseListAsRecordType([["1", "3"]], ["d", "c"], {}); + test:assertEquals(cntr4, [{b: 1, a: 3}]); + + RecordWithCustomAnnotation2[]|csv:Error cntr5 = csv:parseListAsRecordType([["3","1"]], ["c", "d"], {}); + test:assertEquals(cntr5, [{b: 1, a: 3}]); + + RecordWithCustomAnnotation2[]|csv:Error cntr6 = csv:parseListAsRecordType( + [["3", "3", "1", "cde"], ["3", "3", "1", "cde"]], ["c", "f", "d", "e"], {}); + test:assertEquals(cntr6, [{b: 1, a: 3, f: 3, e: "cde"}, {b: 1, a: 3, f: 3, e: "cde"}]); + + RecordWithCustomAnnotation2[]|csv:Error cntr7 = csv:parseListAsRecordType([["3", "1"]], ["a", "b"], {}); + test:assertTrue(cntr7 is csv:Error); + test:assertEquals((cntr7).message(), "Duplicate field found in record fields: 'a'"); + + RecordWithCustomAnnotation2[]|csv:Error cntr8 = csv:parseListAsRecordType([["3", "1", "4", "5"]], ["c", "d", "a", "b"], {}); + test:assertTrue(cntr8 is csv:Error); + test:assertEquals((cntr8).message(), "Duplicate field found in record fields: 'a'"); + + RecordWithCustomAnnotation3[]|csv:Error cntr9 = csv:parseListAsRecordType([["1", "3"]], ["d", "c"], {}); + test:assertEquals(cntr9, [{b: 1, a: 3}]); + + RecordWithCustomAnnotation3[]|csv:Error cntr10 = csv:parseListAsRecordType([["3", "1"]], ["c", "d"], {}); + test:assertEquals(cntr10, [{b: 1, a: 3}]); + + RecordWithCustomAnnotation3[]|csv:Error cntr11 = csv:parseListAsRecordType( + [["3", "3", "1", "cde"], ["3", "3", "1", "cde"]], ["c", "f", "d", "e"], {}); + test:assertEquals(cntr11, [{b: 1, a: 3}, {b: 1, a: 3}]); + + RecordWithCustomAnnotation3[]|csv:Error cntr12 = csv:parseListAsRecordType([["3", "1"]], ["a", "b"], {}); + test:assertTrue(cntr12 is csv:Error); + test:assertEquals((cntr12).message(), common:generateErrorMessageForInvalidHeaders(string `["3","1"]`, "user_config_tests:RecordWithCustomAnnotation3")); + + RecordWithCustomAnnotation3[]|csv:Error cntr13 = csv:parseListAsRecordType([["3", "1", "4", "5"]], ["c", "d", "a", "b"], {}); + test:assertTrue(cntr13 is csv:Error); + test:assertEquals((cntr13).message(), "Duplicate field found in record fields: 'a'"); + + RecordWithCustomAnnotation4[]|csv:Error cntr14 = csv:parseListAsRecordType([["1", "3", "true"]], ["d", "c", "z"], {}); + test:assertEquals(cntr14, [{b: 1, a: 3, z: true}]); + + RecordWithCustomAnnotation4[]|csv:Error cntr15 = csv:parseListAsRecordType([["3", "1"]], ["c", "d"], {}); + test:assertEquals(cntr15, [{b: 1, a: 3}]); + + RecordWithCustomAnnotation4[]|csv:Error cntr16 = csv:parseListAsRecordType( + [["3", "3", "1", "cde"], ["3", "3", "1", "cde"]], ["c", "f", "d", "e"], {}); + test:assertEquals(cntr16, [{b: 1, a: 3}, {b: 1, a: 3}]); + + RecordWithCustomAnnotation4[]|csv:Error cntr17 = csv:parseListAsRecordType([["3", "1"]], ["a", "b"], {}); + test:assertTrue(cntr17 is csv:Error); + test:assertEquals((cntr17).message(), "Duplicate field found in record fields: 'a'"); + + RecordWithCustomAnnotation4[]|csv:Error cntr18 = csv:parseListAsRecordType([["3", "1", "4", "5"]], ["c", "d", "a", "b"], {}); + test:assertTrue(cntr18 is csv:Error); + test:assertEquals((cntr18).message(), "Duplicate field found in record fields: 'a'"); + + RecordWithCustomAnnotation5[]|csv:Error cntr19 = csv:parseListAsRecordType([["3", "1", "4", "5"]], ["c", "d", "a", "b"], {}); + test:assertTrue(cntr19 is csv:Error); + test:assertEquals((cntr19).message(), "Duplicate field found in record fields: 'a'"); + + RecordWithCustomAnnotation5[]|csv:Error cntr20 = csv:parseListAsRecordType( + [["3", "1", "4"], ["3", "1", "4"]], ["c", "d", "e"], {}); + test:assertEquals(cntr20, [{a: 3, b: 1, c: 4}, {a: 3, b: 1, c: 4}]); + + RecordWithCustomAnnotation6[]|csv:Error cntr21 = csv:parseListAsRecordType( + [["3", "1", "4"], ["3", "1", "4"]], ["c", "d", "a"], {}); + test:assertEquals(cntr21, [{a: 3, b: 1, c: 4}, {a: 3, b: 1, c: 4}]); +} + +@test:Config +function testAbsentAsNilableConfig() returns error? { + record {|int a; int? g; int? h;|}[]|csv:Error cn = csv:parseStringToRecord(csvStringData1, { + allowDataProjection: {absentAsNilableType: true}, + header: 1 + }); + test:assertEquals(cn, [{a: 1, g: (), h: ()}, {a: 2, g: (), h: ()}, {a: 3, g: (), h: ()}, {a: 4, g: (), h: ()}, {a: 5, g: (), h: ()}]); + + record {|int a; int? g?;|}[]|csv:Error cn2 = csv:parseStringToRecord(csvStringData1, { + allowDataProjection: {absentAsNilableType: true}, + header: 1, + skipLines: "2-10" + }); + test:assertEquals(cn2, [{a: 1}]); + + record {|int a; int g?;|}[]|csv:Error cn3 = csv:parseStringToRecord(csvStringData1, { + allowDataProjection: {absentAsNilableType: true}, + header: 1, + skipLines: "2-10" + }); + test:assertEquals(cn3, [{a: 1}]); + + record {|int a; int g;|}[]|csv:Error cn4 = csv:parseStringToRecord(csvStringData1, { + allowDataProjection: {absentAsNilableType: true}, + header: 1, + skipLines: "2-10" + }); + test:assertTrue(cn4 is csv:Error); + test:assertEquals((cn4).message(), common:generateErrorMessageForMissingRequiredField("g")); + + int?[][]|csv:Error cn5 = csv:parseStringToList(string ` + a,b,c + 1, 1,1`, { + allowDataProjection: {absentAsNilableType: true}, + header: 1 + }); + test:assertEquals(cn5, [[1, 1, 1]]); + + map[]|csv:Error cn6 = csv:parseStringToRecord(string ` + a,b,c + 1, 1,1`, { + allowDataProjection: {absentAsNilableType: true}, + header: 1 + }); + test:assertEquals(cn6, [{a: 1, b: 1, c: 1}]); + + [int, string?, boolean?, decimal?, float?, (), string?][]|csv:Error cn7 = csv:parseStringToList(csvStringData1, { + allowDataProjection: {absentAsNilableType: true}, + header: 1, + skipLines: "2-10" + }); + test:assertEquals(cn7, [[1, "string1", true, 2.234, 2.234, null, null]]); + + [int, string?, boolean?, decimal?, float?, (), string?][]|csv:Error cn8 = csv:parseStringToList(csvStringData1, { + allowDataProjection: {absentAsNilableType: true}, + header: 1, + skipLines: "2-10" + }); + test:assertEquals(cn8, [[1, "string1", true, 2.234, 2.234, null, null]]); + + [int, string?, boolean?, decimal?, float?, (), string?][]|csv:Error cn9 = csv:parseStringToList(csvStringData1, { + allowDataProjection: {absentAsNilableType: true}, + header: 1, + skipLines: "2-10" + }); + test:assertEquals(cn9, [[1, "string1", true, 2.234, 2.234, null, null]]); + + [int, string?, boolean?, decimal?, float?, (), string?][]|csv:Error cn10 = csv:parseStringToList(csvStringData1, { + allowDataProjection: {absentAsNilableType: true}, + header: 1, + skipLines: "2-10" + }); + test:assertEquals(cn10, [[1, "string1", true, 2.234, 2.234, null, null]]); +} + +@test:Config +function testAbsentAsNilableConfig2() returns error? { + record {|int a; int? g; int? h;|}[]|csv:Error cn = csv:parseRecordAsRecordType([{"a": 1}, {"a": 2}, {"a": 3}], { + allowDataProjection: {absentAsNilableType: true}, skipLines: [3] + }); + test:assertEquals(cn, [{a: 1, g: (), h: ()}, {a: 2, g: (), h: ()}]); + + record {|int a; int? g?;|}[]|csv:Error cn2 = csv:parseRecordAsRecordType([{"a": 1}, {"a": 2}, {"a": 3}], { + allowDataProjection: {absentAsNilableType: true}, skipLines: [3] + }); + test:assertEquals(cn2, [{a: 1}, {a: 2}]); + + record {|int a; int g?;|}[]|csv:Error cn3 = csv:parseRecordAsRecordType([{"a": 1}, {"a": 2}, {"a": 3}], { + allowDataProjection: {absentAsNilableType: true}, skipLines: [3] + }); + test:assertEquals(cn3, [{a: 1}, {a: 2}]); + + record {|int a; int g;|}[]|csv:Error cn4 = csv:parseRecordAsRecordType([{"a": 1}, {"a": 2}, {"a": 3}], { + allowDataProjection: {absentAsNilableType: true}, skipLines: [3] + }); + test:assertTrue(cn4 is csv:Error); + test:assertEquals((cn4).message(), common:generateErrorMessageForMissingRequiredField("g")); + + record {|string a; int? g; int? h;|}[]|csv:Error cn5 = csv:parseListAsRecordType([["a"], ["a"], ["a"]], ["a"], { + allowDataProjection: {absentAsNilableType: true}, skipLines: [3] + }); + test:assertEquals(cn5, [{a: "a", g: (), h: ()}, {a: "a", g: (), h: ()}]); + + record {|string a; int? g?;|}[]|csv:Error cn6 = csv:parseListAsRecordType([["a"], ["a"], ["a"]], ["a"], { + allowDataProjection: {absentAsNilableType: true}, skipLines: [3] + }); + test:assertEquals(cn6, [{a: "a"}, {a: "a"}]); + + record {|string a; int g?;|}[]|csv:Error cn7 = csv:parseListAsRecordType([["a"], ["a"], ["b"]], ["a"], { + allowDataProjection: {absentAsNilableType: true}, skipLines: [2] + }); + test:assertEquals(cn7, [{a: "a"}, {a: "b"}]); + + record {|string a; int g;|}[]|csv:Error cn8 = csv:parseListAsRecordType([["a"], ["a"], ["a"]], ["a"], { + allowDataProjection: {absentAsNilableType: true}, skipLines: [3] + }); + test:assertTrue(cn8 is csv:Error); + test:assertEquals((cn8).message(), common:generateErrorMessageForMissingRequiredField("g")); +} + +@test:Config +function testNilAsOptionalConfig() returns error? { + record {|int a; int f?;|}[]|csv:Error cn = csv:parseStringToRecord(csvStringData1, { + allowDataProjection: {nilAsOptionalField: true}, + header: 1 + }); + test:assertEquals(cn, [{a: 1}, {a: 2}, {a: 3}, {a: 4}, {a: 5}]); + + record {|int a; int? f?;|}[]|csv:Error cn2 = csv:parseStringToRecord(csvStringData1, { + allowDataProjection: {nilAsOptionalField: true}, + header: 1, + skipLines: "2-10" + }); + test:assertEquals(cn2, [{a: 1, f: ()}]); + + record {|int a; int f?;|}[]|csv:Error cn3 = csv:parseStringToRecord(csvStringData1, { + allowDataProjection: {nilAsOptionalField: true}, + header: 1, + skipLines: "2-10" + }); + test:assertEquals(cn3, [{a: 1}]); + + record {|int a; int f;|}[]|csv:Error cn4 = csv:parseStringToRecord(csvStringData1, { + allowDataProjection: {nilAsOptionalField: true}, + header: 1, + skipLines: "2-10" + }); + test:assertTrue(cn4 is csv:Error); + test:assertEquals((cn4).message(), common:generateErrorMessageForInvalidCast("()", "int")); + + int?[][]|csv:Error cn5 = csv:parseStringToList(string ` + a,b,c + 1, 1,1`, { + allowDataProjection: {nilAsOptionalField: true}, + header: 1 + }); + test:assertEquals(cn5, [[1, 1, 1]]); + + map[]|csv:Error cn6 = csv:parseStringToRecord(string ` + a,b,c + 1, 1,1`, { + allowDataProjection: {nilAsOptionalField: true}, + header: 1 + }); + test:assertEquals(cn6, [{a: 1, b: 1, c: 1}]); + + [int, string?, boolean?, decimal?, float?, (), string?][]|csv:Error cn7 = csv:parseStringToList(csvStringData1, { + allowDataProjection: {nilAsOptionalField: true}, + header: 1, + skipLines: "2-10" + }); + test:assertEquals(cn7, [[1, "string1", true, 2.234, 2.234, null, null]]); + + [int, string?, boolean?, decimal?, float?, (), string?][]|csv:Error cn8 = csv:parseStringToList(csvStringData1, { + allowDataProjection: {nilAsOptionalField: true}, + header: 1, + skipLines: "2-10" + }); + test:assertEquals(cn8, [[1, "string1", true, 2.234, 2.234, null, null]]); + + [int, string?, boolean?, decimal?, float?, (), string?][]|csv:Error cn9 = csv:parseStringToList(csvStringData1, { + allowDataProjection: {nilAsOptionalField: true}, + header: 1, + skipLines: "2-10" + }); + test:assertEquals(cn9, [[1, "string1", true, 2.234, 2.234, null, null]]); + + [int, string?, boolean?, decimal?, float?, (), string?][]|csv:Error cn10 = csv:parseStringToList(csvStringData1, { + allowDataProjection: {nilAsOptionalField: true}, + header: 1, + skipLines: "2-10" + }); + test:assertEquals(cn10, [[1, "string1", true, 2.234, 2.234, null, null]]); +} + +@test:Config +function testNilAsOptionalConfig2() returns error? { + record {|int a; int? f;|}[]|csv:Error cn = csv:parseRecordAsRecordType([{"a": 1, "f": ()}, {"a": 2, "f": ()}, {"a": 3, "f": ()}], { + allowDataProjection: {nilAsOptionalField: true}, skipLines: [3] + }); + test:assertEquals(cn, [{a: 1, f: ()}, {a: 2, f: ()}]); + + record {|int a; int? f?;|}[]|csv:Error cn2 = csv:parseRecordAsRecordType([{"a": 1, "f": ()}, {"a": 2, "f": ()}, {"a": 3, "f": ()}], { + allowDataProjection: {nilAsOptionalField: true}, skipLines: [3] + }); + test:assertEquals(cn2, [{a: 1, f: ()}, {a: 2, f: ()}]); + + record {|int a; int f?;|}[]|csv:Error cn3 = csv:parseRecordAsRecordType([{"a": 1, "f": ()}, {"a": 2, "f": ()}, {"a": 3, "f": ()}], { + allowDataProjection: {nilAsOptionalField: true}, skipLines: [3] + }); + test:assertEquals(cn3, [{a: 1}, {a: 2}]); + + record {|int a; int f;|}[]|csv:Error cn4 = csv:parseRecordAsRecordType([{"a": 1, "f": ()}, {"a": 2, "f": ()}, {"a": 3, "f": ()}], { + allowDataProjection: {nilAsOptionalField: true}, skipLines: [3] + }); + test:assertTrue(cn4 is csv:Error); + test:assertEquals((cn4).message(), common:generateErrorMessageForInvalidFieldType("null", "f")); +} + +@test:Config +function testDataProjectionConfig() returns error? { + string csvValue1 = string `a,b + "a",2 + b,4`; + record{}[] csvValue2 = [{"a": "a", "b": 2}, {"a": "b", "b": 4}]; + + record{}[]|csv:Error cn = csv:parseStringToRecord(csvValue1, { + allowDataProjection: false + }); + test:assertEquals(cn, [{"a": "a", "b": 2}, {"a": "b", "b": 4}]); + + record{|string a; int b;|}[]|csv:Error cn_2 = csv:parseStringToRecord(csvValue1, { + allowDataProjection: false + }); + test:assertEquals(cn_2, [{"a": "a", "b": 2}, {"a": "b", "b": 4}]); + + record{|string a;|}[]|csv:Error cn2 = csv:parseStringToRecord(csvValue1, { + allowDataProjection: false + }); + test:assertTrue(cn2 is csv:Error); + test:assertEquals((cn2).message(), "No mapping field in the expected type for header 'b'"); + + record{|string a; int...;|}[]|csv:Error cn3 = csv:parseStringToRecord(csvValue1, { + allowDataProjection: false + }); + test:assertEquals(cn3, [{"a": "a", "b": 2}, {"a": "b", "b": 4}]); + + record{|string...;|}[]|csv:Error cn4 = csv:parseStringToRecord(csvValue1, { + allowDataProjection: false + }); + test:assertEquals(cn4, [{"a": "a", "b": "2"}, {"a": "b", "b": "4"}]); + + record{|string a?;|}[]|csv:Error cn5 = csv:parseStringToRecord(csvValue1, { + allowDataProjection: false + }); + test:assertTrue(cn5 is csv:Error); + test:assertEquals((cn5).message(), "No mapping field in the expected type for header 'b'"); + + record{|string? a;|}[]|csv:Error cn6 = csv:parseStringToRecord(csvValue1, { + allowDataProjection: false + }); + test:assertTrue(cn6 is csv:Error); + test:assertEquals((cn6).message(), "No mapping field in the expected type for header 'b'"); + + anydata[][]|csv:Error c7 = csv:parseStringToList(csvValue1, { + allowDataProjection: false + }); + test:assertEquals(c7, [["a", 2], ["b", 4]]); + + [string, int][]|csv:Error cn7_2 = csv:parseStringToList(csvValue1, { + allowDataProjection: false + }); + test:assertEquals(cn7_2, [["a", 2], ["b", 4]]); + + [string][]|csv:Error cn8 = csv:parseStringToList(csvValue1, { + allowDataProjection: false + }); + test:assertTrue(cn8 is csv:Error); + test:assertEquals((cn8).message(), "invalid array size for expected tuple type, cannot be greater than '1'"); + + [string][]|csv:Error cn8_2 = csv:parseStringToList(csvValue1, { + allowDataProjection: {} + }); + test:assertEquals(cn8_2, [["a"], ["b"]]); + + [int][]|csv:Error cn8_3 = csv:parseStringToList(csvValue1, { + allowDataProjection: {} + }); + test:assertTrue(cn8_3 is csv:Error); + test:assertEquals((cn8_3).message(), common:generateErrorMessageForInvalidCast("a", "int")); + + [string, int...][]|csv:Error cn9 = csv:parseStringToList(csvValue1, { + allowDataProjection: false + }); + test:assertEquals(cn9, [["a", 2], ["b", 4]]); + + [string...][]|csv:Error cn10 = csv:parseStringToList(csvValue1, { + allowDataProjection: false + }); + test:assertEquals(cn10, [["a", "2"], ["b", "4"]]); + + [string, ()][]|csv:Error cn11 = csv:parseStringToList(csvValue1, { + allowDataProjection: false + }); + test:assertTrue(cn11 is csv:Error); + test:assertEquals((cn11).message(), common:generateErrorMessageForInvalidCast("2", "()")); + + string[][]|csv:Error cn12 = csv:parseStringToList(csvValue1, { + allowDataProjection: false + }); + test:assertEquals(cn12, [["a", "2"], ["b", "4"]]); + + string[][1]|csv:Error cn13 = csv:parseStringToList(csvValue1, { + allowDataProjection: false + }); + test:assertTrue(cn13 is csv:Error); + test:assertEquals((cn13).message(), "invalid array size for expected array type, cannot be greater than '1'"); + + record{}[]|csv:Error cn14 = csv:parseRecordAsRecordType(csvValue2, { + allowDataProjection: false + }); + test:assertEquals(cn14, [{"a": "a", "b": 2}, {"a": "b", "b": 4}]); + + record{|string a; int b;|}[]|csv:Error cn14_2 = csv:parseRecordAsRecordType(csvValue2, { + allowDataProjection: false + }); + test:assertEquals(cn14_2, [{"a": "a", "b": 2}, {"a": "b", "b": 4}]); + + record{|string a;|}[]|csv:Error cn15 = csv:parseRecordAsRecordType(csvValue2, { + allowDataProjection: false + }); + test:assertTrue(cn15 is csv:Error); + test:assertEquals((cn15).message(), "No mapping field in the expected type for header 'b'"); + + record{|string a; int...;|}[]|csv:Error cn16 = csv:parseRecordAsRecordType(csvValue2, { + allowDataProjection: false + }); + test:assertEquals(cn16, [{"a": "a", "b": 2}, {"a": "b", "b": 4}]); + + record{|string...;|}[]|csv:Error cn17 = csv:parseRecordAsRecordType(csvValue2, { + allowDataProjection: false + }); + test:assertEquals(cn17, [{"a": "a"}, {"a": "b"}]); + + record{|string a?;|}[]|csv:Error cn18 = csv:parseRecordAsRecordType(csvValue2, { + allowDataProjection: false + }); + test:assertTrue(cn18 is csv:Error); + test:assertEquals((cn18).message(), "No mapping field in the expected type for header 'b'"); + + record{|string? a;|}[]|csv:Error cn19 = csv:parseRecordAsRecordType(csvValue2, { + allowDataProjection: false + }); + test:assertTrue(cn19 is csv:Error); + test:assertEquals((cn19).message(), "No mapping field in the expected type for header 'b'"); + + anydata[][]|csv:Error c20 = csv:parseRecordAsListType(csvValue2, ["a", "b"] ,{ + allowDataProjection: false + }); + test:assertEquals(c20, [["a", 2], ["b", 4]]); + + [string, int][]|csv:Error cn20_2 = csv:parseRecordAsListType(csvValue2, ["a", "b"] ,{ + allowDataProjection: false + }); + test:assertEquals(cn20_2, [["a", 2], ["b", 4]]); + + [string][]|csv:Error cn21 = csv:parseRecordAsListType(csvValue2, ["a", "b"] ,{ + allowDataProjection: false + }); + test:assertTrue(cn21 is csv:Error); + test:assertEquals((cn21).message(), "invalid array size for expected tuple type, cannot be greater than '1'"); + + [string][]|csv:Error cn21_2 = csv:parseRecordAsListType(csvValue2, ["a", "b"] ,{ + allowDataProjection: {} + }); + test:assertEquals(cn21_2, [["a"], ["b"]]); + + [int][]|csv:Error cn21_3 = csv:parseRecordAsListType(csvValue2, ["a", "b"] ,{ + allowDataProjection: {} + }); + test:assertTrue(cn21_3 is csv:Error); + test:assertEquals((cn21_3).message(), common:generateErrorMessageForInvalidValueForArrayType("a", "0", "int")); + + [string, int...][]|csv:Error cn22 = csv:parseRecordAsListType(csvValue2, ["a", "b"] ,{ + allowDataProjection: false + }); + test:assertEquals(cn22, [["a", 2], ["b", 4]]); + + [string...][]|csv:Error cn23 = csv:parseRecordAsListType(csvValue2, ["a", "b"] ,{ + allowDataProjection: false + }); + test:assertTrue(cn23 is csv:Error); + test:assertEquals(( cn23).message(), common:generateErrorMessageForInvalidValueForArrayType("2", "1", "string")); + + [string, ()][]|csv:Error cn24 = csv:parseRecordAsListType(csvValue2, ["a", "b"] ,{ + allowDataProjection: false + }); + test:assertTrue(cn24 is csv:Error); + test:assertEquals((cn24).message(), common:generateErrorMessageForInvalidValueForArrayType("2", "1", "()")); + + string[][]|csv:Error cn25 = csv:parseRecordAsListType(csvValue2, ["a", "b"] ,{ + allowDataProjection: false + }); + test:assertTrue(cn25 is csv:Error); + test:assertEquals(( cn25).message(), common:generateErrorMessageForInvalidValueForArrayType("2", "1", "string")); + + string[][1]|csv:Error cn26 = csv:parseRecordAsListType(csvValue2, ["a", "b"] ,{ + allowDataProjection: false + }); + test:assertTrue(cn26 is csv:Error); + test:assertEquals((cn26).message(), "invalid array size for expected array type, cannot be greater than '1'"); +} diff --git a/ballerina-tests/user-config-tests/tests/user_config_with_parser_options_test.bal b/ballerina-tests/user-config-tests/tests/user_config_with_parser_options_test.bal new file mode 100644 index 0000000..250fcc4 --- /dev/null +++ b/ballerina-tests/user-config-tests/tests/user_config_with_parser_options_test.bal @@ -0,0 +1,860 @@ +import ballerina/csv_commons as common; +import ballerina/data.csv as csv; +import ballerina/test; + +@test:Config +function testFromCsvStringWithParserOptions() { + [int, string, boolean, decimal, float, string][]|csv:Error csv1op3 = csv:parseStringToList(csvStringData1, option3); + test:assertEquals(csv1op3, [ + [3, "string3", false, 1.23, 1.23, "()"], + [4, "string4", true, -6.51, -6.51, "()"], + [5, "string5", true, 3, 3.0, "()"] + ]); + + record {int a; string b; boolean c; decimal d; float e; string f;}[]|csv:Error csv1op3_2 = csv:parseStringToRecord(csvStringData1, ptOption1); + test:assertEquals(csv1op3_2, [ + {a: 1, b: "string1", c: true, d: 2.234, e: 2.234, f: "()"}, + {a: 3, b: "string3", c: false, d: 1.23, e: 1.23, f: "()"}, + {a: 5, b: "string5", c: true, d: 3, e: 3.0, f: "()"} + ]); + + record {int a; string b; boolean c; decimal d; float e; string f;}[]|csv:Error csv1op3_3 = csv:parseStringToRecord(csvStringData1, ptOption2); + test:assertEquals(csv1op3_3, [ + {a: 1, b: "string1", c: true, d: 2.234, e: 2.234, f: "()"}, + {a: 5, b: "string5", c: true, d: 3, e: 3.0, f: "()"} + ]); + + [int, string, boolean, decimal, float, string][]|csv:Error csv2op4 = csv:parseStringToList(csvStringData2, option4); + test:assertEquals(csv2op4, []); + + record {}[]|csv:Error csv2op4_2 = csv:parseStringToRecord(csvStringData2, ptOption3); + test:assertEquals(csv2op4_2, []); + + record {}[]|csv:Error csv2op4_3 = csv:parseStringToRecord(csvStringData2, ptOption4); + test:assertEquals(csv2op4_3, [ + {a: 1, b: "string1", c: true, d: 2.234, e: 2.234, f: "()"}, + {a: 3, b: "string3", c: false, d: 1.23, e: 1.23, f: "()"}, + {a: 5, b: "string5", c: true, d: 3, e: 3, f: "()"} + ]); + + [int, string, boolean, decimal, float, string][]|csv:Error csv3op3 = csv:parseStringToList(csvStringData3, option3); + test:assertEquals(csv3op3, [ + [3, "string3", false, 1.23, 1.23, "()"], + [4, "string4", true, -6.51, -6.51, "()"], + [5, "string5", true, 3, 3.0, "()"] + ]); + + record {}[]|csv:Error csv3op3_2 = csv:parseStringToRecord(csvStringData3, ptOption1); + test:assertEquals(csv3op3_2, [ + {a: 1, b: "string1", c: true, d: 2.234, e: 2.234, f: "()"}, + {a: 3, b: "string3", c: false, d: 1.23, e: 1.23, f: "()"}, + {a: 5, b: "string5", c: true, d: 3, e: 3, f: "()"} + ]); + + record {}[]|csv:Error csv3op3_3 = csv:parseStringToRecord(csvStringData3, ptOption2); + test:assertEquals(csv3op3_3, [ + {a: 1, b: "string1", c: true, d: 2.234, e: 2.234, f: "()"}, + {a: 5, b: "string5", c: true, d: 3, e: 3, f: "()"} + ]); + + record {}[]|csv:Error csv3op3_4 = csv:parseStringToRecord(csvStringData3, {header: 9, skipLines: "2-10"}); + test:assertEquals(csv3op3_4, [ + {'4: 5, string4: "string5", "true": true, "-6.51": 3, "()": null} + ]); +} + +@test:Config +function testFromCsvStringWithHeaderLessParserOptions() { + [int, string, boolean, decimal, float, ()][]|csv:Error csv1op6 = csv:parseStringToList(csvStringData1, option6); + test:assertTrue(csv1op6 is csv:Error); + test:assertEquals((csv1op6).message(), common:generateErrorMessageForInvalidCast("null", "()")); + + record {}[]|csv:Error csv1op5_2 = csv:parseStringToRecord(csvStringData1, ptOption5); + test:assertEquals(csv1op5_2, [ + {'1: "a", '2: "b", '3: "c", '4: "d", '5: "e", '6: "f"}, + {'1: 1, '2: "string1", '3: true, '4: 2.234, '5: 2.234, '6: ()}, + {'1: 3, '2: "string3", '3: false, '4: 1.23, '5: 1.23, '6: ()}, + {'1: 5, '2: "string5", '3: true, '4: 3, '5: 3, '6: ()} + ]); + + record {}[]|csv:Error csv1op6_2 = csv:parseStringToRecord(csvStringData1, {header: false, skipLines: [3, 5]}); + test:assertEquals(csv1op6_2, [ + {'1: "a", '2: "b", '3: "c", '4: "d", '5: "e", '6: "f"}, + {'1: 1, '2: "string1", '3: true, '4: 2.234, '5: 2.234, '6: ()}, + {'1: 3, '2: "string3", '3: false, '4: 1.23, '5: 1.23, '6: ()}, + {'1: 5, '2: "string5", '3: true, '4: 3, '5: 3, '6: ()} + ]); + + record {}[]|csv:Error csv3op6_2 = csv:parseStringToRecord(csvStringData3, {header: false, skipLines: [1, 3, 5, -1, 100, 100]}); + test:assertEquals(csv3op6_2, [ + {'1: 1, '2: "string1", '3: true, '4: 2.234, '5: 2.234, '6: ()}, + {'1: 3, '2: "string3", '3: false, '4: 1.23, '5: 1.23, '6: ()}, + {'1: 5, '2: "string5", '3: true, '4: 3, '5: 3, '6: ()} + ]); + + record {}[]|csv:Error csv4op6_2 = csv:parseStringToRecord(csvStringData4, {header: false, skipLines: [2, 4, -1, 100, 100]}); + test:assertEquals(csv4op6_2, [ + {'1: 1, '2: "string1", '3: true, '4: 2.234, '5: 2.234, '6: ()}, + {'1: 3, '2: "string3", '3: false, '4: 1.23, '5: 1.23, '6: ()}, + {'1: 5, '2: "string5", '3: true, '4: 3, '5: 3, '6: ()} + ]); + + record {}[]|csv:Error csv5op6_2 = csv:parseStringToRecord(csvStringData5, {header: false, skipLines: [2, 4, -1, 100, 100]}); + test:assertEquals(csv5op6_2, [ + {'1: 1, '2: "string1", '3: true, '4: 2.234, '5: 2.234, '6: ()}, + {'1: 3, '2: "string3", '3: false, '4: 1.23, '5: 1.23, '6: ()}, + {'1: 5, '2: "string5", '3: true, '4: 3, '5: 3, '6: ()} + ]); + + record {}[]|csv:Error csv6op6_2 = csv:parseStringToRecord(csvStringData6, {header: false, skipLines: [2, 4, -1, 100, 100]}); + test:assertEquals(csv6op6_2, [ + {'1: 1, '2: "string1", '3: true, '4: 2.234, '5: 2.234, '6: ()}, + {'1: 3, '2: "string3", '3: false, '4: 1.23, '5: 1.23, '6: ()}, + {'1: 5, '2: "string5", '3: true, '4: 3, '5: 3, '6: ()} + ]); + + record {}[]|csv:Error csv2op6_2 = csv:parseStringToRecord(csvStringData2, {header: false, skipLines: [5, 7]}); + test:assertEquals(csv2op6_2, [ + {'1: "hello", '2: "hello", '3: (), '4: 12, '5: true, '6: 12.34}, + {'1: "// comment"}, + {'1: "a", '2: "b", '3: "c", '4: "d", '5: "e", '6: "f"}, + {'1: 1, '2: "string1", '3: true, '4: 2.234, '5: 2.234, '6: ()}, + {'1: 3, '2: "string3", '3: false, '4: 1.23, '5: 1.23, '6: ()}, + {'1: 5, '2: "string5", '3: true, '4: 3, '5: 3, '6: ()} + ]); +} + +@test:Config +function testHeaderOption() { + record {}[]|csv:Error csv2cop1 = csv:parseStringToRecord(csvStringData2, {header: 4}); + test:assertEquals(csv2cop1, [ + {a: 1, b: "string1", c: true, d: 2.234, e: 2.234, f: ()}, + {a: 2, b: "string2", c: false, d: 0, e: 0, f: ()}, + {a: 3, b: "string3", c: false, d: 1.23, e: 1.23, f: ()}, + {a: 4, b: "string4", c: true, d: -6.51, e: -6.51, f: ()}, + {a: 5, b: "string5", c: true, d: 3, e: 3, f: ()} + ]); + + record {}[]|csv:Error csv2cop2 = csv:parseStringToRecord(csvStringData2, {header: 100}); + test:assertTrue(csv2cop2 is csv:Error); + test:assertEquals(( csv2cop2).message(), "The provided header row is empty"); + + record {}[]|csv:Error csv2cop3 = csv:parseStringToRecord(csvStringData2, {header: 11}); + test:assertEquals(csv2cop3, []); + + record {}[]|csv:Error csv2cop4 = csv:parseStringToRecord(csvStringData2, {header: 10}); + test:assertEquals(csv2cop4, [{'4: 5, string4: "string5", "true": true, "-6.51": 3, "()": ()}]); + + record {}[]|csv:Error csv1cop5 = csv:parseStringToRecord(csvStringData1, {}); + test:assertTrue(csv1cop5 is csv:Error); + test:assertEquals((csv1cop5).message(), "The provided header row is empty"); +} + +@test:Config +function testNullConfigOption() { + string csvValue1 = string `a + ()`; + string csvValue2 = string `a + null`; + string csvValue3 = string `c, a + true, e`; + string csvValue4 = string `a + Null`; + string csvValue5 = string `b, a + bN/Aa,N/A`; + + record {() a;}[]|csv:Error cn = csv:parseStringToRecord(csvValue1, {nilValue: ()}); + test:assertEquals(cn, [{a: ()}]); + + cn = csv:parseStringToRecord(csvValue2, {nilValue: ()}); + test:assertEquals(cn, [{a: ()}]); + + cn = csv:parseStringToRecord(csvValue3, {nilValue: ()}); + test:assertTrue(cn is csv:Error); + test:assertEquals((cn).message(), common:generateErrorMessageForInvalidCast("e", "()")); + + cn = csv:parseStringToRecord(csvValue4, {nilValue: ()}); + test:assertEquals(cn, [{a: ()}]); + + cn = csv:parseStringToRecord(csvValue1, {nilValue: null}); + test:assertEquals(cn, [{a: ()}]); + + cn = csv:parseStringToRecord(csvValue2, {nilValue: null}); + test:assertEquals(cn, [{a: ()}]); + + cn = csv:parseStringToRecord(csvValue3, {nilValue: null}); + test:assertTrue(cn is csv:Error); + test:assertEquals((cn).message(), common:generateErrorMessageForInvalidCast("e", "()")); + + cn = csv:parseStringToRecord(csvValue4, {nilValue: null}); + test:assertEquals(cn, [{a: ()}]); + + cn = csv:parseStringToRecord(csvValue1, {nilValue: "()"}); + test:assertEquals(cn, [{a: ()}]); + + cn = csv:parseStringToRecord(csvValue2, {nilValue: "()"}); + test:assertTrue(cn is csv:Error); + test:assertEquals((cn).message(), common:generateErrorMessageForInvalidCast("null", "()")); + + cn = csv:parseStringToRecord(csvValue3, {nilValue: "()"}); + test:assertTrue(cn is csv:Error); + test:assertEquals((cn).message(), common:generateErrorMessageForInvalidCast("e", "()")); + + cn = csv:parseStringToRecord(csvValue4, {nilValue: "()"}); + test:assertTrue(cn is csv:Error); + test:assertEquals((cn).message(), common:generateErrorMessageForInvalidCast("Null", "()")); + + cn = csv:parseStringToRecord(csvValue5, {nilValue: "N/A"}); + test:assertEquals(cn, [{b: "bN/Aa", a: ()}]); + + cn = csv:parseStringToRecord(csvValue2, {nilValue: "null"}); + test:assertEquals(cn, [{a: ()}]); + + cn = csv:parseStringToRecord(csvValue4, {nilValue: "null"}); + test:assertTrue(cn is csv:Error); + test:assertEquals((cn).message(), common:generateErrorMessageForInvalidCast("Null", "()")); + + cn = csv:parseStringToRecord(csvValue1, {nilValue: "null"}); + test:assertTrue(cn is csv:Error); + test:assertEquals((cn).message(), common:generateErrorMessageForInvalidCast("()", "()")); +} + +@test:Config +function testCommentConfigOption() { + string csvValue1 = string `a + 1`; + string csvValue2 = string `a # comment + 1`; + string csvValue3 = string `a #, c + 1#, e`; + string csvValue4 = string `a + # comment + 1`; + string csvValue5 = string `a, b + 1,2 + # comment`; + string csvValue6 = string `a, b + 1,2 # comment + # comment`; + string csvValue7 = string `a, b + 1#,2 comment + # comment`; + string csvValue8 = string `a#, b + 1, 2 # comment + # comment`; + string csvValue9 = string `a,# b + 1 ,#2 # comment + # comment`; + + record {int a;}[]|csv:Error cn; + + cn = csv:parseStringToRecord(csvValue1); + test:assertEquals(cn, [{a: 1}]); + + cn = csv:parseStringToRecord(csvValue2); + test:assertEquals(cn, [{a: 1}]); + + cn = csv:parseStringToRecord(csvValue3); + test:assertEquals(cn, [{a: 1}]); + + cn = csv:parseStringToRecord(csvValue4); + test:assertEquals(cn, [{a: 1}]); + + cn = csv:parseStringToRecord(csvValue5); + test:assertEquals(cn, [{a: 1, b: 2}]); + + cn = csv:parseStringToRecord(csvValue6); + test:assertEquals(cn, [{a: 1, b: 2}]); + + cn = csv:parseStringToRecord(csvValue7); + test:assertEquals(cn, [{a: 1}]); + + record {|int a; int b;|}[]|csv:Error cn2 = csv:parseStringToRecord(csvValue7, {header: 0}); + test:assertEquals(cn2, [{a: 1, b: 0}]); + + cn = csv:parseStringToRecord(csvValue8); + test:assertTrue(cn is csv:Error); + // TODO:Fix the error message + // test:assertEquals(( cn).message(), common:generateErrorMessageForInvalidCast("1, 2", "int")); + + cn = csv:parseStringToRecord(csvValue9); + test:assertEquals(cn, [{a: 1}]); +} + +@test:Config +function testCommentConfigOption2() { + string csvValue1 = string `a + 1`; + string csvValue2 = string `a & comment + 1`; + string csvValue3 = string `a &, c + 1&, e`; + string csvValue4 = string `a + + + + & comment + 1`; + string csvValue5 = string `a&, b + 1, 2 & comment + + + & comment`; + string csvValue6 = string ` + + a,& b + 1 ,&2 & comment + + & comment`; + + record {int a; int b;}[]|csv:Error cn; + record {int c;}[]|csv:Error cn2; + + cn = csv:parseStringToRecord(csvValue1, {comment: "&"}); + test:assertTrue(cn is csv:Error); + test:assertEquals((cn).message(), common:generateErrorMessageForMissingRequiredField("b")); + + cn = csv:parseStringToRecord(csvValue2, {comment: "&"}); + test:assertTrue(cn is csv:Error); + test:assertEquals((cn).message(), common:generateErrorMessageForMissingRequiredField("b")); + + cn = csv:parseStringToRecord(csvValue3, {comment: "&"}); + test:assertTrue(cn is csv:Error); + test:assertEquals((cn).message(), common:generateErrorMessageForMissingRequiredField("b")); + + cn = csv:parseStringToRecord(csvValue4, {comment: "&"}); + test:assertTrue(cn is csv:Error); + test:assertEquals((cn).message(), common:generateErrorMessageForMissingRequiredField("b")); + + cn = csv:parseStringToRecord(csvValue5, {comment: "&"}); + test:assertTrue(cn is csv:Error); + // TODO: Fix the error message + // test:assertEquals(( cn).message(), common:generateErrorMessageForMissingRequiredField("b")); + + cn = csv:parseStringToRecord(csvValue6, {comment: "&", header: 2}); + test:assertTrue(cn is csv:Error); + test:assertEquals((cn).message(), common:generateErrorMessageForMissingRequiredField("b")); + + cn2 = csv:parseStringToRecord(csvValue1, {comment: "&"}); + test:assertTrue(cn2 is csv:Error); + test:assertEquals((cn2).message(), common:generateErrorMessageForMissingRequiredField("c")); + + cn2 = csv:parseStringToRecord(csvValue2, {comment: "&"}); + test:assertTrue(cn2 is csv:Error); + test:assertEquals((cn2).message(), common:generateErrorMessageForMissingRequiredField("c")); + + cn2 = csv:parseStringToRecord(csvValue3, {comment: "&"}); + test:assertTrue(cn2 is csv:Error); + test:assertEquals((cn2).message(), common:generateErrorMessageForMissingRequiredField("c")); + + cn2 = csv:parseStringToRecord(csvValue4, {comment: "&"}); + test:assertTrue(cn2 is csv:Error); + test:assertEquals((cn2).message(), common:generateErrorMessageForMissingRequiredField("c")); + + cn2 = csv:parseStringToRecord(csvValue5, {comment: "&"}); + test:assertTrue(cn2 is csv:Error); + // TODO: Fix the error message + // test:assertEquals(( cn2).message(), common:generateErrorMessageForMissingRequiredField("c")); + + cn2 = csv:parseStringToRecord(csvValue6, {header: 2, comment: "&"}); + test:assertTrue(cn2 is csv:Error); + test:assertEquals((cn2).message(), common:generateErrorMessageForMissingRequiredField("c")); +} + +@test:Config +function testSkipLineParserOption() { + [int, string, boolean, decimal, float, ()][]|csv:Error csv1cp = csv:parseStringToList(csvStringData1, {skipLines: [], header: 1}); + test:assertEquals(csv1cp, [ + [1, "string1", true, 2.234, 2.234, ()], + [2, "string2", false, 0, 0, ()], + [3, "string3", false, 1.23, 1.23, ()], + [4, "string4", true, -6.51, -6.51, ()], + [5, "string5", true, 3, 3.0, ()] + ]); + + csv1cp = csv:parseStringToList(csvStringData1, {skipLines: [0], header: 1}); + test:assertEquals(csv1cp, [ + [1, "string1", true, 2.234, 2.234, ()], + [2, "string2", false, 0, 0, ()], + [3, "string3", false, 1.23, 1.23, ()], + [4, "string4", true, -6.51, -6.51, ()], + [5, "string5", true, 3, 3.0, ()] + ]); + + csv1cp = csv:parseStringToList(csvStringData1, {skipLines: [0, 4, 10], header: 1}); + test:assertEquals(csv1cp, [ + [1, "string1", true, 2.234, 2.234, ()], + [2, "string2", false, 0, 0, ()], + [3, "string3", false, 1.23, 1.23, ()], + [5, "string5", true, 3, 3.0, ()] + ]); + + csv1cp = csv:parseStringToList(csvStringData1, {skipLines: [1, 2, 3, 4, 5], header: 1}); + test:assertEquals(csv1cp, [ + ]); + + csv1cp = csv:parseStringToList(csvStringData1, {skipLines: "1-5", header: 1}); + test:assertEquals(csv1cp, [ + ]); + + csv1cp = csv:parseStringToList(csvStringData1, {skipLines: [4, 2], header: 1}); + test:assertEquals(csv1cp, [ + [1, "string1", true, 2.234, 2.234, ()], + [3, "string3", false, 1.23, 1.23, ()], + [5, "string5", true, 3, 3.0, ()] + ]); + + csv1cp = csv:parseStringToList(csvStringData1, {skipLines: "2-4", header: 1}); + test:assertEquals(csv1cp, [ + [1, "string1", true, 2.234, 2.234, ()], + [5, "string5", true, 3, 3.0, ()] + ]); + + csv1cp = csv:parseStringToList(csvStringData1, {skipLines: [4, 2, -1], header: 1}); + test:assertEquals(csv1cp, [ + [1, "string1", true, 2.234, 2.234, ()], + [3, "string3", false, 1.23, 1.23, ()], + [5, "string5", true, 3, 3.0, ()] + ]); + + csv1cp = csv:parseStringToList(csvStringData1, {skipLines: [4, -1, 2], header: 1}); + test:assertEquals(csv1cp, [ + [1, "string1", true, 2.234, 2.234, ()], + [3, "string3", false, 1.23, 1.23, ()], + [5, "string5", true, 3, 3.0, ()] + ]); + + csv1cp = csv:parseStringToList(csvStringData1, {skipLines: [5, 4, 3, 2, 1], header: 1}); + test:assertEquals(csv1cp, [ + ]); + + csv1cp = csv:parseStringToList(csvStringData1, {skipLines: [10], header: 1}); + test:assertEquals(csv1cp, [ + [1, "string1", true, 2.234, 2.234, ()], + [2, "string2", false, 0, 0, ()], + [3, "string3", false, 1.23, 1.23, ()], + [4, "string4", true, -6.51, -6.51, ()], + [5, "string5", true, 3, 3.0, ()] + ]); + + csv1cp = csv:parseStringToList(csvStringData1, {skipLines: [-2], header: 1}); + test:assertEquals(csv1cp, [ + [1, "string1", true, 2.234, 2.234, ()], + [2, "string2", false, 0, 0, ()], + [3, "string3", false, 1.23, 1.23, ()], + [4, "string4", true, -6.51, -6.51, ()], + [5, "string5", true, 3, 3.0, ()] + ]); + + csv1cp = csv:parseStringToList(csvStringData1, {skipLines: [-2, 0, 2], header: 1}); + test:assertEquals(csv1cp, [ + [1, "string1", true, 2.234, 2.234, ()], + [3, "string3", false, 1.23, 1.23, ()], + [4, "string4", true, -6.51, -6.51, ()], + [5, "string5", true, 3, 3.0, ()] + ]); + + csv1cp = csv:parseStringToList(csvStringData1, {skipLines: "0-2", header: 1}); + test:assertEquals(csv1cp, [ + [3, "string3", false, 1.23, 1.23, ()], + [4, "string4", true, -6.51, -6.51, ()], + [5, "string5", true, 3, 3.0, ()] + ]); +} + +@test:Config +function testCustomHeaderOption() { + anydata[][]|csv:Error bm1ba = csv:parseRecordAsListType([bm1, bm1], ["b1", "b2"], {}); + test:assertEquals(bm1ba, [ + [true, false], + [true, false] + ]); + + anydata[][]|csv:Error bm1ba2 = csv:parseRecordAsListType([bm1, bm1], ["b2", "b1"], {}); + test:assertEquals(bm1ba2, [ + [false, true], + [false, true] + ]); + + anydata[][]|csv:Error bm2ba = csv:parseRecordAsListType([bm2, bm2], ["b1", "n1", "b2", "n2", "b3"], {}); + test:assertTrue(bm2ba is csv:Error); + test:assertEquals((bm2ba).message(), common:generateErrorMessageForInvalidCustomHeader("n2")); + + anydata[][]|csv:Error bm3ba = csv:parseRecordAsListType([bm3, bm3], ["b1", "b4", "b2", "n2", "i1"], {}); + test:assertTrue(bm3ba is csv:Error); + test:assertEquals((bm3ba).message(), common:generateErrorMessageForInvalidCustomHeader("n2")); + + anydata[][]|csv:Error bm3ba2 = csv:parseRecordAsListType([bm3, bm3], ["b1", "b3", "b4", "b2", "i2"], {}); + test:assertTrue(bm3ba2 is csv:Error); + test:assertEquals((bm3ba2).message(), common:generateErrorMessageForInvalidCustomHeader("i2")); + + [boolean...][]|csv:Error bm3ba4 = csv:parseRecordAsListType([bm3, bm3], ["n2"], {}); + test:assertTrue(bm3ba4 is csv:Error); + test:assertEquals((bm3ba4).message(), "Invalid length for the header names"); + + [boolean...][]|csv:Error bm3ba5 = csv:parseRecordAsListType([bm3, bm3], [], {}); + test:assertTrue(bm3ba5 is csv:Error); + test:assertEquals((bm3ba5).message(), "Invalid length for the header names"); + + record {}[]|csv:Error ct1br = csv:parseListAsRecordType([["a", "1", "true"], ["a", "1", "true"]], ["a", "b"], {}); + test:assertTrue(ct1br is csv:Error); + test:assertEquals((ct1br).message(), "Invalid length for the custom headers"); + + record {}[]|csv:Error ct1br2 = csv:parseListAsRecordType([["a", "1", "true"], ["a", "1", "true"]], ["a", "b", "c", "d"], {}); + test:assertTrue(ct1br2 is csv:Error); + test:assertEquals((ct1br2).message(), "Invalid length for the custom headers"); + + record {}[]|csv:Error ct1br2_2 = csv:parseListAsRecordType([["a", "1", "true"], ["a", "1", "true"]], ["a", "c", "b", "d"], {}); + test:assertTrue(ct1br2_2 is csv:Error); + test:assertEquals((ct1br2_2).message(), "Invalid length for the custom headers"); + + record {}[]|csv:Error ct1br3 = csv:parseListAsRecordType([["a", "1", "true"], ["a", "1", "true"]], [], {}); + test:assertTrue(ct1br3 is csv:Error); + test:assertEquals((ct1br3).message(), "Invalid length for the custom headers"); + + record {|string a; string b; string c;|}[]|csv:Error ct1br5 = csv:parseListAsRecordType([["a", "1", "true"], ["a", "1", "true"]], ["a", "e", "b"], {}); + test:assertTrue(ct1br5 is csv:Error); + // TODO: Fix the error message + test:assertEquals((ct1br5).message(), common:generateErrorMessageForMissingRequiredField("c")); + + record {string a; string b; string c;}[]|csv:Error ct1br6 = csv:parseListAsRecordType([["a", "1", "true"], ["a", "1", "true"]], ["a", "e", "b"], {}); + test:assertTrue(ct1br6 is csv:Error); + test:assertEquals((ct1br6).message(), common:generateErrorMessageForMissingRequiredField("c")); + + record {string a; string b;}[]|csv:Error ct1br7 = csv:parseListAsRecordType([["a", "1", "true"], ["a", "1", "true"]], ["a", "e", "b"], { + stringConversion: false + }); + test:assertEquals(ct1br7, [ + {a: "a", e: "1", b: "true"}, + {a: "a", e: "1", b: "true"} + ]); + + record {|string a; string b;|}[]|csv:Error ct1br8 = csv:parseListAsRecordType([["a", "1", "true"], ["a", "1", "true"]], ["a", "e", "b"], { + stringConversion: false + }); + test:assertEquals(ct1br8, [ + {a: "a", b: "true"}, + {a: "a", b: "true"} + ]); + + record {|string...;|}[]|csv:Error ct1br9 = csv:parseListAsRecordType([["a", "1", "true"], ["a", "1", "true"]], ["a", "e", "b"], { + stringConversion: false + }); + test:assertEquals(ct1br9, [ + {a: "a", b: "true", e: "1"}, + {a: "a", b: "true", e: "1"} + ]); + + record {|string...;|}[]|csv:Error ct1br10 = csv:parseListAsRecordType([["a", "1", "true"], ["a", "1", "true"]], (), { + stringConversion: false + }); + test:assertEquals(ct1br10, [ + {'1: "a", '3: "true", '2: "1"}, + {'1: "a", '3: "true", '2: "1"} + ]); +} + +@test:Config +function testCustomHeaderParserOption2() { + record {}[]|csv:Error ct1br = csv:parseStringToRecord(csvStringData1, {header: 1, customHeaders: ["a", "b"]}); + test:assertTrue(ct1br is csv:Error); + test:assertEquals((ct1br).message(), "Invalid length for the custom headers"); + + record {}[]|csv:Error ct1br2 = csv:parseStringToRecord(csvStringData1, {header: 1, customHeaders: []}); + test:assertTrue(ct1br2 is csv:Error); + test:assertEquals((ct1br2).message(), "Invalid length for the custom headers"); + + record {int a; string b; boolean c; decimal d; float e; () f;}[]|csv:Error ct1br3 = csv:parseStringToRecord(csvStringData1, {header: 1, customHeaders: ["a", "b"]}); + test:assertTrue(ct1br3 is csv:Error); + test:assertEquals((ct1br3).message(), "Invalid length for the custom headers"); + + record {int a; string b; boolean c; decimal d; float e; () f;}[]|csv:Error ct1br4 = csv:parseStringToRecord(csvStringData1, {header: 1, customHeaders: ["a", "b", "c", "d", "e", "f"]}); + test:assertEquals(ct1br4, [ + {a: 1, b: "string1", c: true, d: 2.234, e: 2.234, f: ()}, + {a: 2, b: "string2", c: false, d: 0, e: 0, f: ()}, + {a: 3, b: "string3", c: false, d: 1.23, e: 1.23, f: ()}, + {a: 4, b: "string4", c: true, d: -6.51, e: -6.51, f: ()}, + {a: 5, b: "string5", c: true, d: 3, e: 3, f: ()} + ]); + + record {() a; float b; decimal c; boolean d; string e; int f;}[]|csv:Error ct1br5 = csv:parseStringToRecord(csvStringData1, {header: 1, customHeaders: ["f", "e", "d", "c", "b", "a"]}); + test:assertEquals(ct1br5, [ + {f: 1, e: "string1", d: true, c: 2.234, b: 2.234, a: ()}, + {f: 2, e: "string2", d: false, c: 0, b: 0, a: ()}, + {f: 3, e: "string3", d: false, c: 1.23, b: 1.23, a: ()}, + {f: 4, e: "string4", d: true, c: -6.51, b: -6.51, a: ()}, + {f: 5, e: "string5", d: true, c: 3, b: 3, a: ()} + ]); + + record {() a; float b; decimal c; boolean d; string e; int f;}[]|csv:Error ct1br5_2 = csv:parseStringToRecord(csvStringData1, {header: false, skipLines: [1], customHeaders: ["f", "e", "d", "c", "b", "a"]}); + test:assertEquals(ct1br5_2, [ + {f: 1, e: "string1", d: true, c: 2.234, b: 2.234, a: ()}, + {f: 2, e: "string2", d: false, c: 0, b: 0, a: ()}, + {f: 3, e: "string3", d: false, c: 1.23, b: 1.23, a: ()}, + {f: 4, e: "string4", d: true, c: -6.51, b: -6.51, a: ()}, + {f: 5, e: "string5", d: true, c: 3, b: 3, a: ()} + ]); + + record {() a; float b; decimal c; boolean d; string e; int f;}[]|csv:Error ct1br5_3 = csv:parseStringToRecord(csvStringData1, {skipLines: [1], customHeaders: ["f", "e", "d", "c", "b", "a"]}); + test:assertEquals(ct1br5_3, [ + {f: 1, e: "string1", d: true, c: 2.234, b: 2.234, a: ()}, + {f: 2, e: "string2", d: false, c: 0, b: 0, a: ()}, + {f: 3, e: "string3", d: false, c: 1.23, b: 1.23, a: ()}, + {f: 4, e: "string4", d: true, c: -6.51, b: -6.51, a: ()}, + {f: 5, e: "string5", d: true, c: 3, b: 3, a: ()} + ]); + + record {|() a1; float b1; decimal c1; boolean d1; string e1; int f1;|}[]|csv:Error ct1br6 = csv:parseStringToRecord(csvStringData1, {header: 1, customHeaders: ["f1", "e1", "d1", "c1", "b1", "a1"]}); + test:assertEquals(ct1br6, [ + {f1: 1, e1: "string1", d1: true, c1: 2.234, b1: 2.234, a1: ()}, + {f1: 2, e1: "string2", d1: false, c1: 0, b1: 0, a1: ()}, + {f1: 3, e1: "string3", d1: false, c1: 1.23, b1: 1.23, a1: ()}, + {f1: 4, e1: "string4", d1: true, c1: -6.51, b1: -6.51, a1: ()}, + {f1: 5, e1: "string5", d1: true, c1: 3, b1: 3, a1: ()} + ]); + + record {|boolean d1; string e1;|}[]|csv:Error ct1br7 = csv:parseStringToRecord(csvStringData1, {header: 1, customHeaders: ["f1", "e1", "d1", "c1", "b1", "a1"]}); + test:assertEquals(ct1br7, [ + {e1: "string1", d1: true}, + {e1: "string2", d1: false}, + {e1: "string3", d1: false}, + {e1: "string4", d1: true}, + {e1: "string5", d1: true} + ]); + + record {|boolean d1; string e1;|}[]|csv:Error ct1br7_2 = csv:parseStringToRecord(csvStringData1, {header: false, skipLines: [1], customHeaders: ["f1", "e1", "d1", "c1", "b1", "a1"]}); + test:assertEquals(ct1br7_2, [ + {e1: "string1", d1: true}, + {e1: "string2", d1: false}, + {e1: "string3", d1: false}, + {e1: "string4", d1: true}, + {e1: "string5", d1: true} + ]); + + record {|boolean d1; string e1;|}[]|csv:Error ct1br8 = csv:parseStringToRecord(csvStringData1, {header: 1, customHeaders: ["e1", "d1"]}); + test:assertTrue(ct1br8 is csv:Error); + test:assertEquals((ct1br8).message(), common:generateErrorMessageForInvalidCast("string1", "boolean")); + + record {|boolean d1; string e1;|}[]|csv:Error ct1br9 = csv:parseStringToRecord(csvStringData1, {header: 1, customHeaders: ["f1", "e1", "d1", "c1", "b1", "a1"]}); + test:assertEquals(ct1br9, [ + {e1: "string1", d1: true}, + {e1: "string2", d1: false}, + {e1: "string3", d1: false}, + {e1: "string4", d1: true}, + {e1: "string5", d1: true} + ]); + + record {|boolean d1; string e1;|}[]|csv:Error ct1br10 = csv:parseStringToRecord(csvStringData1, {header: 1, customHeaders: ["f1", "e1", "d1", "f1", "b1", "a1"]}); + test:assertEquals(ct1br10, [ + {e1: "string1", d1: true}, + {e1: "string2", d1: false}, + {e1: "string3", d1: false}, + {e1: "string4", d1: true}, + {e1: "string5", d1: true} + ]); + + record {|boolean d1; string e1;|}[]|csv:Error ct1br11 = csv:parseStringToRecord(csvStringData1, {header: 1, customHeaders: ["f1", "e1"]}); + test:assertTrue(ct1br11 is csv:Error); + test:assertEquals((ct1br11).message(), "Invalid length for the custom headers"); + + record {|string d1; string e1;|}[]|csv:Error ct1br12 = csv:parseStringToRecord(csvStringData1, {header: 1, customHeaders: ["f1", "e1", "d1", "c1", "b1", "a1"]}); + test:assertEquals(ct1br12, [ + {e1: "string1", d1: "true"}, + {e1: "string2", d1: "false"}, + {e1: "string3", d1: "false"}, + {e1: "string4", d1: "true"}, + {e1: "string5", d1: "true"} + ]); + + record {|string d1; string e1;|}[]|csv:Error ct1br13 = csv:parseStringToRecord(csvStringData1, {header: 1, customHeaders: ["f1", "e1", "dd1", "c1", "b1", "a1"]}); + test:assertTrue(ct1br13 is csv:Error); + test:assertEquals((ct1br13).message(), common:generateErrorMessageForMissingRequiredField("d1")); +} + +@test:Config +function testTextQuotesWithParserOptions() { + string csvValue1 = string ` + a, b, c + 1, "2", "3" + "1", 2, 3 + 1, "2", 3 + + "1", "2", "3"`; + + string csvValue2 = string ` + a, b, c + 1, "2, 3", 3 + 1, "2, 3",3 + 4, 5, 6 + `; + + string csvValue3 = string `a, b, c + "1", ""2"", "3" + 4, "5, 6"b" " a "", ""6""`; + + string csvValue4 = string `a, b, c + 1, '2', 3 + 4, '5, '6'7', 8 + 4, "5", '4, '5"a", ,"," a '6'7'`; + + string csvValue5 = string `a, b, c + 1, "2", "3" + 1, 2, 3 + "1", "2", 3 + 1, "2", "3" + `; + + string csvValue6 = string `a, b, c + 1, "2 a ","", "3" + 1, 2, 3 + "1", "2", 3 + 1, "2", "3" + `; + + record {int a;}[]|csv:Error cn = csv:parseStringToRecord(csvValue1, {header: 1}); + test:assertEquals(cn, [{"a": 1, "b": 2, "c": 3}, {"a": 1, "b": 2, "c": 3}, {"a": 1, "b": 2, "c": 3}, {"a": 1, "b": 2, "c": 3}]); + + record {|int c; string...;|}[]|csv:Error cn2 = csv:parseStringToRecord(csvValue2, {header: 1}); + test:assertEquals(cn2, [{"a": "1", "b": "2, 3", "c": 3}, {"a": "1", "b": "2, 3", "c": 3}, {"a": "4", "b": "5", "c": 6}]); + + record {|string b; string c;|}[]|csv:Error cn3 = csv:parseStringToRecord(csvValue3, {}); + test:assertEquals(cn3, [{"b": "\"2\"", "c": "3"}, {"b": "5, 6\"b\" \" a \"", c: "\"6\""}]); + + record {}[]|csv:Error cn4 = csv:parseStringToRecord(csvValue4, {textEnclosure: "'"}); + test:assertEquals(cn4, [{"a": 1, "b": 2, "c": 3}, {"a": 4, b: "5, '6'7", c: 8}, {a: 4, b: "\"5\"", c: "4, '5\"a\", ,\",\" a '6'7"}]); + + anydata[][]|csv:Error cn4_2 = csv:parseStringToList(csvValue4, {textEnclosure: "'"}); + test:assertEquals(cn4_2, [[1, 2, 3], [4, "5, '6'7", 8], [4, "\"5\"", "4, '5\"a\", ,\",\" a '6'7"]]); + + record {}[]|csv:Error cn5 = csv:parseStringToRecord(csvValue5, {}); + test:assertEquals(cn5, [{a: 1, b: 2, c: 3}, {a: 1, b: 2, c: 3}, {a: 1, b: 2, c: 3}, {a: 1, b: 2, c: 3}]); + + record {}[]|csv:Error cn6 = csv:parseStringToRecord(csvValue6, {}); + test:assertTrue(cn6 is csv:Error); + test:assertEquals((cn6).message(), "Invalid length for the custom headers"); +} + +@test:Config +function testHeaderQuotesWithParserOptions() { + string csvValue1 = string ` + "a", b, c + 1, "2", "3" + "1", 2, 3 + 1, "2", 3 + + "1", "2", "3"`; + + string csvValue2 = string ` + "a, b, c", "b,c", "c,d" + 1, "2, 3", 3 + 1, "2, 3",3 + 4, 5, 6 + `; + + string csvValue3 = string `'a '1'a5,6', 'b", " ","""', c + 1, '2', 3 + 4, '5, '6'7', 8 + 4, "5", '4, '5"a", ,"," a '6'7'`; + + record {}[]|csv:Error cn = csv:parseStringToRecord(csvValue1, {header: 1}); + test:assertEquals(cn, [{"a": 1, "b": 2, "c": 3}, {"a": 1, "b": 2, "c": 3}, {"a": 1, "b": 2, "c": 3}, {"a": 1, "b": 2, "c": 3}]); + + record {}[]|csv:Error cn2 = csv:parseStringToRecord(csvValue2, {header: 1}); + test:assertEquals(cn2, [{"a, b, c": 1, "b,c": "2, 3", "c,d": 3}, {"a, b, c": 1, "b,c": "2, 3", "c,d": 3}, {"a, b, c": 4, "b,c": 5, "c,d": 6}]); + + anydata[][]|csv:Error cn2_2 = csv:parseStringToList(csvValue2, {header: 1}); + test:assertEquals(cn2_2, [[1, "2, 3", 3], [1, "2, 3", 3], [4, 5, 6]]); + + record {}[]|csv:Error cn3 = csv:parseStringToRecord(csvValue3, {textEnclosure: "'"}); + test:assertEquals(cn3, [{"a '1'a5,6": 1, "b\", \" \",\"\"\"": 2, "c": 3}, {"a '1'a5,6": 4, "b\", \" \",\"\"\"": "5, '6'7", c: 8}, {"a '1'a5,6": 4, "b\", \" \",\"\"\"": "\"5\"", c: "4, '5\"a\", ,\",\" a '6'7"}]); +} + +@test:Config +function testEscapeCharactersWithParserOptions() { + string csvValue1 = string ` + "a", b, c + 1, "2a\t", "3b\n" + "1c\n", 2, 3 + 1, "2a\"", 3 + + "1a\\", "2b\\"", "3"`; + + string csvValue2 = string ` + "a\"", "\tb\t\n", c + 1, "2a\t", "3b\n" + "1c\n", "/2/", 3 + 1, "2a\"", "3" + + "1a\\", "2b\\"", "3"`; + + string csvValue3 = string ` + "a", b, c + 1, "2\t", "3\n" + "1\n", 2, 3 + 1, "2\"", 3 + + "1\\", "2\\"", "3"`; + + record {}[]|csv:Error cn = csv:parseStringToRecord(csvValue1, {header: 1}); + test:assertEquals(cn, [{"a": 1, "b": "2a\t", "c": "3b\n"}, {"a": "1c\n", "b": 2, "c": 3}, {"a": 1, "b": "2a\"", "c": 3}, {"a": "1a\\", "b": "2b\\\"", "c": 3}]); + + record {}[]|csv:Error cn2 = csv:parseStringToRecord(csvValue2, {header: 1}); + test:assertEquals(cn2, [{"a\"": 1, "\tb\t\n": "2a\t", "c": "3b\n"}, {"a\"": "1c\n", "\tb\t\n": "/2/", "c": 3}, {"a\"": 1, "\tb\t\n": "2a\"", "c": 3}, {"a\"": "1a\\", "\tb\t\n": "2b\\\"", "c": 3}]); + + record {}[]|csv:Error cn3 = csv:parseStringToRecord(csvValue3, {header: 1}); + test:assertEquals(cn3, [{"a": 1, "b": 2.0, "c": 3.0}, {"a": 1.0, "b": 2, "c": 3}, {"a": 1, "b": "2\"", "c": 3}, {"a": "1\\", "b": "2\\\"", "c": 3}]); + + anydata[][]|csv:Error cn_2 = csv:parseStringToList(csvValue1, {header: 1}); + test:assertEquals(cn_2, [[1, "2a\t", "3b\n"], ["1c\n", 2, 3], [1, "2a\"", 3], ["1a\\", "2b\\\"", 3]]); + + anydata[][]|csv:Error cn2_2 = csv:parseStringToList(csvValue2, {header: 1}); + test:assertEquals(cn2_2, [[1, "2a\t", "3b\n"], ["1c\n", "/2/", 3], [1, "2a\"", 3], ["1a\\", "2b\\\"", 3]]); + + anydata[][]|csv:Error cn3_2 = csv:parseStringToList(csvValue3, {header: 1}); + test:assertEquals(cn3_2, [[1, 2.0, 3.0], [1.0, 2, 3], [1, "2\"", 3], ["1\\", "2\\\"", 3]]); +} + +@test:Config +function testDelimiterWithParserOptions() { + record {}[]|csv:Error cn = csv:parseStringToRecord(csvStringData7, {header: 1, delimiter: "@"}); + test:assertEquals(cn, [ + {a: 1, b: "string", c: true, d: 2.234, e: -3.21, f: ()}, + {a: 2, b: "s,tring", c: true, d: 2.234, e: -3.21, f: ()}, + {a: 3, b: "stri,ng", c: true, d: 2.234, e: -3.21, f: ()}, + {a: 4, b: "string", c: true, d: 2.234, e: -3.21, f: ()}, + {a: 5, b: "string", c: true, d: 2.234, e: -3.21, f: ()} + ]); + + anydata[][]|csv:Error cn2 = csv:parseStringToList(csvStringData7, {header: 1, delimiter: "@"}); + test:assertEquals(cn2, [ + [1, "string", true, 2.234, -3.21, ()], + [2, "s,tring", true, 2.234, -3.21, ()], + [3, "stri,ng", true, 2.234, -3.21, ()], + [4, "string", true, 2.234, -3.21, ()], + [5, "string", true, 2.234, -3.21, ()] + ]); +} + +@test:Config +function testLineTerminatorWithParserOptions() { + string csvValue = string `a,b + 1,"2\n3"`; + + record {}[]|csv:Error cn = csv:parseStringToRecord(csvValue, {header: 0, lineTerminator: [csv:CRLF, csv:LF]}); + test:assertEquals(cn, [{a: 1, b: "2\n3"}]); + + cn = csv:parseStringToRecord(csvValue, {header: 0, lineTerminator: [csv:CRLF, csv:LF]}); + test:assertEquals(cn, [{a: 1, b: "2\n3"}]); + + cn = csv:parseStringToRecord(csvValue, {header: 0, lineTerminator: [csv:CRLF, csv:LF]}); + test:assertEquals(cn, [{a: 1, b: "2\n3"}]); + + anydata[][]|csv:Error cn2 = csv:parseStringToList(csvValue, {header: 0, lineTerminator: [csv:CRLF, csv:LF]}); + test:assertEquals(cn2, [[1, "2\n3"]]); + + cn2 = csv:parseStringToList(csvValue, {header: 0, lineTerminator: [csv:CRLF, csv:LF]}); + test:assertEquals(cn2, [[1, "2\n3"]]); + + cn2 = csv:parseStringToList(csvValue, {header: 0, lineTerminator: [csv:CRLF, csv:LF]}); + test:assertEquals(cn2, [[1, "2\n3"]]); +} diff --git a/ballerina-tests/user-config-tests/tests/user_configs.bal b/ballerina-tests/user-config-tests/tests/user_configs.bal new file mode 100644 index 0000000..8e85183 --- /dev/null +++ b/ballerina-tests/user-config-tests/tests/user_configs.bal @@ -0,0 +1,29 @@ +import ballerina/data.csv as csv; + +// Valid parser options +csv:ParseOption option1 = {delimiter: "@", nilValue: "null", lineTerminator: [csv:LF]}; +csv:ParseOption option2 = {nilValue: "N/A", lineTerminator: [csv:CRLF, csv:LF], comment: "/"}; +csv:ParseOption option3 = {nilValue: "()", header: 1, skipLines: [1, 2]}; +csv:ParseOption option4 = {nilValue: "", header: 4, skipLines: "1-5"}; +csv:ParseOption option5 = {nilValue: "", header: 4, skipLines: "1-1"}; +csv:ParseOption option6 = {nilValue: "()", header: false, skipLines: [1, 2]}; + +csv:parseToRecordOption ptOption1 = {nilValue: "", header: 1, skipLines: [2, 4]}; +csv:parseToRecordOption ptOption2 = {nilValue: "", header: 1, skipLines: "2-4"}; +csv:parseToRecordOption ptOption3 = {nilValue: "", header: 4, skipLines: "1-5"}; +csv:parseToRecordOption ptOption4 = {nilValue: "", header: 4, skipLines: [-1, -2, 4, 2]}; +csv:parseToRecordOption ptOption5 = {header: false, skipLines: [-1, -2, 5, 3]}; + +// Invalid parser options +csv:ParseOption invalidParserOptions1 = {header: 4}; +csv:ParseOption invalidParserOptions2 = {comment: "$"}; +csv:ParseOption invalidParserOptions3 = {lineTerminator: csv:CRLF}; +csv:ParseOption invalidParserOptions4 = {skipLines: [1000, 1001]}; +csv:ParseOption invalidParserOptions5 = {skipLines: "a-b"}; +csv:ParseOption invalidParserOptions6 = {skipLines: "3-1"}; +csv:ParseOption invalidParserOptions7 = {skipLines: "a-5"}; +csv:ParseOption invalidParserOptions8 = {skipLines: "6-a"}; +csv:ParseOption invalidParserOptions9 = {skipLines: "a-5"}; +csv:ParseOption invalidParserOptions10 = {skipLines: "-1-6"}; +csv:ParseOption invalidParserOptions11 = {nilValue: "", header: 4, skipLines: "0-10"}; +csv:ParseOption invalidParserOptions12 = {skipLines: [1, 3, 4, -1]}; diff --git a/ballerina/Ballerina.toml b/ballerina/Ballerina.toml index ecae9dc..f1d6945 100644 --- a/ballerina/Ballerina.toml +++ b/ballerina/Ballerina.toml @@ -17,3 +17,9 @@ groupId = "io.ballerina.stdlib" artifactId = "data.csv-native" version = "0.1.0" path = "../native/build/libs/data.csv-native-0.1.0-SNAPSHOT.jar" + +[[platform.java17.dependency]] +groupId = "io.ballerina.stdlib" +artifactId = "constraint-native" +version = "1.5.0" +path = "./lib/constraint-native-1.5.0.jar" diff --git a/ballerina/Dependencies.toml b/ballerina/Dependencies.toml index c07b540..c995088 100644 --- a/ballerina/Dependencies.toml +++ b/ballerina/Dependencies.toml @@ -12,7 +12,8 @@ org = "ballerina" name = "data.csv" version = "0.1.0" dependencies = [ - {org = "ballerina", name = "jballerina.java"} + {org = "ballerina", name = "jballerina.java"}, + {org = "ballerina", name = "test"} ] modules = [ {org = "ballerina", packageName = "data.csv", moduleName = "data.csv"} @@ -26,3 +27,52 @@ modules = [ {org = "ballerina", packageName = "jballerina.java", moduleName = "jballerina.java"} ] +[[package]] +org = "ballerina" +name = "lang.__internal" +version = "0.0.0" +scope = "testOnly" +dependencies = [ + {org = "ballerina", name = "jballerina.java"}, + {org = "ballerina", name = "lang.object"} +] + +[[package]] +org = "ballerina" +name = "lang.array" +version = "0.0.0" +scope = "testOnly" +dependencies = [ + {org = "ballerina", name = "jballerina.java"}, + {org = "ballerina", name = "lang.__internal"} +] + +[[package]] +org = "ballerina" +name = "lang.error" +version = "0.0.0" +scope = "testOnly" +dependencies = [ + {org = "ballerina", name = "jballerina.java"} +] + +[[package]] +org = "ballerina" +name = "lang.object" +version = "0.0.0" +scope = "testOnly" + +[[package]] +org = "ballerina" +name = "test" +version = "0.0.0" +scope = "testOnly" +dependencies = [ + {org = "ballerina", name = "jballerina.java"}, + {org = "ballerina", name = "lang.array"}, + {org = "ballerina", name = "lang.error"} +] +modules = [ + {org = "ballerina", packageName = "test", moduleName = "test"} +] + diff --git a/ballerina/Package.md b/ballerina/Package.md index 7da4a1a..26878a7 100644 --- a/ballerina/Package.md +++ b/ballerina/Package.md @@ -1 +1 @@ -# Ballerina CSV Data module \ No newline at end of file +# Ballerina CSV Data module diff --git a/ballerina/build.gradle b/ballerina/build.gradle index 4c5f9c3..7a1da6b 100644 --- a/ballerina/build.gradle +++ b/ballerina/build.gradle @@ -82,6 +82,8 @@ task updateTomlFiles { def stdlibDependentConstraintVersion = stripBallerinaExtensionVersion("${stdlibDependentConstraintNativeVersion}") def newConfig = ballerinaTomlFilePlaceHolder.text.replace("@project.version@", project.version) newConfig = newConfig.replace("@toml.version@", tomlVersion) + newConfig = newConfig.replace("@stdlib.constraintnative.version@", stdlibDependentConstraintNativeVersion) + newConfig = newConfig.replace("@constraint.version@", stdlibDependentConstraintVersion) ballerinaTomlFile.text = newConfig def newCompilerPluginToml = compilerPluginTomlFilePlaceHolder.text.replace("@project.version@", project.version) @@ -135,10 +137,14 @@ build.dependsOn ":${packageName}-native:build" build.dependsOn deleteDependencyTomlFiles build.dependsOn ":${packageName}-compiler-plugin:build" build.dependsOn deleteDependencyTomlFiles +build.finalizedBy ":${packageName}-ballerina-tests:build" + +//build.finalizedBy ":${packageName}-ballerina-tests:ballerinaTest" test.dependsOn ":${packageName}-native:build" test.dependsOn ":${packageName}-native:build" test.dependsOn ":${packageName}-compiler-plugin:build" +test.finalizedBy ":${packageName}-ballerina-tests:build" publish.dependsOn build publishToMavenLocal.dependsOn build diff --git a/ballerina/types.bal b/ballerina/types.bal index 11b0c38..1bee776 100644 --- a/ballerina/types.bal +++ b/ballerina/types.bal @@ -1,3 +1,7 @@ +# Represents an error. +# +# This type is used to capture error details that occur during the execution of a program. +# It can hold an error message, an optional error cause, and an optional map of additional details. public type Error error; # Defines the name of the JSON Object key. @@ -10,61 +14,87 @@ public type NameConfig record {| # The annotation is used to overwrite the existing record field name. public const annotation NameConfig Name on record field; +# Represents options for data projection. public type Options record { + # Allows data projection with specific settings. + # + # This field can be either a record or a boolean. If it's a record, it contains the following fields: + # - `nilAsOptionalField`: If `true`, nil values will be considered as optional fields in the projection. + # - `absentAsNilableType`: If `true`, absent fields will be considered as nilable types in the projection. + # If it's set to `false`, data projection is not allowed. record { # If `true`, nil values will be considered as optional fields in the projection. - boolean nilAsOptionalField = false; // () assign to op + boolean nilAsOptionalField = false; # If `true`, absent fields will be considered as nilable types in the projection. - boolean absentAsNilableType = false; // source haven't () && expected type contains op => () + boolean absentAsNilableType = false; }|false allowDataProjection = {}; + + # Lines to skip during processing, specified either as an array of integers or a string. int[]|string skipLines = []; }; +# Represents the options for parsing data. public type ParseOption record {| *Options; + # The delimiter character used for separating fields in the data. string:Char delimiter = ","; + # The character encoding of the data. string encoding = "UTF-8"; + # The locale used for parsing. string locale = "en_US"; -// TODO: Add " for Strings" + # The character used to enclose text fields. string:Char textEnclosure = "\""; + # The character used for escaping. string:Char escapeChar = "\\"; - LineTerminator|LineTerminator[] lineTerminator = [CR, LF, CRLF]; + # The line terminator(s) used in the data. + LineTerminator|LineTerminator[] lineTerminator = [LF, CRLF]; + # The value to represent nil. NilValue? nilValue = (); - // string commentStartingSequence = "#"; + # The character used to indicate comments in the data. string:Char comment = "#"; + # Specifies whether the header is present and, if so, the number of header lines. false|int:Unsigned32 header = 0; |}; +# Represents options for parsing data into records. public type parseToRecordOption record {| *ParseOption; - - // if header = false and this value is null, Then compiler time error. + # Custom headers for the data, if any. string[]? customHeaders = (); + # If `true`, enables validation of constraints during parsing. boolean enableConstraintValidation = true; |}; +# Represents options for treating a list as a list. public type ListAsListOption record {| *Options; + # If `true`, enables conversion of strings during processing. boolean stringConversion = true; |}; +# Represents options for treating a record as a record. public type RecordAsRecordOption record {| *Options; - boolean enableConstraintValidation = true; + # If `true`, enables validation of constraints during processing. + boolean enableConstraintValidation = true; |}; +# Represents options for treating a list as a record. public type ListAsRecordOption record {| *Options; + # If `true`, enables validation of constraints during processing. boolean enableConstraintValidation = true; + # If `true`, enables conversion of strings during processing. boolean stringConversion = true; |}; +# Enum representing possible line terminators. public enum LineTerminator { - CR = "\r", LF = "\n", CRLF = "\r\n" }; +# Enum representing possible nil values. public enum NilValue { NULL = "null", EMPTY_STRING = "", diff --git a/build-config/resources/Ballerina.toml b/build-config/resources/Ballerina.toml index 3db6b47..ea02379 100644 --- a/build-config/resources/Ballerina.toml +++ b/build-config/resources/Ballerina.toml @@ -17,3 +17,9 @@ groupId = "io.ballerina.stdlib" artifactId = "data.csv-native" version = "@toml.version@" path = "../native/build/libs/data.csv-native-@project.version@.jar" + +[[platform.java17.dependency]] +groupId = "io.ballerina.stdlib" +artifactId = "constraint-native" +version = "@constraint.version@" +path = "./lib/constraint-native-@stdlib.constraintnative.version@.jar" diff --git a/build-config/resources/BallerinaTest.toml b/build-config/resources/BallerinaTest.toml new file mode 100644 index 0000000..05b0322 --- /dev/null +++ b/build-config/resources/BallerinaTest.toml @@ -0,0 +1,13 @@ +[package] +org = "ballerina" +name = "@package.name@" +version = "@toml.version@" + +[[dependency]] +org = "ballerina" +name = "@test.common@" +repository = "local" +version = "@toml.version@" + +[platform.java17] +graalvmCompatible = true diff --git a/build-config/resources/CsvTestCommon.toml b/build-config/resources/CsvTestCommon.toml new file mode 100644 index 0000000..91de9a7 --- /dev/null +++ b/build-config/resources/CsvTestCommon.toml @@ -0,0 +1,4 @@ +[package] +org = "ballerina" +name = "@package.name@" +version = "@toml.version@" diff --git a/compiler-plugin-test/src/test/java/io/ballerina/lib/data/csvdata/compiler/CompilerPluginTest.java b/compiler-plugin-test/src/test/java/io/ballerina/lib/data/csvdata/compiler/CompilerPluginTest.java index 69c212b..5d1bd17 100644 --- a/compiler-plugin-test/src/test/java/io/ballerina/lib/data/csvdata/compiler/CompilerPluginTest.java +++ b/compiler-plugin-test/src/test/java/io/ballerina/lib/data/csvdata/compiler/CompilerPluginTest.java @@ -18,9 +18,51 @@ package io.ballerina.lib.data.csvdata.compiler; +import io.ballerina.projects.DiagnosticResult; +import io.ballerina.tools.diagnostics.Diagnostic; +import io.ballerina.tools.diagnostics.DiagnosticSeverity; +import org.testng.Assert; +import org.testng.annotations.Test; + +import java.util.List; +import java.util.stream.Collectors; + /** * This class includes tests for Ballerina Csv Data compiler plugin. */ public class CompilerPluginTest { + static final String UNSUPPORTED_TYPE = "unsupported type: type is not supported"; + static final String DUPLICATE_FIELD = "invalid field: duplicate field found"; + + @Test + public void testInvalidExpectedUnionType() { + DiagnosticResult diagnosticResult = + CompilerPluginTestUtils.loadPackage("sample_package_1").getCompilation().diagnosticResult(); + List errorDiagnosticsList = diagnosticResult.diagnostics().stream() + .filter(r -> r.diagnosticInfo().severity().equals(DiagnosticSeverity.ERROR)) + .collect(Collectors.toList()); + Assert.assertEquals(errorDiagnosticsList.size(), 10); + Assert.assertEquals(errorDiagnosticsList.get(0).diagnosticInfo().messageFormat(), UNSUPPORTED_TYPE); + Assert.assertEquals(errorDiagnosticsList.get(1).diagnosticInfo().messageFormat(), UNSUPPORTED_TYPE); + Assert.assertEquals(errorDiagnosticsList.get(2).diagnosticInfo().messageFormat(), UNSUPPORTED_TYPE); + Assert.assertEquals(errorDiagnosticsList.get(3).diagnosticInfo().messageFormat(), UNSUPPORTED_TYPE); + Assert.assertEquals(errorDiagnosticsList.get(4).diagnosticInfo().messageFormat(), UNSUPPORTED_TYPE); + Assert.assertEquals(errorDiagnosticsList.get(5).diagnosticInfo().messageFormat(), UNSUPPORTED_TYPE); + Assert.assertEquals(errorDiagnosticsList.get(6).diagnosticInfo().messageFormat(), UNSUPPORTED_TYPE); + Assert.assertEquals(errorDiagnosticsList.get(7).diagnosticInfo().messageFormat(), UNSUPPORTED_TYPE); + Assert.assertEquals(errorDiagnosticsList.get(8).diagnosticInfo().messageFormat(), UNSUPPORTED_TYPE); + Assert.assertEquals(errorDiagnosticsList.get(9).diagnosticInfo().messageFormat(), UNSUPPORTED_TYPE); + } + + @Test + public void testInvalidRecordFields() { + DiagnosticResult diagnosticResult = + CompilerPluginTestUtils.loadPackage("sample_package_2").getCompilation().diagnosticResult(); + List errorDiagnosticsList = diagnosticResult.diagnostics().stream() + .filter(r -> r.diagnosticInfo().severity().equals(DiagnosticSeverity.ERROR)) + .collect(Collectors.toList()); + Assert.assertEquals(errorDiagnosticsList.size(), 1); + Assert.assertEquals(errorDiagnosticsList.get(0).diagnosticInfo().messageFormat(), DUPLICATE_FIELD); + } } diff --git a/compiler-plugin-test/src/test/java/io/ballerina/lib/data/csvdata/compiler/CompilerPluginTestUtils.java b/compiler-plugin-test/src/test/java/io/ballerina/lib/data/csvdata/compiler/CompilerPluginTestUtils.java new file mode 100644 index 0000000..13c34d1 --- /dev/null +++ b/compiler-plugin-test/src/test/java/io/ballerina/lib/data/csvdata/compiler/CompilerPluginTestUtils.java @@ -0,0 +1,46 @@ +/* + * Copyright (c) 2024, WSO2 LLC. (https://www.wso2.com). + * + * 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 + * + * 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 io.ballerina.lib.data.csvdata.compiler; + +import io.ballerina.projects.Package; +import io.ballerina.projects.ProjectEnvironmentBuilder; +import io.ballerina.projects.directory.BuildProject; +import io.ballerina.projects.environment.Environment; +import io.ballerina.projects.environment.EnvironmentBuilder; + +import java.nio.file.Path; +import java.nio.file.Paths; + +/** + * Utility functions related to compiler plugins tests. + */ +public class CompilerPluginTestUtils { + private static final Path RESOURCE_DIRECTORY = Paths.get("src", "test", "resources", "ballerina_sources") + .toAbsolutePath(); + private static final Path DISTRIBUTION_PATH = Paths.get("../", "target", "ballerina-runtime") + .toAbsolutePath(); + + static Package loadPackage(String path) { + Path projectDirPath = RESOURCE_DIRECTORY.resolve(path); + Environment environment = EnvironmentBuilder.getBuilder().setBallerinaHome(DISTRIBUTION_PATH).build(); + ProjectEnvironmentBuilder projectEnvironmentBuilder = ProjectEnvironmentBuilder.getBuilder(environment); + BuildProject project = BuildProject.load(projectEnvironmentBuilder, projectDirPath); + return project.currentPackage(); + } +} diff --git a/compiler-plugin-test/src/test/resources/ballerina_sources/sample_package_1/Ballerina.toml b/compiler-plugin-test/src/test/resources/ballerina_sources/sample_package_1/Ballerina.toml new file mode 100644 index 0000000..437bf7b --- /dev/null +++ b/compiler-plugin-test/src/test/resources/ballerina_sources/sample_package_1/Ballerina.toml @@ -0,0 +1,6 @@ +[package] +org = "admin" +name = "sample_package_1" +version = "0.1.0" +distribution = "2201.9.0" + diff --git a/compiler-plugin-test/src/test/resources/ballerina_sources/sample_package_1/main.bal b/compiler-plugin-test/src/test/resources/ballerina_sources/sample_package_1/main.bal new file mode 100644 index 0000000..9483153 --- /dev/null +++ b/compiler-plugin-test/src/test/resources/ballerina_sources/sample_package_1/main.bal @@ -0,0 +1,20 @@ +import ballerina/data.csv; + +type A [[int, string], [int, string]]; + +public function main() returns error? { + stream s = ( [[1, 2, 3, 4, 5]]).toStream(); + + [[int, string], [int, string]] val = check csv:parseStringToList(string `a,b`, {}); + [record{}, record{}, record{}, record{}] val2 = check csv:parseStringToRecord(string `a,b`, {}); + [[int, string], [int, string]] val3 = check csv:parseStreamToList(s, {}); + [record{}, record{}, record{}, record{}] val4 = check csv:parseStreamToRecord(s, {}); + A val5 = check csv:parseBytesToList([1,2,3], {}); + record{}[]|[record{}, record{}, record{}, record{}] val6 = check csv:parseBytesToRecord([1,2,3], {}); + int[][]|[[int, string], [int, string]] val7 = check csv:parseRecordAsListType([{}], [], {}); + [[int, string], [int, string]] val8 = check csv:parseListAsListType([], {}); + [record{}, record{}, record{}, record{}] val9 = check csv:parseRecordAsRecordType([{}], {}); + [record{}, record{}, record{}, record{}] val10 = check csv:parseListAsRecordType([], [], {}); + record{}[2] val11 = check csv:parseListAsRecordType([], [], {}); + int[3][2] val12 = check csv:parseListAsListType([], {}); +} diff --git a/compiler-plugin-test/src/test/resources/ballerina_sources/sample_package_2/Ballerina.toml b/compiler-plugin-test/src/test/resources/ballerina_sources/sample_package_2/Ballerina.toml new file mode 100644 index 0000000..3b39d28 --- /dev/null +++ b/compiler-plugin-test/src/test/resources/ballerina_sources/sample_package_2/Ballerina.toml @@ -0,0 +1,6 @@ +[package] +org = "admin" +name = "sample_package_2" +version = "0.1.0" +distribution = "2201.9.0" + diff --git a/compiler-plugin-test/src/test/resources/ballerina_sources/sample_package_2/main.bal b/compiler-plugin-test/src/test/resources/ballerina_sources/sample_package_2/main.bal new file mode 100644 index 0000000..4670e29 --- /dev/null +++ b/compiler-plugin-test/src/test/resources/ballerina_sources/sample_package_2/main.bal @@ -0,0 +1,7 @@ +import ballerina/data.csv as c; + +type A record { + @c:Name {value: "b"} + int a; + string b; +}; diff --git a/compiler-plugin/src/main/java/io/ballerina/stdlib/data/csvdata/compiler/Constants.java b/compiler-plugin/src/main/java/io/ballerina/stdlib/data/csvdata/compiler/Constants.java new file mode 100644 index 0000000..9dba404 --- /dev/null +++ b/compiler-plugin/src/main/java/io/ballerina/stdlib/data/csvdata/compiler/Constants.java @@ -0,0 +1,41 @@ +/* + * Copyright (c) 2024, WSO2 LLC. (https://www.wso2.com). + * + * 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 + * + * 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 io.ballerina.stdlib.data.csvdata.compiler; + +/** + * Constants for CsvData's compiler plugin. + * + * @since 0.1.0 + */ +public class Constants { + static final String PARSE_STRING_TO_RECORD = "parseStringToRecord"; + static final String PARSE_BYTES_TO_RECORD = "parseBytesToRecord"; + static final String PARSE_STREAM_TO_RECORD = "parseStreamToRecord"; + static final String PARSE_STRING_TO_LIST = "parseStringToList"; + static final String PARSE_BYTES_TO_LIST = "parseBytesToList"; + static final String PARSE_STREAM_TO_LIST = "parseStreamToList"; + static final String PARSE_RECORD_AS_RECORD_TYPE = "parseRecordAsRecordType"; + static final String PARSE_RECORD_AS_LIST_TYPE = "parseRecordAsListType"; + static final String PARSE_LIST_AS_RECORD_TYPE = "parseListAsRecordType"; + static final String PARSE_LIST_AS_LIST_TYPE = "parseListAsListType"; + static final String NAME = "Name"; + static final String CSVDATA = "csv"; + static final String BALLERINA = "ballerina"; + static final String DATA_CSVDATA = "data.csv"; +} diff --git a/compiler-plugin/src/main/java/io/ballerina/stdlib/data/csvdata/compiler/CsvDataCodeAnalyzer.java b/compiler-plugin/src/main/java/io/ballerina/stdlib/data/csvdata/compiler/CsvDataCodeAnalyzer.java new file mode 100644 index 0000000..86d27f1 --- /dev/null +++ b/compiler-plugin/src/main/java/io/ballerina/stdlib/data/csvdata/compiler/CsvDataCodeAnalyzer.java @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2024, WSO2 LLC. (https://www.wso2.com). + * + * 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 + * + * 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 io.ballerina.stdlib.data.csvdata.compiler; + +import io.ballerina.compiler.syntax.tree.SyntaxKind; +import io.ballerina.projects.plugins.CodeAnalysisContext; +import io.ballerina.projects.plugins.CodeAnalyzer; + +import java.util.List; + +/** + * Csvdata Code Analyzer. + * + * @since 0.1.0 + */ +public class CsvDataCodeAnalyzer extends CodeAnalyzer { + @Override + public void init(CodeAnalysisContext codeAnalysisContext) { + codeAnalysisContext.addSyntaxNodeAnalysisTask(new CsvDataTypeValidator(), + List.of(SyntaxKind.MODULE_PART)); + } +} diff --git a/compiler-plugin/src/main/java/io/ballerina/stdlib/data/csvdata/compiler/CsvDataCompilerPlugin.java b/compiler-plugin/src/main/java/io/ballerina/stdlib/data/csvdata/compiler/CsvDataCompilerPlugin.java index 80f28de..865eca3 100644 --- a/compiler-plugin/src/main/java/io/ballerina/stdlib/data/csvdata/compiler/CsvDataCompilerPlugin.java +++ b/compiler-plugin/src/main/java/io/ballerina/stdlib/data/csvdata/compiler/CsvDataCompilerPlugin.java @@ -30,6 +30,6 @@ public class CsvDataCompilerPlugin extends CompilerPlugin { @Override public void init(CompilerPluginContext compilerPluginContext) { - + compilerPluginContext.addCodeAnalyzer(new CsvDataCodeAnalyzer()); } } diff --git a/compiler-plugin/src/main/java/io/ballerina/stdlib/data/csvdata/compiler/CsvDataDiagnosticCodes.java b/compiler-plugin/src/main/java/io/ballerina/stdlib/data/csvdata/compiler/CsvDataDiagnosticCodes.java new file mode 100644 index 0000000..57c9cac --- /dev/null +++ b/compiler-plugin/src/main/java/io/ballerina/stdlib/data/csvdata/compiler/CsvDataDiagnosticCodes.java @@ -0,0 +1,55 @@ +/* + * Copyright (c) 2024, WSO2 LLC. (https://www.wso2.com). + * + * 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 + * + * 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 io.ballerina.stdlib.data.csvdata.compiler; + +import io.ballerina.tools.diagnostics.DiagnosticSeverity; + +import static io.ballerina.tools.diagnostics.DiagnosticSeverity.ERROR; + +/** + * Diagnostic codes for Csv data's compiler plugin. + * + * @since 0.1.0 + */ +public enum CsvDataDiagnosticCodes { + DUPLICATE_FIELD("JSON_ERROR_202", "invalid field: duplicate field found", ERROR), + UNSUPPORTED_TYPE("JSON_ERROR_203", "unsupported type: type is not supported", ERROR); + + private final String code; + private final String message; + private final DiagnosticSeverity severity; + + CsvDataDiagnosticCodes(String code, String message, DiagnosticSeverity severity) { + this.code = code; + this.message = message; + this.severity = severity; + } + + public String getCode() { + return code; + } + + public String getMessage() { + return message; + } + + public DiagnosticSeverity getSeverity() { + return severity; + } +} diff --git a/compiler-plugin/src/main/java/io/ballerina/stdlib/data/csvdata/compiler/CsvDataTypeValidator.java b/compiler-plugin/src/main/java/io/ballerina/stdlib/data/csvdata/compiler/CsvDataTypeValidator.java new file mode 100644 index 0000000..7b36726 --- /dev/null +++ b/compiler-plugin/src/main/java/io/ballerina/stdlib/data/csvdata/compiler/CsvDataTypeValidator.java @@ -0,0 +1,396 @@ +/* + * Copyright (c) 2024, WSO2 LLC. (https://www.wso2.com). + * + * 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 + * + * 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 io.ballerina.stdlib.data.csvdata.compiler; + +import io.ballerina.compiler.api.ModuleID; +import io.ballerina.compiler.api.SemanticModel; +import io.ballerina.compiler.api.symbols.AnnotationAttachmentSymbol; +import io.ballerina.compiler.api.symbols.AnnotationSymbol; +import io.ballerina.compiler.api.symbols.ArrayTypeSymbol; +import io.ballerina.compiler.api.symbols.IntersectionTypeSymbol; +import io.ballerina.compiler.api.symbols.ModuleSymbol; +import io.ballerina.compiler.api.symbols.RecordFieldSymbol; +import io.ballerina.compiler.api.symbols.RecordTypeSymbol; +import io.ballerina.compiler.api.symbols.Symbol; +import io.ballerina.compiler.api.symbols.SymbolKind; +import io.ballerina.compiler.api.symbols.TupleTypeSymbol; +import io.ballerina.compiler.api.symbols.TypeDefinitionSymbol; +import io.ballerina.compiler.api.symbols.TypeDescKind; +import io.ballerina.compiler.api.symbols.TypeReferenceTypeSymbol; +import io.ballerina.compiler.api.symbols.TypeSymbol; +import io.ballerina.compiler.api.symbols.UnionTypeSymbol; +import io.ballerina.compiler.api.symbols.VariableSymbol; +import io.ballerina.compiler.syntax.tree.CheckExpressionNode; +import io.ballerina.compiler.syntax.tree.ChildNodeList; +import io.ballerina.compiler.syntax.tree.ExpressionNode; +import io.ballerina.compiler.syntax.tree.FunctionCallExpressionNode; +import io.ballerina.compiler.syntax.tree.FunctionDefinitionNode; +import io.ballerina.compiler.syntax.tree.ImportDeclarationNode; +import io.ballerina.compiler.syntax.tree.ModuleMemberDeclarationNode; +import io.ballerina.compiler.syntax.tree.ModulePartNode; +import io.ballerina.compiler.syntax.tree.ModuleVariableDeclarationNode; +import io.ballerina.compiler.syntax.tree.NameReferenceNode; +import io.ballerina.compiler.syntax.tree.Node; +import io.ballerina.compiler.syntax.tree.QualifiedNameReferenceNode; +import io.ballerina.compiler.syntax.tree.SyntaxKind; +import io.ballerina.compiler.syntax.tree.TypeDefinitionNode; +import io.ballerina.compiler.syntax.tree.VariableDeclarationNode; +import io.ballerina.projects.plugins.AnalysisTask; +import io.ballerina.projects.plugins.SyntaxNodeAnalysisContext; +import io.ballerina.tools.diagnostics.Diagnostic; +import io.ballerina.tools.diagnostics.DiagnosticFactory; +import io.ballerina.tools.diagnostics.DiagnosticInfo; +import io.ballerina.tools.diagnostics.DiagnosticSeverity; +import io.ballerina.tools.diagnostics.Location; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; +import java.util.Optional; + +/** + * CsvData Record Field Validator. + * + * @since 0.1.0 + */ +public class CsvDataTypeValidator implements AnalysisTask { + + private SemanticModel semanticModel; + private final HashMap allDiagnosticInfo = new HashMap<>(); + Location currentLocation; + private String modulePrefix = Constants.CSVDATA; + + @Override + public void perform(SyntaxNodeAnalysisContext ctx) { + semanticModel = ctx.semanticModel(); + List diagnostics = semanticModel.diagnostics(); + boolean erroneousCompilation = diagnostics.stream() + .anyMatch(d -> d.diagnosticInfo().severity().equals(DiagnosticSeverity.ERROR)); + if (erroneousCompilation) { + reset(); + return; + } + + ModulePartNode rootNode = (ModulePartNode) ctx.node(); + updateModulePrefix(rootNode); + + for (ModuleMemberDeclarationNode member : rootNode.members()) { + switch (member.kind()) { + case FUNCTION_DEFINITION -> processFunctionDefinitionNode((FunctionDefinitionNode) member, ctx); + case MODULE_VAR_DECL -> + processModuleVariableDeclarationNode((ModuleVariableDeclarationNode) member, ctx); + case TYPE_DEFINITION -> + processTypeDefinitionNode((TypeDefinitionNode) member, ctx); + } + } + reset(); + } + + private void reset() { + semanticModel = null; + allDiagnosticInfo.clear(); + currentLocation = null; + modulePrefix = Constants.CSVDATA; + } + + private void updateModulePrefix(ModulePartNode rootNode) { + for (ImportDeclarationNode importDeclarationNode : rootNode.imports()) { + Optional symbol = semanticModel.symbol(importDeclarationNode); + if (symbol.isPresent() && symbol.get().kind() == SymbolKind.MODULE) { + ModuleSymbol moduleSymbol = (ModuleSymbol) symbol.get(); + if (isCsvdataImport(moduleSymbol)) { + modulePrefix = moduleSymbol.id().modulePrefix(); + break; + } + } + } + } + + private void processFunctionDefinitionNode(FunctionDefinitionNode functionDefinitionNode, + SyntaxNodeAnalysisContext ctx) { + ChildNodeList childNodeList = functionDefinitionNode.functionBody().children(); + for (Node node : childNodeList) { + if (node.kind() != SyntaxKind.LOCAL_VAR_DECL) { + continue; + } + VariableDeclarationNode variableDeclarationNode = (VariableDeclarationNode) node; + Optional initializer = variableDeclarationNode.initializer(); + if (initializer.isEmpty()) { + continue; + } + + currentLocation = variableDeclarationNode.typedBindingPattern().typeDescriptor().location(); + Optional symbol = semanticModel.symbol(variableDeclarationNode.typedBindingPattern()); + if (symbol.isEmpty()) { + continue; + } + + TypeSymbol typeSymbol = ((VariableSymbol) symbol.get()).typeDescriptor(); + if (!isParseFunctionOfStringSource(initializer.get())) { + checkTypeAndDetectDuplicateFields(typeSymbol, ctx); + continue; + } + + validateExpectedType(typeSymbol, ctx); + } + } + + private void checkTypeAndDetectDuplicateFields(TypeSymbol typeSymbol, SyntaxNodeAnalysisContext ctx) { + switch (typeSymbol.typeKind()) { + case RECORD -> detectDuplicateFields((RecordTypeSymbol) typeSymbol, ctx); + case ARRAY -> checkTypeAndDetectDuplicateFields(((ArrayTypeSymbol) typeSymbol).memberTypeDescriptor(), ctx); + case TUPLE -> { + for (TypeSymbol memberType : ((TupleTypeSymbol) typeSymbol).memberTypeDescriptors()) { + checkTypeAndDetectDuplicateFields(memberType, ctx); + } + } + case UNION -> { + for (TypeSymbol memberType : ((UnionTypeSymbol) typeSymbol).memberTypeDescriptors()) { + checkTypeAndDetectDuplicateFields(memberType, ctx); + } + } + case TYPE_REFERENCE -> checkTypeAndDetectDuplicateFields( + ((TypeReferenceTypeSymbol) typeSymbol).typeDescriptor(), ctx); + case INTERSECTION -> checkTypeAndDetectDuplicateFields(getRawType(typeSymbol), ctx); + } + } + + private boolean isParseFunctionOfStringSource(ExpressionNode expressionNode) { + if (expressionNode.kind() == SyntaxKind.CHECK_EXPRESSION) { + expressionNode = ((CheckExpressionNode) expressionNode).expression(); + } + + if (expressionNode.kind() != SyntaxKind.FUNCTION_CALL) { + return false; + } + NameReferenceNode nameReferenceNode = ((FunctionCallExpressionNode) expressionNode).functionName(); + if (nameReferenceNode.kind() != SyntaxKind.QUALIFIED_NAME_REFERENCE) { + return false; + } + String prefix = ((QualifiedNameReferenceNode) nameReferenceNode).modulePrefix().text(); + if (!prefix.equals(modulePrefix)) { + return false; + } + String functionName = ((FunctionCallExpressionNode) expressionNode).functionName().toString().trim(); + return functionName.contains(Constants.PARSE_STRING_TO_RECORD) || + functionName.contains(Constants.PARSE_BYTES_TO_RECORD) || + functionName.contains(Constants.PARSE_STREAM_TO_RECORD) || + functionName.contains(Constants.PARSE_STRING_TO_LIST) || + functionName.contains(Constants.PARSE_BYTES_TO_LIST) || + functionName.contains(Constants.PARSE_STREAM_TO_LIST) || + functionName.contains(Constants.PARSE_RECORD_AS_RECORD_TYPE) || + functionName.contains(Constants.PARSE_RECORD_AS_LIST_TYPE) || + functionName.contains(Constants.PARSE_LIST_AS_RECORD_TYPE) || + functionName.contains(Constants.PARSE_LIST_AS_LIST_TYPE); + } + + private void validateExpectedType(TypeSymbol typeSymbol, SyntaxNodeAnalysisContext ctx) { + typeSymbol.getLocation().ifPresent(location -> currentLocation = location); + + switch (typeSymbol.typeKind()) { + case UNION -> validateUnionType((UnionTypeSymbol) typeSymbol, typeSymbol.getLocation(), ctx); + case ARRAY -> validateArrayType((ArrayTypeSymbol) typeSymbol, ctx); + case TUPLE -> validateTupleType((TupleTypeSymbol) typeSymbol, ctx); + case TYPE_REFERENCE -> validateExpectedType(((TypeReferenceTypeSymbol) typeSymbol).typeDescriptor(), ctx); + case INTERSECTION -> validateExpectedType(getRawType(typeSymbol), ctx); + } + } + + private void validateTupleType(TupleTypeSymbol typeSymbol, SyntaxNodeAnalysisContext ctx) { + reportDiagnosticInfo(ctx, typeSymbol.getLocation(), CsvDataDiagnosticCodes.UNSUPPORTED_TYPE); + } + + private void validateArrayType(ArrayTypeSymbol typeSymbol, SyntaxNodeAnalysisContext ctx) { + if (!isSupportedArrayMemberType(typeSymbol.memberTypeDescriptor())) { + reportDiagnosticInfo(ctx, typeSymbol.getLocation(), CsvDataDiagnosticCodes.UNSUPPORTED_TYPE); + } + } + + private void validateUnionType(UnionTypeSymbol unionTypeSymbol, Optional location, + SyntaxNodeAnalysisContext ctx) { + boolean isHasUnsupportedType = false; + List memberTypeSymbols = unionTypeSymbol.memberTypeDescriptors(); + for (TypeSymbol memberTypeSymbol : memberTypeSymbols) { + validateExpectedType(memberTypeSymbol, ctx); + } + + if (isHasUnsupportedType) { + reportDiagnosticInfo(ctx, location, CsvDataDiagnosticCodes.UNSUPPORTED_TYPE); + } + } + + private boolean isSupportedUnionMemberType(TypeSymbol typeSymbol) { + TypeDescKind kind = typeSymbol.typeKind(); + if (kind == TypeDescKind.TYPE_REFERENCE) { + kind = ((TypeReferenceTypeSymbol) typeSymbol).typeDescriptor().typeKind(); + } + + switch (kind) { + case ARRAY, INTERSECTION -> { + return true; + } + default -> { + return false; + } + } + } + + private boolean isSupportedArrayMemberType(TypeSymbol typeSymbol) { + TypeDescKind kind = typeSymbol.typeKind(); + if (kind == TypeDescKind.TYPE_REFERENCE) { + kind = ((TypeReferenceTypeSymbol) typeSymbol).typeDescriptor().typeKind(); + } + + switch (kind) { + case RECORD, ARRAY, TUPLE, MAP, UNION, INTERSECTION -> { + return true; + } + default -> { + return false; + } + } + } + + private boolean isSupportedExpectedType(TypeSymbol typeSymbol) { + TypeDescKind kind = typeSymbol.typeKind(); + if (kind == TypeDescKind.TYPE_REFERENCE) { + kind = ((TypeReferenceTypeSymbol) typeSymbol).typeDescriptor().typeKind(); + } + + switch (kind) { + case ARRAY, UNION, INTERSECTION -> { + return true; + } + default -> { + return false; + } + } + } + + public static TypeSymbol getRawType(TypeSymbol typeDescriptor) { + if (typeDescriptor.typeKind() == TypeDescKind.INTERSECTION) { + return getRawType(((IntersectionTypeSymbol) typeDescriptor).effectiveTypeDescriptor()); + } + if (typeDescriptor.typeKind() == TypeDescKind.TYPE_REFERENCE) { + TypeReferenceTypeSymbol typeRef = (TypeReferenceTypeSymbol) typeDescriptor; + if (typeRef.typeDescriptor().typeKind() == TypeDescKind.INTERSECTION) { + return getRawType(((IntersectionTypeSymbol) typeRef.typeDescriptor()).effectiveTypeDescriptor()); + } + TypeSymbol rawType = typeRef.typeDescriptor(); + if (rawType.typeKind() == TypeDescKind.TYPE_REFERENCE) { + return getRawType(rawType); + } + return rawType; + } + return typeDescriptor; + } + + private void reportDiagnosticInfo(SyntaxNodeAnalysisContext ctx, Optional location, + CsvDataDiagnosticCodes diagnosticsCodes) { + Location pos = location.orElseGet(() -> currentLocation); + DiagnosticInfo diagnosticInfo = new DiagnosticInfo(diagnosticsCodes.getCode(), + diagnosticsCodes.getMessage(), diagnosticsCodes.getSeverity()); + if (allDiagnosticInfo.containsKey(pos) && allDiagnosticInfo.get(pos).equals(diagnosticInfo)) { + return; + } + allDiagnosticInfo.put(pos, diagnosticInfo); + ctx.reportDiagnostic(DiagnosticFactory.createDiagnostic(diagnosticInfo, pos)); + } + + private void processModuleVariableDeclarationNode(ModuleVariableDeclarationNode moduleVariableDeclarationNode, + SyntaxNodeAnalysisContext ctx) { + Optional initializer = moduleVariableDeclarationNode.initializer(); + if (initializer.isEmpty() || !isParseFunctionOfStringSource(initializer.get())) { + return; + } + + Optional symbol = semanticModel.symbol(moduleVariableDeclarationNode.typedBindingPattern()); + if (symbol.isEmpty()) { + return; + } + validateExpectedType(((VariableSymbol) symbol.get()).typeDescriptor(), ctx); + } + + private void processTypeDefinitionNode(TypeDefinitionNode typeDefinitionNode, SyntaxNodeAnalysisContext ctx) { + Node typeDescriptor = typeDefinitionNode.typeDescriptor(); + if (typeDescriptor.kind() != SyntaxKind.RECORD_TYPE_DESC) { + return; + } + validateRecordTypeDefinition(typeDefinitionNode, ctx); + } + + private void validateRecordTypeDefinition(TypeDefinitionNode typeDefinitionNode, SyntaxNodeAnalysisContext ctx) { + Optional symbol = semanticModel.symbol(typeDefinitionNode); + if (symbol.isEmpty()) { + return; + } + TypeDefinitionSymbol typeDefinitionSymbol = (TypeDefinitionSymbol) symbol.get(); + detectDuplicateFields((RecordTypeSymbol) typeDefinitionSymbol.typeDescriptor(), ctx); + } + + private void detectDuplicateFields(RecordTypeSymbol recordTypeSymbol, SyntaxNodeAnalysisContext ctx) { + List fieldMembers = new ArrayList<>(); + for (Map.Entry entry : recordTypeSymbol.fieldDescriptors().entrySet()) { + RecordFieldSymbol fieldSymbol = entry.getValue(); + String name = getNameFromAnnotation(entry.getKey(), fieldSymbol.annotAttachments()); + if (fieldMembers.contains(name)) { + reportDiagnosticInfo(ctx, fieldSymbol.getLocation(), CsvDataDiagnosticCodes.DUPLICATE_FIELD); + return; + } + fieldMembers.add(name); + } + } + + private String getNameFromAnnotation(String fieldName, + List annotationAttachments) { + for (AnnotationAttachmentSymbol annotAttSymbol : annotationAttachments) { + AnnotationSymbol annotation = annotAttSymbol.typeDescriptor(); + if (!getAnnotModuleName(annotation).contains(Constants.CSVDATA)) { + continue; + } + Optional nameAnnot = annotation.getName(); + if (nameAnnot.isEmpty()) { + continue; + } + String value = nameAnnot.get(); + if (value.equals(Constants.NAME)) { + return ((LinkedHashMap) annotAttSymbol.attachmentValue().orElseThrow().value()) + .get("value").toString(); + } + } + return fieldName; + } + + private String getAnnotModuleName(AnnotationSymbol annotation) { + Optional moduleSymbol = annotation.getModule(); + if (moduleSymbol.isEmpty()) { + return ""; + } + Optional moduleName = moduleSymbol.get().getName(); + return moduleName.orElse(""); + } + + private boolean isCsvdataImport(ModuleSymbol moduleSymbol) { + ModuleID moduleId = moduleSymbol.id(); + return Constants.BALLERINA.equals(moduleId.orgName()) + && Constants.DATA_CSVDATA.equals(moduleId.moduleName()); + } +} diff --git a/gradle.properties b/gradle.properties index ee77c50..9ef82e1 100644 --- a/gradle.properties +++ b/gradle.properties @@ -2,6 +2,7 @@ org.gradle.caching=true group=io.ballerina.stdlib version=0.1.0-SNAPSHOT ballerinaLangVersion=2201.9.0 +ballerinaTomlParserVersion=1.2.2 checkstyleToolVersion=10.12.0 puppycrawlCheckstyleVersion=10.12.0 diff --git a/native/build.gradle b/native/build.gradle index 54266fa..d87213d 100644 --- a/native/build.gradle +++ b/native/build.gradle @@ -26,7 +26,6 @@ description = 'Ballerina - Data.CSV Java Utils' dependencies { implementation 'junit:junit:4.13.1' -// checkstyle project(':checkstyle') checkstyle "com.puppycrawl.tools:checkstyle:${puppycrawlCheckstyleVersion}" implementation 'org.apache.commons:commons-lang3:3.6' @@ -35,7 +34,6 @@ dependencies { implementation group: 'org.ballerinalang', name: 'value', version: "${ballerinaLangVersion}" implementation group: 'org.ballerinalang', name: 'value', version: "${ballerinaLangVersion}" implementation group: 'io.ballerina.stdlib', name: 'constraint-native', version: "${stdlibConstraintVersion}" - // ballerinaStdLibs "io.ballerina.stdlib:constraint-ballerina:${stdlibConstraintVersion}" } checkstyle { diff --git a/native/src/main/java/io/ballerina/stdlib/data/csvdata/FromString.java b/native/src/main/java/io/ballerina/stdlib/data/csvdata/FromString.java new file mode 100644 index 0000000..24afea6 --- /dev/null +++ b/native/src/main/java/io/ballerina/stdlib/data/csvdata/FromString.java @@ -0,0 +1,326 @@ +/* + * Copyright (c) 2024, WSO2 LLC. (https://www.wso2.com). + * + * 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 + * + * 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 io.ballerina.stdlib.data.csvdata; + +import io.ballerina.runtime.api.PredefinedTypes; +import io.ballerina.runtime.api.TypeTags; +import io.ballerina.runtime.api.creators.ErrorCreator; +import io.ballerina.runtime.api.creators.TypeCreator; +import io.ballerina.runtime.api.creators.ValueCreator; +import io.ballerina.runtime.api.types.FiniteType; +import io.ballerina.runtime.api.types.IntersectionType; +import io.ballerina.runtime.api.types.ReferenceType; +import io.ballerina.runtime.api.types.Type; +import io.ballerina.runtime.api.types.UnionType; +import io.ballerina.runtime.api.utils.StringUtils; +import io.ballerina.runtime.api.utils.TypeUtils; +import io.ballerina.runtime.api.values.BDecimal; +import io.ballerina.runtime.api.values.BError; +import io.ballerina.runtime.api.values.BString; +import io.ballerina.stdlib.data.csvdata.utils.Constants; +import io.ballerina.stdlib.data.csvdata.utils.CsvConfig; +import io.ballerina.stdlib.data.csvdata.utils.DiagnosticErrorCode; +import io.ballerina.stdlib.data.csvdata.utils.DiagnosticLog; + +import java.util.ArrayList; +import java.util.Comparator; +import java.util.List; + +import static io.ballerina.stdlib.data.csvdata.utils.CsvUtils.isNullValue; + +/** + * Native implementation of data:fromStringWithType(string). + * + * @since 0.1.0 + */ +public class FromString { + + private static final List TYPE_PRIORITY_ORDER = List.of( + TypeTags.INT_TAG, + TypeTags.FLOAT_TAG, + TypeTags.DECIMAL_TAG, + TypeTags.NULL_TAG, + TypeTags.BOOLEAN_TAG, + TypeTags.JSON_TAG, + TypeTags.STRING_TAG + ); + + private static final List BASIC_JSON_MEMBER_TYPES = List.of( + PredefinedTypes.TYPE_NULL, + PredefinedTypes.TYPE_BOOLEAN, + PredefinedTypes.TYPE_INT, + PredefinedTypes.TYPE_FLOAT, + PredefinedTypes.TYPE_DECIMAL, + PredefinedTypes.TYPE_STRING + ); + private static final UnionType JSON_TYPE_WITH_BASIC_TYPES = TypeCreator.createUnionType(BASIC_JSON_MEMBER_TYPES); + public static final Integer BBYTE_MIN_VALUE = 0; + public static final Integer BBYTE_MAX_VALUE = 255; + public static final Integer SIGNED32_MAX_VALUE = 2147483647; + public static final Integer SIGNED32_MIN_VALUE = -2147483648; + public static final Integer SIGNED16_MAX_VALUE = 32767; + public static final Integer SIGNED16_MIN_VALUE = -32768; + public static final Integer SIGNED8_MAX_VALUE = 127; + public static final Integer SIGNED8_MIN_VALUE = -128; + public static final Long UNSIGNED32_MAX_VALUE = 4294967295L; + public static final Integer UNSIGNED16_MAX_VALUE = 65535; + public static final Integer UNSIGNED8_MAX_VALUE = 255; + + public static Object fromStringWithType(BString string, Type expType, CsvConfig config) { + String value = string.getValue(); + try { + switch (expType.getTag()) { + case TypeTags.INT_TAG: + return stringToInt(value); + case TypeTags.BYTE_TAG: + return stringToByte(value); + case TypeTags.SIGNED8_INT_TAG: + return stringToSigned8Int(value); + case TypeTags.SIGNED16_INT_TAG: + return stringToSigned16Int(value); + case TypeTags.SIGNED32_INT_TAG: + return stringToSigned32Int(value); + case TypeTags.UNSIGNED8_INT_TAG: + return stringToUnsigned8Int(value); + case TypeTags.UNSIGNED16_INT_TAG: + return stringToUnsigned16Int(value); + case TypeTags.UNSIGNED32_INT_TAG: + return stringToUnsigned32Int(value); + case TypeTags.FLOAT_TAG: + return stringToFloat(value); + case TypeTags.DECIMAL_TAG: + return stringToDecimal(value); + case TypeTags.CHAR_STRING_TAG: + return stringToChar(value); + case TypeTags.STRING_TAG: + return string; + case TypeTags.BOOLEAN_TAG: + return stringToBoolean(value); + case TypeTags.NULL_TAG: + return stringToNull(value, config); + case TypeTags.FINITE_TYPE_TAG: + return stringToFiniteType(value, (FiniteType) expType, config); + case TypeTags.UNION_TAG: + return stringToUnion(string, (UnionType) expType, config); + case TypeTags.JSON_TAG: + case TypeTags.ANYDATA_TAG: + return stringToUnion(string, JSON_TYPE_WITH_BASIC_TYPES, config); + case TypeTags.TYPE_REFERENCED_TYPE_TAG: + return fromStringWithType(string, ((ReferenceType) expType).getReferredType(), config); + case TypeTags.INTERSECTION_TAG: + return fromStringWithType(string, ((IntersectionType) expType).getEffectiveType(), config); + default: + return returnError(value, expType.toString()); + } + } catch (NumberFormatException e) { + return returnError(value, expType.toString()); + } + } + + private static Object stringToFiniteType(String value, FiniteType finiteType, CsvConfig config) { + return finiteType.getValueSpace().stream() + .filter(finiteValue -> !(convertToSingletonValue(value, finiteValue, config) instanceof BError)) + .findFirst() + .orElseGet(() -> returnError(value, finiteType.toString())); + } + + private static Object convertToSingletonValue(String str, Object singletonValue, CsvConfig config) { + String singletonStr = String.valueOf(singletonValue); + if (str.equals(singletonStr)) { + return fromStringWithType(StringUtils.fromString(str), TypeUtils.getType(singletonValue), config); + } else { + return returnError(str, singletonStr); + } + } + + private static Long stringToInt(String value) throws NumberFormatException { + return Long.parseLong(value); + } + + private static int stringToByte(String value) throws NumberFormatException { + int intValue = Integer.parseInt(value); + if (!isByteLiteral(intValue)) { + throw DiagnosticLog.error(DiagnosticErrorCode.INVALID_CAST, PredefinedTypes.TYPE_BYTE, value); + } + return intValue; + } + + private static long stringToSigned8Int(String value) throws NumberFormatException { + long intValue = Long.parseLong(value); + if (!isSigned8LiteralValue(intValue)) { + throw DiagnosticLog.error(DiagnosticErrorCode.INVALID_CAST, PredefinedTypes.TYPE_INT_SIGNED_8, value); + } + return intValue; + } + + private static long stringToSigned16Int(String value) throws NumberFormatException { + long intValue = Long.parseLong(value); + if (!isSigned16LiteralValue(intValue)) { + throw DiagnosticLog.error(DiagnosticErrorCode.INVALID_CAST, PredefinedTypes.TYPE_INT_SIGNED_16, value); + } + return intValue; + } + + private static long stringToSigned32Int(String value) throws NumberFormatException { + long intValue = Long.parseLong(value); + if (!isSigned32LiteralValue(intValue)) { + throw DiagnosticLog.error(DiagnosticErrorCode.INVALID_CAST, PredefinedTypes.TYPE_INT_SIGNED_32, value); + } + return intValue; + } + + private static long stringToUnsigned8Int(String value) throws NumberFormatException { + long intValue = Long.parseLong(value); + if (!isUnsigned8LiteralValue(intValue)) { + throw DiagnosticLog.error(DiagnosticErrorCode.INVALID_TYPE, + PredefinedTypes.TYPE_INT_UNSIGNED_8, value); + } + return intValue; + } + + private static long stringToUnsigned16Int(String value) throws NumberFormatException { + long intValue = Long.parseLong(value); + if (!isUnsigned16LiteralValue(intValue)) { + throw DiagnosticLog.error(DiagnosticErrorCode.INVALID_CAST, + PredefinedTypes.TYPE_INT_UNSIGNED_16, value); + } + return intValue; + } + + private static long stringToUnsigned32Int(String value) throws NumberFormatException { + long intValue = Long.parseLong(value); + if (!isUnsigned32LiteralValue(intValue)) { + throw DiagnosticLog.error(DiagnosticErrorCode.INVALID_CAST, + PredefinedTypes.TYPE_INT_UNSIGNED_32, value); + } + return intValue; + } + + private static BString stringToChar(String value) throws NumberFormatException { + if (!isCharLiteralValue(value)) { + throw DiagnosticLog.error(DiagnosticErrorCode.INVALID_CAST, + PredefinedTypes.TYPE_STRING_CHAR, value); + } + return StringUtils.fromString(value); + } + + private static Double stringToFloat(String value) throws NumberFormatException { + if (hasFloatOrDecimalLiteralSuffix(value)) { + throw new NumberFormatException(); + } + return Double.parseDouble(value); + } + + private static BDecimal stringToDecimal(String value) throws NumberFormatException { + return ValueCreator.createDecimalValue(value); + } + + private static Object stringToBoolean(String value) throws NumberFormatException { + if ("true".equalsIgnoreCase(value) || "TRUE".equalsIgnoreCase(value)) { + return true; + } + + if ("false".equalsIgnoreCase(value) || "FALSE".equalsIgnoreCase(value)) { + return false; + } + return returnError(value, "boolean"); + } + + private static Object stringToNull(String value, CsvConfig config) throws NumberFormatException { + Object nullValue = config.nilValue; + if (isNullValue(nullValue, value)) { + return null; + } + return returnError(value, nullValue == null ? Constants.Values.BALLERINA_NULL : nullValue.toString()); + } + + private static Object stringToUnion(BString string, UnionType expType, CsvConfig config) + throws NumberFormatException { + List memberTypes = new ArrayList<>(expType.getMemberTypes()); + memberTypes.sort(Comparator.comparingInt(t -> { + int index = TYPE_PRIORITY_ORDER.indexOf(TypeUtils.getReferredType(t).getTag()); + return index == -1 ? Integer.MAX_VALUE : index; + })); + for (Type memberType : memberTypes) { + try { + Object result = fromStringWithType(string, memberType, config); + if (result instanceof BError) { + continue; + } + return result; + } catch (Exception e) { + // Skip + } + } + return returnError(string.getValue(), expType.toString()); + } + + private static boolean hasFloatOrDecimalLiteralSuffix(String value) { + int length = value.length(); + if (length == 0) { + return false; + } + + switch (value.charAt(length - 1)) { + case 'F': + case 'f': + case 'D': + case 'd': + return true; + default: + return false; + } + } + + private static boolean isByteLiteral(long longValue) { + return (longValue >= BBYTE_MIN_VALUE && longValue <= BBYTE_MAX_VALUE); + } + + private static boolean isSigned32LiteralValue(Long longObject) { + return (longObject >= SIGNED32_MIN_VALUE && longObject <= SIGNED32_MAX_VALUE); + } + + private static boolean isSigned16LiteralValue(Long longObject) { + return (longObject.intValue() >= SIGNED16_MIN_VALUE && longObject.intValue() <= SIGNED16_MAX_VALUE); + } + + private static boolean isSigned8LiteralValue(Long longObject) { + return (longObject.intValue() >= SIGNED8_MIN_VALUE && longObject.intValue() <= SIGNED8_MAX_VALUE); + } + + private static boolean isUnsigned32LiteralValue(Long longObject) { + return (longObject >= 0 && longObject <= UNSIGNED32_MAX_VALUE); + } + + private static boolean isUnsigned16LiteralValue(Long longObject) { + return (longObject.intValue() >= 0 && longObject.intValue() <= UNSIGNED16_MAX_VALUE); + } + + private static boolean isUnsigned8LiteralValue(Long longObject) { + return (longObject.intValue() >= 0 && longObject.intValue() <= UNSIGNED8_MAX_VALUE); + } + + private static boolean isCharLiteralValue(String value) { + return value.codePoints().count() == 1; + } + + private static BError returnError(String string, String expType) { + return ErrorCreator.createError(StringUtils.fromString("Cannot convert to the exptype")); + } +} diff --git a/native/src/main/java/io/ballerina/stdlib/data/csvdata/csv/CsvCreator.java b/native/src/main/java/io/ballerina/stdlib/data/csvdata/csv/CsvCreator.java new file mode 100644 index 0000000..77bc61f --- /dev/null +++ b/native/src/main/java/io/ballerina/stdlib/data/csvdata/csv/CsvCreator.java @@ -0,0 +1,179 @@ +/* + * Copyright (c) 2024, WSO2 LLC. (https://www.wso2.com). + * + * 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 + * + * 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 io.ballerina.stdlib.data.csvdata.csv; + +import io.ballerina.runtime.api.PredefinedTypes; +import io.ballerina.runtime.api.TypeTags; +import io.ballerina.runtime.api.creators.ValueCreator; +import io.ballerina.runtime.api.flags.SymbolFlags; +import io.ballerina.runtime.api.types.ArrayType; +import io.ballerina.runtime.api.types.Field; +import io.ballerina.runtime.api.types.IntersectionType; +import io.ballerina.runtime.api.types.MapType; +import io.ballerina.runtime.api.types.TupleType; +import io.ballerina.runtime.api.types.Type; +import io.ballerina.runtime.api.utils.StringUtils; +import io.ballerina.runtime.api.utils.TypeUtils; +import io.ballerina.runtime.api.values.BArray; +import io.ballerina.runtime.api.values.BError; +import io.ballerina.runtime.api.values.BMap; +import io.ballerina.runtime.api.values.BString; +import io.ballerina.stdlib.data.csvdata.FromString; +import io.ballerina.stdlib.data.csvdata.utils.CsvConfig; +import io.ballerina.stdlib.data.csvdata.utils.CsvUtils; +import io.ballerina.stdlib.data.csvdata.utils.DiagnosticErrorCode; +import io.ballerina.stdlib.data.csvdata.utils.DiagnosticLog; +import org.ballerinalang.langlib.value.CloneReadOnly; + +import java.util.Map; +import java.util.Optional; + +import static io.ballerina.stdlib.data.csvdata.utils.CsvUtils.getUpdatedHeaders; +/** + * Create objects for partially parsed csv. + * + * @since 0.1.0 + */ +public class CsvCreator { + + static Object initRowValue(Type expectedType) { + expectedType = TypeUtils.getReferredType(expectedType); + if (expectedType.getTag() == TypeTags.INTERSECTION_TAG) { + Optional mutableType = CsvUtils.getMutableType((IntersectionType) expectedType); + if (!mutableType.isEmpty()) { + expectedType = mutableType.get(); + } + } + + switch (expectedType.getTag()) { + case TypeTags.RECORD_TYPE_TAG: + return ValueCreator.createRecordValue(expectedType.getPackage(), expectedType.getName()); + case TypeTags.MAP_TAG: + return ValueCreator.createMapValue((MapType) expectedType); + case TypeTags.TUPLE_TAG: + return ValueCreator.createTupleValue((TupleType) expectedType); + case TypeTags.ARRAY_TAG: + return ValueCreator.createArrayValue((ArrayType) expectedType); + default: + throw DiagnosticLog.error(DiagnosticErrorCode.INVALID_TYPE, expectedType); + } + } + + static Object convertAndUpdateCurrentJsonNode(CsvParser.StateMachine sm, + String value, Type type, CsvConfig config, Type exptype, + Field currentField) { + Object currentCsv = sm.currentCsvNode; + Object nilValue = config.nilValue; + if (sm.config.nilAsOptionalField && !type.isNilable() + && CsvUtils.isNullValue(nilValue, value) + && currentField != null && SymbolFlags.isFlagOn(currentField.getFlags(), SymbolFlags.OPTIONAL)) { + return null; + } + Object convertedValue = convertToExpectedType(StringUtils.fromString(value), type, config); + sm.isCurrentCsvNodeEmpty = false; + if (convertedValue instanceof BError || convertedValue instanceof CsvUtils.UnMappedValue) { + if (ignoreIncompatibilityErrorsForMaps(sm, exptype)) { + return null; + } + throw DiagnosticLog.error(DiagnosticErrorCode.INVALID_CAST, value, type); + } + + Type currentCsvNodeType = TypeUtils.getType(currentCsv); + switch (currentCsvNodeType.getTag()) { + case TypeTags.MAP_TAG: + case TypeTags.RECORD_TYPE_TAG: + ((BMap) currentCsv).put(StringUtils.fromString(getHeaderValueForColumnIndex(sm)), + convertedValue); + return currentCsv; + case TypeTags.ARRAY_TAG: + ArrayType arrayType = (ArrayType) currentCsvNodeType; + if (arrayType.getState() == ArrayType.ArrayState.CLOSED && + arrayType.getSize() - 1 < sm.columnIndex) { + return currentCsv; + } + ((BArray) currentCsv).add(sm.columnIndex, convertedValue); + return currentCsv; + case TypeTags.TUPLE_TAG: + ((BArray) currentCsv).add(sm.columnIndex, convertedValue); + return currentCsv; + default: + return convertedValue; + } + } + + public static String getHeaderValueForColumnIndex(CsvParser.StateMachine sm) { + if (sm.config.customHeader == null && (sm.config.header == Boolean.FALSE)) { + String header = String.valueOf(sm.columnIndex + 1); + Map fieldHierarchy = sm.fieldHierarchy; + if (fieldHierarchy.containsKey(header)) { + fieldHierarchy.remove(header); + } + return header; + } + if (sm.columnIndex >= sm.headers.size()) { + throw DiagnosticLog.error(DiagnosticErrorCode.INVALID_CUSTOM_HEADER_LENGTH); + } + String header = sm.headers.get(sm.columnIndex); + return getUpdatedHeaders(sm.updatedRecordFieldNames, header, + sm.fields.contains(header)); + } + + public static void checkAndAddCustomHeaders(CsvParser.StateMachine sm, Object customHeader) { + if (customHeader == null) { + return; + } + + BArray customHeaders = (BArray) customHeader; + for (int i = 0; i < customHeaders.size(); i++) { + String header = StringUtils.getStringValue(customHeaders.get(i)); + Map fieldHierarchy = sm.fieldHierarchy; + sm.headers.add(header); + if (fieldHierarchy.containsKey(header)) { + Field field = fieldHierarchy.get(header); + sm.fieldNames.put(header, field); + fieldHierarchy.remove(header); + } + } + } + + private static boolean ignoreIncompatibilityErrorsForMaps(CsvParser.StateMachine sm, Type exptype) { + if (exptype.getTag() == TypeTags.RECORD_TYPE_TAG) { + String header = getHeaderValueForColumnIndex(sm); + Map fields = sm.fieldNames; + if (fields.containsKey(header)) { + return false; + } + return true; + } else if (exptype.getTag() == TypeTags.MAP_TAG) { + return true; + } + return false; + } + + public static Object convertToExpectedType(BString value, Type type, CsvConfig config) { + if (type.getTag() == TypeTags.ANYDATA_TAG) { + return FromString.fromStringWithType(value, PredefinedTypes.TYPE_JSON, config); + } + return FromString.fromStringWithType(value, type, config); + } + + public static Object constructReadOnlyValue(Object value) { + return CloneReadOnly.cloneReadOnly(value); + } +} diff --git a/native/src/main/java/io/ballerina/stdlib/data/csvdata/csv/CsvParser.java b/native/src/main/java/io/ballerina/stdlib/data/csvdata/csv/CsvParser.java new file mode 100644 index 0000000..7041ebe --- /dev/null +++ b/native/src/main/java/io/ballerina/stdlib/data/csvdata/csv/CsvParser.java @@ -0,0 +1,1058 @@ +/* + * Copyright (c) 2024, WSO2 LLC. (https://www.wso2.com). + * + * 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 + * + * 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 io.ballerina.stdlib.data.csvdata.csv; + +import io.ballerina.runtime.api.PredefinedTypes; +import io.ballerina.runtime.api.TypeTags; +import io.ballerina.runtime.api.creators.TypeCreator; +import io.ballerina.runtime.api.creators.ValueCreator; +import io.ballerina.runtime.api.flags.SymbolFlags; +import io.ballerina.runtime.api.types.ArrayType; +import io.ballerina.runtime.api.types.Field; +import io.ballerina.runtime.api.types.IntersectionType; +import io.ballerina.runtime.api.types.MapType; +import io.ballerina.runtime.api.types.RecordType; +import io.ballerina.runtime.api.types.TupleType; +import io.ballerina.runtime.api.types.Type; +import io.ballerina.runtime.api.utils.TypeUtils; +import io.ballerina.runtime.api.values.BArray; +import io.ballerina.runtime.api.values.BError; +import io.ballerina.runtime.api.values.BTypedesc; +import io.ballerina.stdlib.data.csvdata.utils.Constants; +import io.ballerina.stdlib.data.csvdata.utils.CsvConfig; +import io.ballerina.stdlib.data.csvdata.utils.CsvUtils; +import io.ballerina.stdlib.data.csvdata.utils.DataUtils; +import io.ballerina.stdlib.data.csvdata.utils.DiagnosticErrorCode; +import io.ballerina.stdlib.data.csvdata.utils.DiagnosticLog; +import org.apache.commons.lang3.StringEscapeUtils; + +import java.io.IOException; +import java.io.Reader; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Stack; + +import static io.ballerina.stdlib.data.csvdata.csv.CsvCreator.checkAndAddCustomHeaders; +import static io.ballerina.stdlib.data.csvdata.csv.CsvCreator.getHeaderValueForColumnIndex; +import static io.ballerina.stdlib.data.csvdata.utils.CsvUtils.checkRequiredFieldsAndLogError; +import static io.ballerina.stdlib.data.csvdata.utils.CsvUtils.getSkipDataRows; +import static io.ballerina.stdlib.data.csvdata.utils.CsvUtils.isCharContainsInLineTerminatorUserConfig; +import static io.ballerina.stdlib.data.csvdata.utils.CsvUtils.processNameAnnotationsAndBuildCustomFieldMap; +import static io.ballerina.stdlib.data.csvdata.utils.CsvUtils.validateExpectedArraySize; + +/** + * Convert Csv string to a ballerina record. + * + * @since 0.1.0 + */ +public class CsvParser { + private static final char CR = 0x000D; + private static final char HZ_TAB = 0x0009; + private static final char SPACE = 0x0020; + private static final char BACKSPACE = 0x0008; + private static final char FORMFEED = 0x000C; + private static final char QUOTES = '"'; + private static final char REV_SOL = '\\'; + private static final char SOL = '/'; + private static final char EOF = (char) -1; + private static final char NEWLINE = 0x000A; + + + private static final ThreadLocal LOCAL_THREAD_STATE_MACHINE + = ThreadLocal.withInitial(StateMachine::new); + + public static Object parse(Reader reader, BTypedesc type, CsvConfig config) + throws BError { + StateMachine sm = LOCAL_THREAD_STATE_MACHINE.get(); + try { + Object convertedValue = sm.execute(reader, TypeUtils.getReferredType(type.getDescribingType()), + config, type); + return DataUtils.validateConstraints(convertedValue, type, config.enableConstraintValidation); + } finally { + // Need to reset the state machine before leaving. Otherwise, references to the created + // CSV values will be maintained and the java GC will not happen properly. + sm.reset(); + } + } + + static class StateMachine { + private static final State HEADER_START_STATE = new HeaderStartState(); + private static final State HEADER_END_STATE = new HeaderEndState(); + private static final State ROW_START_STATE = new RowStartState(); + private static final State ROW_END_STATE = new RowEndState(); + private static final State STRING_ESCAPE_VALUE_STATE = new StringValueEscapedCharacterProcessingState(); + private static final State STRING_UNICODE_CHAR_STATE = new StringValueUnicodeHexProcessingState(); + private static final State HEADER_UNICODE_CHAR_STATE = new HeaderUnicodeHexProcessingState(); + private static final State HEADER_ESCAPE_CHAR_STATE = new HeaderEscapedCharacterProcessingState(); + private static final State STRING_QUOTE_CHAR_STATE = new StringQuoteValueState(); + private static final State HEADER_QUOTE_CHAR_STATE = new HeaderQuoteValueState(); + + + + private static final char LINE_BREAK = '\n'; + + Object currentCsvNode; + Stack currentEscapeCharacters = new Stack<>(); + ArrayList headers = new ArrayList<>(); + BArray rootCsvNode; + Map fieldHierarchy = new HashMap<>(); + Map updatedRecordFieldNames = new HashMap<>(); + HashSet fields = new HashSet<>(); + Map fieldNames = new HashMap<>(); + private char[] charBuff = new char[1024]; + private int charBuffIndex; + private int index; + private int line; + private int column; + Type restType; + Type expectedArrayElementType; + int columnIndex = 0; + int rowIndex = 1; + int lineNumber = 0; + ArrayType rootArrayType = null; + CsvConfig config = null; + boolean skipTheRow = false; + boolean insideComment = false; + boolean isCurrentCsvNodeEmpty = true; + boolean isHeaderConfigExceedLineNumber = false; + boolean isQuoteClosed = false; + boolean isIntersectionElementType = false; + private StringBuilder hexBuilder = new StringBuilder(4); + boolean isValueStart = false; + State prevState; + int arraySize = 0; + StateMachine() { + reset(); + } + + public void reset() { + index = 0; + currentCsvNode = null; + line = 1; + column = 0; + restType = null; + rootCsvNode = null; + columnIndex = 0; + rowIndex = 1; + fieldHierarchy.clear(); + updatedRecordFieldNames.clear(); + fields.clear(); + fieldNames.clear(); + rootArrayType = null; + config = null; + lineNumber = 0; + expectedArrayElementType = null; + headers = new ArrayList<>(); + currentEscapeCharacters = new Stack<>(); + charBuff = new char[1024]; + charBuffIndex = 0; + skipTheRow = false; + isCurrentCsvNodeEmpty = true; + isHeaderConfigExceedLineNumber = false; + hexBuilder = new StringBuilder(4); + isQuoteClosed = false; + isIntersectionElementType = false; + prevState = null; + arraySize = 0; + } + + private static boolean isWhitespace(char ch, Object lineTerminator) { + return ch == SPACE || ch == HZ_TAB || ch == CR + || isCharContainsInLineTerminatorUserConfig(ch, lineTerminator); + } + + private static void throwExpected(String... chars) throws CsvParserException { + throw new CsvParserException("expected '" + String.join("' or '", chars) + "'"); + } + + private void processLocation(char ch) { + if (ch == LINE_BREAK) { + this.line++; + this.column = 0; + } else { + this.column++; + } + } + + private String value() { + if (this.charBuffIndex == 0) { + return ""; + } + String result = new String(this.charBuff, 0, this.charBuffIndex); + this.charBuffIndex = 0; + return result; + } + + private void clear() { + this.charBuffIndex = 0; + } + + private String peek() { + return new String(this.charBuff, 0, this.charBuffIndex); + } + + public Object execute(Reader reader, Type type, CsvConfig config, BTypedesc bTypedesc) throws BError { + this.config = config; + Type referredType = TypeUtils.getReferredType(type); + if (referredType.getTag() == TypeTags.INTERSECTION_TAG) { + for (Type constituentType : ((IntersectionType) referredType).getConstituentTypes()) { + if (constituentType.getTag() == TypeTags.READONLY_TAG) { + continue; + } + return CsvCreator.constructReadOnlyValue(execute(reader, constituentType, config, bTypedesc)); + } + } + + if (referredType.getTag() == TypeTags.UNION_TAG) { + expectedArrayElementType = referredType; + } else if (referredType.getTag() != TypeTags.ARRAY_TAG) { + throw DiagnosticLog.error(DiagnosticErrorCode.INVALID_TYPE, type); + } else { + rootArrayType = (ArrayType) referredType; + expectedArrayElementType = TypeUtils.getReferredType(rootArrayType.getElementType()); + rootCsvNode = ValueCreator.createArrayValue(rootArrayType); + } + + switch (expectedArrayElementType.getTag()) { + case TypeTags.RECORD_TYPE_TAG: + RecordType recordType = (RecordType) expectedArrayElementType; + restType = (recordType).getRestFieldType(); + fieldHierarchy = new HashMap<>(recordType.getFields()); + fields = new HashSet<>(recordType.getFields().keySet()); + updatedRecordFieldNames = processNameAnnotationsAndBuildCustomFieldMap(recordType, fieldHierarchy); + break; + case TypeTags.TUPLE_TAG: + restType = ((TupleType) expectedArrayElementType).getRestType(); + break; + case TypeTags.MAP_TAG: + case TypeTags.ARRAY_TAG: + break; + case TypeTags.INTERSECTION_TAG: + for (Type constituentType : ((IntersectionType) expectedArrayElementType).getConstituentTypes()) { + if (constituentType.getTag() == TypeTags.READONLY_TAG) { + continue; + } + Object mapValue = execute(reader, TypeCreator.createArrayType( + TypeCreator.createMapType(PredefinedTypes.TYPE_STRING) + ), CsvConfig.createConfigOptionsForUnion(config), bTypedesc); + config.stringConversion = true; + return CsvCreator.constructReadOnlyValue(CsvTraversal + .traverse((BArray) mapValue, config, bTypedesc, + TypeCreator.createArrayType(constituentType))); + } + throw DiagnosticLog.error(DiagnosticErrorCode.SOURCE_CANNOT_CONVERT_INTO_EXP_TYPE, + expectedArrayElementType); + case TypeTags.UNION_TAG: + Object mapValue = execute(reader, TypeCreator.createArrayType( + TypeCreator.createMapType(PredefinedTypes.TYPE_STRING) + ), CsvConfig.createConfigOptionsForUnion(config), bTypedesc); + config.stringConversion = true; + return CsvTraversal.traverse((BArray) mapValue, config, bTypedesc); + default: + throw DiagnosticLog.error(DiagnosticErrorCode.SOURCE_CANNOT_CONVERT_INTO_EXP_TYPE, + expectedArrayElementType); + } + + State currentState; + if (config.header != Boolean.FALSE) { + currentState = HEADER_START_STATE; + } else { + if (config.customHeader != null) { + checkAndAddCustomHeaders(this, config.customHeader); + } + currentState = ROW_START_STATE; + addFieldNamesForNonHeaderState(); + } + try { + char[] buff = new char[1024]; + int count; + while ((count = reader.read(buff)) > 0) { + this.index = 0; + while (this.index < count) { + currentState = currentState.transition(this, buff, this.index, count); + } + } + currentState = currentState.transition(this, new char[] { EOF }, 0, 1); + if (currentState != ROW_END_STATE && currentState != HEADER_END_STATE) { + if (!this.isHeaderConfigExceedLineNumber) { + throw new CsvParserException("Invalid token found"); + } + } + return rootCsvNode; + } catch (IOException e) { + throw DiagnosticLog.error(DiagnosticErrorCode.INVALID_TOKEN, e.getMessage(), line, column); + } catch (CsvParserException e) { + throw DiagnosticLog.error(DiagnosticErrorCode.INVALID_TOKEN, e.getMessage(), line, column); + } + } + + private void addFieldNamesForNonHeaderState() { + for (Map.Entry entry: this.fieldHierarchy.entrySet()) { + this.fieldNames.put(entry.getKey(), entry.getValue()); + } + } + + private void append(char ch) { + try { + this.charBuff[this.charBuffIndex] = ch; + this.charBuffIndex++; + } catch (ArrayIndexOutOfBoundsException e) { + /* this approach is faster than checking for the size by ourself */ + this.growCharBuff(); + this.charBuff[this.charBuffIndex++] = ch; + } + } + + private boolean isNewLineOrEof(char ch) { + return ch == EOF || isCharContainsInLineTerminatorUserConfig(ch, config.lineTerminator); + } + + private void growCharBuff() { + char[] newBuff = new char[charBuff.length * 2]; + System.arraycopy(this.charBuff, 0, newBuff, 0, this.charBuff.length); + this.charBuff = newBuff; + } + + /** + * A specific state in the Csv parsing state machine. + */ + interface State { + State transition(StateMachine sm, char[] buff, int i, int count) throws CsvParserException; + } + + private static class HeaderStartState implements State { + @Override + public State transition(StateMachine sm, char[] buff, int i, int count) throws CsvParserException { + char ch; + State state = HEADER_START_STATE; + char separator = sm.config.delimiter; + Object customHeader = sm.config.customHeader; + int headerStartRowNumber = getHeaderStartRowWhenHeaderIsPresent(sm.config.header); + for (; i < count; i++) { + ch = buff[i]; + sm.processLocation(ch); + if (ch == EOF) { + handleEndOfTheHeader(sm); + return HEADER_END_STATE; + } + if (ch == Constants.LineTerminator.CR) { + CsvUtils.setCarriageTokenPresent(true); + continue; + } else if (!(CsvUtils.isCarriageTokenPresent && ch == Constants.LineTerminator.LF)) { + CsvUtils.setCarriageTokenPresent(false); + } + + if (sm.lineNumber < headerStartRowNumber) { + sm.isHeaderConfigExceedLineNumber = true; + if (sm.isNewLineOrEof(ch)) { + sm.lineNumber++; + } + continue; + } + sm.isHeaderConfigExceedLineNumber = false; + if (customHeader != null) { + if (sm.isNewLineOrEof(ch)) { + checkAndAddCustomHeaders(sm, customHeader); + sm.lineNumber++; + state = HEADER_END_STATE; + break; + } + state = this; + continue; + } + + if (ch == sm.config.comment) { + sm.insideComment = true; + } else if (!sm.insideComment && ch == separator) { + addHeader(sm); + sm.columnIndex++; + state = this; + continue; + } else if (!sm.insideComment && ch == sm.config.textEnclosure) { + sm.prevState = this; + state = HEADER_QUOTE_CHAR_STATE; + break; + } else if (!sm.insideComment && ch == sm.config.escapeChar) { + sm.prevState = this; + state = HEADER_ESCAPE_CHAR_STATE; + break; + } else if (sm.insideComment && sm.isNewLineOrEof(ch)) { + sm.insideComment = false; + handleEndOfTheHeader(sm); + state = HEADER_END_STATE; + } else if (!sm.insideComment && isEndOfTheHeaderRow(sm, ch)) { + handleEndOfTheHeader(sm); + state = HEADER_END_STATE; + } else if (StateMachine.isWhitespace(ch, sm.config.lineTerminator)) { + if (sm.isValueStart) { + sm.append(ch); + } + state = this; + continue; + } else { + if (!sm.insideComment) { + sm.append(ch); + sm.isValueStart = true; + } + state = this; + continue; + } + break; + } + sm.index = i + 1; + return state; + } + } + + private static void handleEndOfTheHeader(StateMachine sm) throws CsvParserException { + handleEndOfTheHeader(sm, true); + } + + private static void handleEndOfTheHeader(StateMachine sm, boolean trim) throws CsvParserException { + sm.isValueStart = false; + if (!sm.peek().isBlank()) { + addHeader(sm, trim); + } + finalizeHeaders(sm); + sm.columnIndex = 0; + sm.lineNumber++; + } + + private static int getHeaderStartRowWhenHeaderIsPresent(Object header) { + return ((Long) header).intValue(); + } + + private static void finalizeHeaders(StateMachine sm) throws CsvParserException { + if (sm.headers.size() == 0) { + throw DiagnosticLog.error(DiagnosticErrorCode.HEADER_CANNOT_BE_EMPTY); + } + Type expType = sm.expectedArrayElementType; + if (expType instanceof RecordType) { + validateRemainingRecordFields(sm); + } else if (expType instanceof ArrayType) { + validateExpectedArraySize(((ArrayType) expType).getSize(), sm.headers.size()); + } else if (expType instanceof MapType) { + //ignore + } else if (expType instanceof TupleType) { + validateTupleTypes((TupleType) expType, sm.restType, sm.headers.size()); + } else { + throw new CsvParserException("Invalid expected type"); + } + } + + private static void validateTupleTypes(TupleType tupleType, Type restType, int currentSize) { + if (restType != null && tupleType.getTupleTypes().size() > currentSize) { + throw DiagnosticLog.error(DiagnosticErrorCode.INVALID_EXPECTED_TUPLE_SIZE, currentSize); + } + } + + private static void validateRemainingRecordFields(StateMachine sm) { + if (sm.restType == null) { + for (Field field : sm.fieldHierarchy.values()) { + if (sm.config.absentAsNilableType && field.getFieldType().isNilable()) { + return; + } + if (SymbolFlags.isFlagOn(field.getFlags(), SymbolFlags.REQUIRED)) { + throw DiagnosticLog.error(DiagnosticErrorCode.INVALID_FIELD_IN_CSV, field.getFieldName()); + } + } + } + } + + private static void addHeader(StateMachine sm) { + addHeader(sm, true); + } + + private static void addHeader(StateMachine sm, boolean trim) { + sm.isValueStart = false; + String value = sm.value(); + if (trim) { + value = value.trim(); + } + if (sm.expectedArrayElementType instanceof RecordType) { + String fieldName = CsvUtils.getUpdatedHeaders( + sm.updatedRecordFieldNames, value, sm.fields.contains(value)); + Field field = sm.fieldHierarchy.get(fieldName); + if (field != null) { + sm.fieldNames.put(fieldName, field); + sm.fieldHierarchy.remove(fieldName); + } + } + sm.headers.add(value); + } + + private static class HeaderEndState implements State { + @Override + public State transition(StateMachine sm, char[] buff, int i, int count) { + return ROW_START_STATE; + } + } + + private static class RowStartState implements State { + char ch; + State state = ROW_START_STATE; + + @Override + public State transition(StateMachine sm, char[] buff, int i, int count) throws CsvParserException { + char separator = sm.config.delimiter; + long[] skipLines = getSkipDataRows(sm.config.skipLines); + + for (; i < count; i++) { + ch = buff[i]; + sm.processLocation(ch); + if (ch == Constants.LineTerminator.CR) { + CsvUtils.setCarriageTokenPresent(true); + continue; + } else if (!(CsvUtils.isCarriageTokenPresent && ch == Constants.LineTerminator.LF)) { + CsvUtils.setCarriageTokenPresent(false); + } + + if (sm.skipTheRow) { + if (sm.isEndOfTheRowAndValueIsNotEmpty(sm, ch)) { + sm.insideComment = false; + sm.skipTheRow = false; + sm.clear(); + if (ch == EOF) { + state = ROW_END_STATE; + } + } else { + sm.append(ch); + sm.isValueStart = true; + } + continue; + } + + if (sm.isCurrentCsvNodeEmpty) { + if (ignoreRow(skipLines, sm.rowIndex)) { + updateLineAndColumnIndexes(sm); + sm.skipTheRow = true; + continue; + } + initiateNewRowType(sm); + } + if (!sm.insideComment && ch == sm.config.comment) { + handleEndOfTheRow(sm); + sm.insideComment = true; + if (ch == EOF) { + state = ROW_END_STATE; + } + } else if (!sm.insideComment && ch == separator) { + addRowValue(sm); + } else if (!sm.insideComment && ch == sm.config.textEnclosure) { + sm.prevState = this; + state = STRING_QUOTE_CHAR_STATE; + break; + } else if (!sm.insideComment && ch == sm.config.escapeChar) { + sm.prevState = this; + state = STRING_ESCAPE_VALUE_STATE; + break; + } else if (sm.insideComment && sm.isNewLineOrEof(ch)) { + sm.insideComment = false; + if (ch == EOF) { + state = ROW_END_STATE; + break; + } + } else if (isEndOfTheRowAndValueIsNotEmpty(sm, ch)) { + handleEndOfTheRow(sm); + if (ch == EOF) { + state = ROW_END_STATE; + break; + } + } else if (StateMachine.isWhitespace(ch, sm.config.lineTerminator)) { + if (sm.isValueStart) { + sm.append(ch); + } + state = this; + // ignore + } else { + if (!sm.insideComment) { + sm.append(ch); + sm.isValueStart = true; + } + } + } + sm.index = i + 1; + return state; + } + } + + private static void handleEndOfTheRow(StateMachine sm) throws CsvParserException { + handleEndOfTheRow(sm, true); + } + + private static void handleEndOfTheRow(StateMachine sm, boolean trim) throws CsvParserException { + sm.isValueStart = false; + handleCsvRow(sm, trim); + checkRequiredFieldsAndLogError(sm.fieldHierarchy, sm.config.absentAsNilableType); + } + + private static void handleCsvRow(StateMachine sm, boolean trim) throws CsvParserException { + String value = sm.peek(); + if (trim) { + value = value.trim(); + } + if (!value.isBlank()) { + addRowValue(sm, trim); + } + if (!sm.isCurrentCsvNodeEmpty) { + finalizeTheRow(sm); + } else { + updateLineAndColumnIndexesWithoutRowIndexes(sm); + } + updateLineAndColumnIndexes(sm); + } + + private static void updateLineAndColumnIndexes(StateMachine sm) { + sm.rowIndex++; + updateLineAndColumnIndexesWithoutRowIndexes(sm); + } + + private static void updateLineAndColumnIndexesWithoutRowIndexes(StateMachine sm) { + sm.lineNumber++; + sm.currentCsvNode = null; + sm.isCurrentCsvNodeEmpty = true; + sm.columnIndex = 0; + } + + private static boolean ignoreRow(long[] skipLines, int lineNumber) { + for (long skipLine: skipLines) { + if (skipLine == lineNumber) { + return true; + } + } + return false; + } + + private static void initiateNewRowType(StateMachine sm) { + sm.currentCsvNode = CsvCreator.initRowValue(sm.expectedArrayElementType); + } + + private static void finalizeTheRow(StateMachine sm) { + int rootArraySize = sm.rootArrayType.getSize(); + if (rootArraySize == -1) { + sm.rootCsvNode.append(sm.currentCsvNode); + } else if (sm.arraySize < rootArraySize) { + sm.rootCsvNode.add(sm.arraySize, sm.currentCsvNode); + } + sm.arraySize++; + } + + private static void addRowValue(StateMachine sm) throws CsvParserException { + addRowValue(sm, true); + } + + private static void addRowValue(StateMachine sm, boolean trim) throws CsvParserException { + Type type; + Field currentField = null; + sm.isValueStart = false; + Type exptype = sm.expectedArrayElementType; + String value = sm.value(); + if (trim) { + value = value.trim(); + } + + if (exptype instanceof RecordType) { + type = getExpectedRowTypeOfRecord(sm); + currentField = getCurrentField(sm); + } else if (exptype instanceof MapType) { + type = ((MapType) exptype).getConstrainedType(); + } else if (exptype instanceof ArrayType) { + type = getExpectedRowTypeOfArray(sm, (ArrayType) exptype); + } else if (exptype instanceof TupleType) { + type = getExpectedRowTypeOfTuple(sm, (TupleType) exptype); + } else { + throw new CsvParserException("Unexpected expected type"); + } + + if (type != null) { + CsvCreator.convertAndUpdateCurrentJsonNode(sm, + value, type, sm.config, exptype, currentField); + } + sm.columnIndex++; + } + + private static Type getExpectedRowTypeOfTuple(StateMachine sm, TupleType tupleType) { + List tupleTypes = tupleType.getTupleTypes(); + if (tupleTypes.size() > sm.columnIndex) { + return tupleTypes.get(sm.columnIndex); + } else { + Type restType = sm.restType; + if (restType != null) { + return restType; + } else { + sm.charBuffIndex = 0; + if (sm.config.allowDataProjection) { + return null; + } + throw DiagnosticLog.error(DiagnosticErrorCode.INVALID_EXPECTED_TUPLE_SIZE, tupleTypes.size()); + } + } + } + + private static Type getExpectedRowTypeOfArray(StateMachine sm, ArrayType arrayType) { + if (arrayType.getSize() != -1 && arrayType.getSize() <= sm.columnIndex) { + sm.charBuffIndex = 0; + if (sm.config.allowDataProjection) { + return null; + } + throw DiagnosticLog.error(DiagnosticErrorCode.INVALID_EXPECTED_ARRAY_SIZE, arrayType.getSize()); + } + return arrayType.getElementType(); + } + + private static Type getExpectedRowTypeOfRecord(StateMachine sm) { + String header = getHeaderValueForColumnIndex(sm); + Map fields = sm.fieldNames; + if (fields.containsKey(header)) { + return fields.get(header).getFieldType(); + } else { + Type restType = sm.restType; + if (restType != null) { + return restType; + } else { + sm.charBuffIndex = 0; + if (sm.config.allowDataProjection) { + return null; + } + throw DiagnosticLog.error(DiagnosticErrorCode.NO_FIELD_FOR_HEADER, header); + } + } + } + + private static Field getCurrentField(StateMachine sm) { + String header = getHeaderValueForColumnIndex(sm); + Map fields = sm.fieldNames; + if (fields.containsKey(header)) { + return fields.get(header); + } + return null; + } + + private static class RowEndState implements State { + @Override + public State transition(StateMachine sm, char[] buff, int i, int count) { + return ROW_END_STATE; + } + } + + private static class StringQuoteValueState implements State { + + @Override + public State transition(StateMachine sm, char[] buff, int i, int count) + throws CsvParserException { + State state = this; + char ch; + for (; i < count; i++) { + ch = buff[i]; + sm.processLocation(ch); + if (ch == EOF) { + handleEndOfTheRow(sm, false); + return ROW_END_STATE; + } + if (ch == Constants.LineTerminator.CR) { + CsvUtils.setCarriageTokenPresent(true); + continue; + } else if (!(CsvUtils.isCarriageTokenPresent && ch == Constants.LineTerminator.LF)) { + CsvUtils.setCarriageTokenPresent(false); + } + + if (ch == sm.config.textEnclosure) { + if (sm.isQuoteClosed) { + sm.append(ch); + sm.isValueStart = true; + continue; + } + sm.isQuoteClosed = true; + } else if (ch == sm.config.delimiter && sm.isQuoteClosed) { + addRowValue(sm, false); + state = ROW_START_STATE; + sm.isQuoteClosed = false; + break; + } else if (sm.isNewLineOrEof(ch) && sm.isQuoteClosed) { + handleEndOfTheRow(sm, false); + state = ROW_START_STATE; + sm.isQuoteClosed = false; + break; + } else if (ch == sm.config.escapeChar) { + state = STRING_ESCAPE_VALUE_STATE; + sm.prevState = this; + sm.isQuoteClosed = false; + break; + } else if (!sm.isQuoteClosed && !sm.peek().isEmpty() && ch == EOF) { + throw new CsvParserException("unexpected end of csv stream"); + } else { + if (!sm.isQuoteClosed) { + sm.append(ch); + } else { + sm.append(sm.config.textEnclosure); + sm.append(ch); + sm.isQuoteClosed = false; + } + sm.isValueStart = true; + state = this; + } + } + sm.index = i + 1; + return state; + } + } + + private static class HeaderQuoteValueState implements State { + + @Override + public State transition(StateMachine sm, char[] buff, int i, int count) + throws CsvParserException { + State state = this; + char ch; + for (; i < count; i++) { + ch = buff[i]; + sm.processLocation(ch); + if (ch == EOF) { + handleEndOfTheRow(sm); + return ROW_END_STATE; + } + if (ch == Constants.LineTerminator.CR) { + CsvUtils.setCarriageTokenPresent(true); + continue; + } else if (!(CsvUtils.isCarriageTokenPresent && ch == Constants.LineTerminator.LF)) { + CsvUtils.setCarriageTokenPresent(false); + } + + if (ch == sm.config.textEnclosure) { + sm.isQuoteClosed = true; + } else if (ch == sm.config.delimiter && sm.isQuoteClosed) { + addHeader(sm, false); + sm.columnIndex++; + sm.isQuoteClosed = false; + state = HEADER_START_STATE; + break; + } else if (sm.isNewLineOrEof(ch) && sm.isQuoteClosed) { + handleEndOfTheHeader(sm, false); + state = HEADER_END_STATE; + sm.isQuoteClosed = false; + break; + } else if (!sm.isQuoteClosed && ch == sm.config.escapeChar) { + sm.isQuoteClosed = false; + sm.prevState = this; + state = HEADER_ESCAPE_CHAR_STATE; + break; + } else if (!sm.isQuoteClosed && ch == EOF) { + throw new CsvParserException("unexpected end of csv stream"); + } else { + if (!sm.isQuoteClosed) { + sm.append(ch); + } else { + sm.append(sm.config.textEnclosure); + sm.append(ch); + sm.isQuoteClosed = false; + } + sm.isValueStart = true; + state = this; + continue; + } + break; + } + sm.index = i + 1; + return state; + } + } + + private static class StringValueUnicodeHexProcessingState extends UnicodeHexProcessingState { + + @Override + protected State getSourceState() { + return STRING_UNICODE_CHAR_STATE; + } + + } + + /** + * Represents the state where an escaped unicode character in hex format is processed + * from a field name. + */ + private static class HeaderUnicodeHexProcessingState extends UnicodeHexProcessingState { + + @Override + protected State getSourceState() { + return HEADER_UNICODE_CHAR_STATE; + } + } + + /** + * Represents the state where an escaped unicode character in hex format is processed. + */ + private abstract static class UnicodeHexProcessingState implements State { + + protected abstract State getSourceState(); + + @Override + public State transition(StateMachine sm, char[] buff, int i, int count) throws CsvParserException { + State state = null; + char ch; + for (; i < count; i++) { + ch = buff[i]; + sm.processLocation(ch); + if (ch == EOF) { + handleEndOfTheRow(sm); + return ROW_END_STATE; + } + if (ch == Constants.LineTerminator.CR) { + CsvUtils.setCarriageTokenPresent(true); + continue; + } else if (!(CsvUtils.isCarriageTokenPresent && ch == Constants.LineTerminator.LF)) { + CsvUtils.setCarriageTokenPresent(false); + } + + if ((ch >= '0' && ch <= '9') || (ch >= 'A' && ch <= 'F') || (ch >= 'a' && ch <= 'f')) { + sm.hexBuilder.append(ch); + sm.isValueStart = true; + if (sm.hexBuilder.length() >= 4) { + sm.append(this.extractUnicodeChar(sm)); + this.reset(sm); + state = sm.prevState; + sm.prevState = this; + break; + } + state = this; + continue; + } + this.reset(sm); + StateMachine.throwExpected("hexadecimal value of an unicode character"); + break; + } + sm.index = i + 1; + return state; + } + + private void reset(StateMachine sm) { + sm.hexBuilder.setLength(0); + } + + private char extractUnicodeChar(StateMachine sm) { + return StringEscapeUtils.unescapeJava("\\u" + sm.hexBuilder.toString()).charAt(0); + } + + } + + private static class HeaderEscapedCharacterProcessingState extends EscapedCharacterProcessingState { + + @Override + protected State getSourceState() { + return HEADER_ESCAPE_CHAR_STATE; + } + } + + private static class StringValueEscapedCharacterProcessingState extends EscapedCharacterProcessingState { + + @Override + protected State getSourceState() { + return STRING_ESCAPE_VALUE_STATE; + } + } + + private abstract static class EscapedCharacterProcessingState implements State { + + protected abstract State getSourceState(); + + @Override + public State transition(StateMachine sm, char[] buff, int i, int count) throws CsvParserException { + State state = null; + char ch; + if (i < count) { + ch = buff[i]; + sm.processLocation(ch); + if (ch == Constants.LineTerminator.CR) { + CsvUtils.setCarriageTokenPresent(true); + } else if (!(CsvUtils.isCarriageTokenPresent && ch == Constants.LineTerminator.LF)) { + CsvUtils.setCarriageTokenPresent(false); + } + if (ch == EOF) { + handleEndOfTheRow(sm); + return ROW_END_STATE; + } + switch (ch) { + case '"': + sm.append(QUOTES); + state = sm.prevState; + break; + case '\\': + sm.append(REV_SOL); + state = sm.prevState; + break; + case '/': + sm.append(SOL); + state = sm.prevState; + break; + case 'b': + sm.append(BACKSPACE); + state = sm.prevState; + break; + case 'f': + sm.append(FORMFEED); + state = sm.prevState; + break; + case 'n': + sm.append(NEWLINE); + state = sm.prevState; + break; + case 'r': + sm.append(CR); + state = sm.prevState; + break; + case 't': + sm.append(HZ_TAB); + state = sm.prevState; + break; + case 'u': + if (this.getSourceState() == STRING_ESCAPE_VALUE_STATE) { + state = STRING_UNICODE_CHAR_STATE; + } else if (this.getSourceState() == HEADER_ESCAPE_CHAR_STATE) { + state = HEADER_UNICODE_CHAR_STATE; + } else { + throw new CsvParserException("unknown source '" + this.getSourceState() + + "' in escape char processing state"); + } + break; + default: + StateMachine.throwExpected("escaped characters"); + } + } + sm.index = i + 1; + return state; + } + } + + public static boolean isEndOfTheRowAndValueIsNotEmpty(CsvParser.StateMachine sm, char ch) { + return sm.isNewLineOrEof(ch) && (ch == EOF || !(sm.isCurrentCsvNodeEmpty && sm.peek().isBlank())); + } + + public static boolean isEndOfTheHeaderRow(CsvParser.StateMachine sm, char ch) { + return sm.isNewLineOrEof(ch); + } + + public static class CsvParserException extends Exception { + public CsvParserException(String msg) { + super(msg); + } + } + } +} diff --git a/native/src/main/java/io/ballerina/stdlib/data/csvdata/csv/CsvTraversal.java b/native/src/main/java/io/ballerina/stdlib/data/csvdata/csv/CsvTraversal.java new file mode 100644 index 0000000..091a4b8 --- /dev/null +++ b/native/src/main/java/io/ballerina/stdlib/data/csvdata/csv/CsvTraversal.java @@ -0,0 +1,802 @@ +/* + * Copyright (c) 2024, WSO2 LLC. (https://www.wso2.com). + * + * 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 + * + * 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 io.ballerina.stdlib.data.csvdata.csv; + +import io.ballerina.runtime.api.PredefinedTypes; +import io.ballerina.runtime.api.TypeTags; +import io.ballerina.runtime.api.creators.TypeCreator; +import io.ballerina.runtime.api.creators.ValueCreator; +import io.ballerina.runtime.api.flags.SymbolFlags; +import io.ballerina.runtime.api.types.ArrayType; +import io.ballerina.runtime.api.types.Field; +import io.ballerina.runtime.api.types.IntersectionType; +import io.ballerina.runtime.api.types.MapType; +import io.ballerina.runtime.api.types.RecordType; +import io.ballerina.runtime.api.types.TupleType; +import io.ballerina.runtime.api.types.Type; +import io.ballerina.runtime.api.types.UnionType; +import io.ballerina.runtime.api.utils.StringUtils; +import io.ballerina.runtime.api.utils.TypeUtils; +import io.ballerina.runtime.api.values.BArray; +import io.ballerina.runtime.api.values.BError; +import io.ballerina.runtime.api.values.BMap; +import io.ballerina.runtime.api.values.BString; +import io.ballerina.runtime.api.values.BTypedesc; +import io.ballerina.stdlib.data.csvdata.utils.CsvConfig; +import io.ballerina.stdlib.data.csvdata.utils.CsvUtils; +import io.ballerina.stdlib.data.csvdata.utils.DataUtils; +import io.ballerina.stdlib.data.csvdata.utils.DiagnosticErrorCode; +import io.ballerina.stdlib.data.csvdata.utils.DiagnosticLog; + +import java.util.ArrayDeque; +import java.util.ArrayList; +import java.util.Deque; +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Optional; + +import static io.ballerina.stdlib.data.csvdata.utils.CsvUtils.SkipMappedValue; +import static io.ballerina.stdlib.data.csvdata.utils.CsvUtils.UnMappedValue; +import static io.ballerina.stdlib.data.csvdata.utils.CsvUtils.checkRequiredFieldsAndLogError; +import static io.ballerina.stdlib.data.csvdata.utils.CsvUtils.checkTypeCompatibility; +import static io.ballerina.stdlib.data.csvdata.utils.CsvUtils.convertToBasicType; +import static io.ballerina.stdlib.data.csvdata.utils.CsvUtils.createHeaders; +import static io.ballerina.stdlib.data.csvdata.utils.CsvUtils.getMutableType; +import static io.ballerina.stdlib.data.csvdata.utils.CsvUtils.getSkipDataRows; +import static io.ballerina.stdlib.data.csvdata.utils.CsvUtils.getTheActualExpectedType; +import static io.ballerina.stdlib.data.csvdata.utils.CsvUtils.isBasicType; +import static io.ballerina.stdlib.data.csvdata.utils.CsvUtils.isHeaderFieldsEmpty; +import static io.ballerina.stdlib.data.csvdata.utils.CsvUtils.processNameAnnotationsAndBuildCustomFieldMap; +import static io.ballerina.stdlib.data.csvdata.utils.CsvUtils.validateExpectedArraySize; + +/** + * Convert Csv value to a ballerina record. + * + * @since 0.1.0 + */ +public class CsvTraversal { + private static final ThreadLocal tlCsvTree = ThreadLocal.withInitial(CsvTree::new); + public static Object traverse(BArray csv, CsvConfig config, BTypedesc type) { + CsvTree csvTree = tlCsvTree.get(); + try { + Object convertedValue = csvTree.traverseCsv(csv, config, type.getDescribingType()); + return DataUtils.validateConstraints(convertedValue, type, config.enableConstraintValidation); + } catch (BError e) { + return e; + } finally { + csvTree.reset(); + } + } + + public static Object traverse(BArray csv, CsvConfig config, BTypedesc typed, Type type) { + CsvTree csvTree = tlCsvTree.get(); + try { + Object convertedValue = csvTree.traverseCsv(csv, config, type); + return DataUtils.validateConstraints(convertedValue, typed, config.enableConstraintValidation); + } catch (BError e) { + return e; + } finally { + csvTree.reset(); + } + } + + static class CsvTree { + Object currentCsvNode; + Field currentField; + Map fieldHierarchy = new HashMap<>(); + Map updatedRecordFieldNames = new HashMap<>(); + Map headerFieldHierarchy = new HashMap<>(); + HashSet fields = new HashSet<>(); + Type restType; + Deque fieldNames = new ArrayDeque<>(); + BArray rootCsvNode; + Type expectedArrayElementType; + Type sourceArrayElementType; + CsvConfig config; + String[] headers = null; + int arraySize = 0; + + void reset() { + currentCsvNode = null; + currentField = null; + fieldHierarchy.clear(); + updatedRecordFieldNames.clear(); + headerFieldHierarchy.clear(); + fields.clear();; + restType = null; + fieldNames.clear(); + rootCsvNode = null; + expectedArrayElementType = null; + sourceArrayElementType = null; + config = null; + headers = null; + arraySize = 0; + } + + + void resetForUnionTypes() { + currentCsvNode = null; + currentField = null; + fieldHierarchy.clear(); + updatedRecordFieldNames.clear(); + headerFieldHierarchy.clear(); + fields.clear();; + restType = null; + fieldNames.clear(); + rootCsvNode = null; + expectedArrayElementType = null; + headers = null; + arraySize = 0; + } + + CsvTree() { + reset(); + } + + @SuppressWarnings("unchecked") + public Object traverseCsv(BArray csv, CsvConfig config, Type type) { + this.config = config; + sourceArrayElementType = TypeUtils.getReferredType(getSourceElementTypeForTupleAndArrays(csv)); + Type referredType = TypeUtils.getReferredType(type); + int sourceArraySize = (int) csv.getLength(); + if (referredType.getTag() == TypeTags.INTERSECTION_TAG) { + Optional mutableType = getMutableType((IntersectionType) referredType); + if (mutableType.isPresent()) { + return CsvCreator.constructReadOnlyValue(traverseCsv(csv, config, mutableType.get())); + } + } + + if (referredType.getTag() != TypeTags.UNION_TAG) { + if (referredType.getTag() == TypeTags.ARRAY_TAG) { + Type arrayElementType = TypeUtils.getReferredType(((ArrayType) referredType).getElementType()); + if (arrayElementType.getTag() == TypeTags.INTERSECTION_TAG) { + Optional mutableType = getMutableType((IntersectionType) arrayElementType); + if (mutableType.isPresent()) { + return CsvCreator.constructReadOnlyValue( + traverseCsv(csv, config, TypeCreator.createArrayType( + mutableType.get() + )) + ); + } + } + } + int expectedArraySize = ((ArrayType) referredType).getSize(); + setRootCsvNodeForNonUnionArrays(referredType, type); + validateExpectedArraySize(expectedArraySize, sourceArraySize); + traverseCsvWithExpectedType(sourceArraySize, csv, type); + } else { + traverseCsvWithUnionExpectedType(referredType, type, sourceArraySize, csv); + } + return rootCsvNode; + } + + private void traverseCsvWithUnionExpectedType(Type referredType, Type type, int sourceArraySize, + BArray csv) { + for (Type memberType: ((UnionType) referredType).getMemberTypes()) { + Type mType = TypeUtils.getReferredType(memberType); + if (mType.getTag() == TypeTags.ARRAY_TAG) { + int expectedArraySize = ((ArrayType) mType).getSize(); + resetForUnionTypes(); + try { + setRootCsvNodeForNonUnionArrays(mType, mType); + validateExpectedArraySize(expectedArraySize, sourceArraySize); + traverseCsvWithExpectedType(sourceArraySize, csv, type); + return; + } catch (Exception ex) { + // ignore + } + } + } + throw DiagnosticLog.error(DiagnosticErrorCode.SOURCE_CANNOT_CONVERT_INTO_EXP_TYPE, type); + } + + private void traverseCsvWithExpectedType(int sourceArraySize, + BArray csv, Type type) { + boolean isIntersection = false; + if (expectedArrayElementType.getTag() == TypeTags.INTERSECTION_TAG) { + Optional mutableType = getMutableType((IntersectionType) expectedArrayElementType); + if (mutableType.isPresent()) { + isIntersection = true; + expectedArrayElementType = mutableType.get(); + } + } + + switch (expectedArrayElementType.getTag()) { + case TypeTags.RECORD_TYPE_TAG: + case TypeTags.MAP_TAG: + traverseCsvArrayMembersWithMapAsCsvElementType(sourceArraySize, csv, + expectedArrayElementType, isIntersection); + break; + case TypeTags.ARRAY_TAG: + case TypeTags.TUPLE_TAG: + traverseCsvArrayMembersWithArrayAsCsvElementType(sourceArraySize, csv, + expectedArrayElementType, isIntersection); + break; + case TypeTags.UNION_TAG: + traverseCsvArrayMembersWithUnionAsCsvElementType(sourceArraySize, csv, + (UnionType) expectedArrayElementType, type); + break; + case TypeTags.INTERSECTION_TAG: + for (Type constituentType : ((IntersectionType) expectedArrayElementType).getConstituentTypes()) { + if (constituentType.getTag() == TypeTags.READONLY_TAG) { + continue; + } + config.stringConversion = true; + CsvCreator.constructReadOnlyValue(this.traverseCsv( + csv, config, TypeCreator.createArrayType(constituentType))); + } + break; + default: + throw DiagnosticLog.error(DiagnosticErrorCode.SOURCE_CANNOT_CONVERT_INTO_EXP_TYPE, type); + } + } + + public void traverseCsvArrayMembersWithMapAsCsvElementType(long length, BArray csv, Type expectedArrayType, + boolean isIntersection) { + Object rowValue; + ArrayType arrayType = (ArrayType) rootCsvNode.getType(); + for (int i = 0; i < length; i++) { + if (ignoreRow(i + 1, config.skipLines)) { + continue; + } + if (arrayType.getState() == ArrayType.ArrayState.CLOSED && + arrayType.getSize() - 1 < this.arraySize) { + break; + } + + rowValue = traverseCsvElementWithMapOrRecord(csv.get(i), expectedArrayType); + if (isIntersection) { + rowValue = CsvCreator.constructReadOnlyValue(rowValue); + } + rootCsvNode.add(this.arraySize, rowValue); + this.arraySize++; + } + } + + public void traverseCsvArrayMembersWithArrayAsCsvElementType(long length, BArray csv, Type expectedArrayType, + boolean isIntersection) { + Object rowValue; + ArrayType arrayType = (ArrayType) rootCsvNode.getType(); + for (int i = 0; i < length; i++) { + if (ignoreRow(i + 1, config.skipLines)) { + continue; + } + if (arrayType.getState() == ArrayType.ArrayState.CLOSED && + arrayType.getSize() - 1 < this.arraySize) { + break; + } + + rowValue = traverseCsvElementWithArray(csv.get(i), expectedArrayType); + if (isIntersection) { + rowValue = CsvCreator.constructReadOnlyValue(rowValue); + } + rootCsvNode.add(this.arraySize, rowValue); + this.arraySize++; + } + } + + public void traverseCsvArrayMembersWithUnionAsCsvElementType(long length, BArray csv, + UnionType expectedArrayType, Type type) { + Object rowValue; + ArrayType arrayType = (ArrayType) rootCsvNode.getType(); + for (int i = 0; i < length; i++) { + boolean isCompatible = false; + if (ignoreRow(i + 1, config.skipLines)) { + continue; + } + if (arrayType.getState() == ArrayType.ArrayState.CLOSED && + arrayType.getSize() - 1 < this.arraySize) { + break; + } + + Object csvData = csv.get(i); + for (Type memberType: expectedArrayType.getMemberTypes()) { + boolean isIntersection = false; + try { + memberType = TypeUtils.getReferredType(memberType); + if (memberType.getTag() == TypeTags.INTERSECTION_TAG) { + Optional mutableType = getMutableType((IntersectionType) memberType); + if (mutableType.isPresent()) { + isIntersection = true; + memberType = mutableType.get(); + } + } + + if (memberType.getTag() == TypeTags.MAP_TAG + || memberType.getTag() == TypeTags.RECORD_TYPE_TAG) { + rowValue = traverseCsvElementWithMapOrRecord(csvData, memberType); + } else if (memberType.getTag() == TypeTags.TUPLE_TAG + || memberType.getTag() == TypeTags.ARRAY_TAG) { + rowValue = traverseCsvElementWithArray(csvData, memberType); + } else { + continue; + } + if (isIntersection) { + rowValue = CsvCreator.constructReadOnlyValue(rowValue); + } + rootCsvNode.add(this.arraySize, rowValue); + this.arraySize++; + isCompatible = true; + break; + } catch (Exception e) { + int a = 1; + } + } + if (!isCompatible) { + throw DiagnosticLog.error(DiagnosticErrorCode.SOURCE_CANNOT_CONVERT_INTO_EXP_TYPE, type); + } + } + } + + private static boolean ignoreRow(int index, Object skipLinesConfig) { + long[] skipLines = getSkipDataRows(skipLinesConfig); + for (long skipLine: skipLines) { + if (skipLine == index) { + return true; + } + } + return false; + } + + public Object traverseCsvElementWithMapOrRecord(Object csvElement, Type expectedType) { + expectedType = TypeUtils.getReferredType(expectedType); + switch (expectedType.getTag()) { + case TypeTags.RECORD_TYPE_TAG: + RecordType recordType = (RecordType) expectedType; + this.fieldHierarchy = new HashMap<>(recordType.getFields()); + fields = new HashSet<>(recordType.getFields().keySet()); + this.updatedRecordFieldNames = processNameAnnotationsAndBuildCustomFieldMap( + recordType, fieldHierarchy); + this.headerFieldHierarchy = new HashMap<>(recordType.getFields()); + this.restType = recordType.getRestFieldType(); + currentCsvNode = ValueCreator.createRecordValue(recordType.getPackage(), recordType.getName()); + traverseCsvMap(csvElement, expectedType, false); + break; + case TypeTags.MAP_TAG: + MapType mapType = (MapType) expectedType; + currentCsvNode = ValueCreator.createMapValue(mapType); + traverseCsvMap(csvElement, expectedType, true); + break; + default: + throw DiagnosticLog.error(DiagnosticErrorCode.INVALID_TYPE, expectedType); + } + return currentCsvNode; + } + + public Object traverseCsvElementWithArray(Object csvElement, Type expectedType) { + expectedType = TypeUtils.getReferredType(expectedType); + switch (expectedType.getTag()) { + case TypeTags.ARRAY_TAG: + ArrayType arrayType = (ArrayType) expectedType; + currentCsvNode = ValueCreator.createArrayValue(arrayType); + traverseArrayValue(csvElement, arrayType); + break; + case TypeTags.TUPLE_TAG: + TupleType tupleType = (TupleType) expectedType; + this.restType = tupleType.getRestType(); + currentCsvNode = ValueCreator.createTupleValue(tupleType); + traverseArrayValue(csvElement, tupleType); + break; + default: + throw DiagnosticLog.error(DiagnosticErrorCode.INVALID_TYPE, expectedType); + } + return currentCsvNode; + } + + private void traverseArrayValue(Object csvElement, Type type) { + int expectedTypeSize = getTheActualExpectedType(type); + if (csvElement instanceof BMap) { + BMap map = (BMap) csvElement; + constructArrayValuesFromMap(map, type, expectedTypeSize == -1 ? map.size() : expectedTypeSize); + } else if (csvElement instanceof BArray) { + BArray array = (BArray) csvElement; + constructArrayValuesFromArray(array, type, expectedTypeSize == -1 ? array.size() : expectedTypeSize); + } + } + + private void constructArrayValuesFromArray(BArray csvElement, Type type, int expectedSize) { + int index = 0; + for (int i = 0; i < csvElement.getLength(); i++) { + if (config.allowDataProjection && index >= expectedSize) { + break; + } + Type memberType = getArrayOrTupleMemberType(type, index); + if (memberType != null) { + addValuesToArrayType(csvElement.get(i), memberType, index, + currentCsvNode, config); + } + index++; + } + } + + private void constructArrayValuesFromMap(BMap map, Type type, int expectedSize) { + int size = map.size(); + BString[] keys = new BString[size]; + int index = 0; + if (config.headersOrder != null) { + String[] headerOrder = config.headersOrder.getStringArray(); + if (headerOrder.length != size) { + throw DiagnosticLog.error(DiagnosticErrorCode.INVALID_HEADER_NAMES_LENGTH); + } + for (int i = 0; i < size; i++) { + keys[i] = StringUtils.fromString(headerOrder[i]); + } + } else if (config.customHeader == null) { + keys = map.getKeys(); + } else { + if (this.headers == null) { + this.headers = createHeaders(new String[size], config); + } + if (this.headers.length != size) { + throw DiagnosticLog.error(DiagnosticErrorCode.INVALID_CUSTOM_HEADER_LENGTH); + } + for (int i = 0; i < size; i++) { + keys[i] = StringUtils.fromString(this.headers[i]); + } + } + for (BString key: keys) { + if (!map.containsKey(key)) { + throw DiagnosticLog.error(DiagnosticErrorCode.INVALID_CUSTOM_HEADER, key); + } + Object v = map.get(key); + if (config.allowDataProjection && index >= expectedSize) { + break; + } + Type memberType = getArrayOrTupleMemberType(type, index); + if (memberType != null) { + addValuesToArrayType(v, memberType, index, + currentCsvNode, config); + } + index++; + } + } + + private boolean isArrayOrTupleRestTypeMember(Type type, int index) { + if (type instanceof ArrayType) { + return false; + } + return ((TupleType) type).getTupleTypes().size() < index + 1; + } + + private Type getArrayOrTupleMemberType(Type type, int index) { + if (type instanceof TupleType) { + TupleType tupleType = (TupleType) type; + List tupleTypes = tupleType.getTupleTypes(); + if (tupleTypes.size() >= index + 1) { + return tupleTypes.get(index); + } + if (restType != null) { + return restType; + } else { + if (config.allowDataProjection) { + return null; + } + throw DiagnosticLog.error(DiagnosticErrorCode.INVALID_EXPECTED_TUPLE_SIZE, tupleTypes.size()); + } + } + ArrayType arrayType = (ArrayType) type; + if (arrayType.getSize() != -1 && arrayType.getSize() <= index) { + if (config.allowDataProjection) { + return null; + } + throw DiagnosticLog.error(DiagnosticErrorCode.INVALID_EXPECTED_ARRAY_SIZE, arrayType.getSize()); + } + return ((ArrayType) type).getElementType(); + } + + private void traverseCsvMap(Object csvElement, Type expectedType, boolean mappingType) { + if (csvElement instanceof BMap map) { + traverseMapValueWithMapAsExpectedType(map, mappingType, expectedType); + } else if (csvElement instanceof BArray) { + traverseArrayValueWithMapAsExpectedType((BArray) csvElement, mappingType, expectedType); + } else { + throw DiagnosticLog.error(DiagnosticErrorCode.INVALID_CSV_DATA_FORMAT); + } + } + + private boolean checkExpectedTypeMatchWithHeaders(Type expectedType, BArray csvElement, int arraySize) { + if (arraySize < this.headers.length) { + return false; + } + if (expectedType instanceof MapType) { + return true; + } + Type type = csvElement.getType(); + if (type instanceof TupleType) { + return checkExpectedTypeMatchWithHeadersForTuple(expectedType, (TupleType) type); + } else { + return checkExpectedTypeMatchWithHeadersForArray(expectedType); + } + } + + private boolean checkExpectedTypeMatchWithHeadersForTuple(Type expectedType, TupleType tupleType) { + Type type; + List tupleTypes = tupleType.getTupleTypes(); + Type tupleRestType = tupleType.getRestType(); + + if (expectedType instanceof RecordType) { + if (this.restType != null + && (this.restType.getTag() == TypeTags.ANYDATA_TAG + || this.restType.getTag() == TypeTags.JSON_TAG)) { + return true; + } + + for (int i = 0; i < this.headers.length; i++) { + if (i >= tupleTypes.size()) { + type = tupleRestType; + } else { + type = tupleTypes.get(i); + } + String header = this.headers[i]; + Field field = this.headerFieldHierarchy.remove(header); + + if (field != null) { + if (!config.stringConversion && type.getTag() != field.getFieldType().getTag()) { + return false; + } + continue; + } + + if ((tupleRestType != null && (type == this.restType || this.restType == tupleRestType))) { + continue; + } + + if (isHeaderFieldsEmpty(this.headerFieldHierarchy)) { + continue; + } + return false; + } + return true; + } + return false; + } + + private boolean checkExpectedTypeMatchWithHeadersForArray(Type expectedType) { + if (expectedType instanceof RecordType) { + if (this.restType != null) { + return true; + } + + for (String key: this.fieldHierarchy.keySet()) { + for (String header: this.headers) { + if (key.equals(this.updatedRecordFieldNames.get(header))) { + return true; + } + } + } + } + return false; + } + + private void traverseArrayValueWithMapAsExpectedType(BArray csvElement, + boolean mappingType, Type expectedType) { + int arraySize = csvElement.size(); + String[] headers = new String[arraySize]; + if (this.headers == null) { + this.headers = createHeaders(headers, config); + } + boolean headersMatchWithExpType = checkExpectedTypeMatchWithHeaders(expectedType, csvElement, arraySize); + if (!headersMatchWithExpType) { + throw DiagnosticLog.error(DiagnosticErrorCode.INVALID_CONVERSION_FOR_ARRAY_TO_MAP, + csvElement, expectedType); + } + addValuesToMapType(csvElement, arraySize, mappingType, expectedType); + } + + private void addValuesToMapType(BArray csvElement, int arraySize, boolean mappingType, Type expectedType) { + Type fieldType; + BString key; + for (int i = 1; i <= arraySize; i++) { + key = StringUtils.fromString(this.headers[i - 1]); + if (!mappingType) { + if (!isKeyBelongsToNonRestType(csvElement.get(i - 1), key)) { + continue; + } + fieldType = TypeUtils.getReferredType(currentField.getFieldType()); + } else { + addFieldInMapType(key); + fieldType = ((MapType) expectedType).getConstrainedType();; + } + addCurrentFieldValue(fieldType, csvElement.get(i - 1), key, mappingType); + } + checkRequiredFieldsAndLogError(fieldHierarchy, config.absentAsNilableType); + } + + private void traverseMapValueWithMapAsExpectedType( + BMap map, boolean mappingType, Type expType) { + Type currentFieldType; + for (BString key : map.getKeys()) { + if (!mappingType) { + if (!isKeyBelongsToNonRestType(map.get(key), key)) { + continue; + } + currentFieldType = TypeUtils.getReferredType(currentField.getFieldType()); + } else { + addFieldInMapType(key); + currentFieldType = TypeUtils.getReferredType( + ((MapType) expType).getConstrainedType() + ); + } + addCurrentFieldValue(currentFieldType, map.get(key), key, mappingType); + } + checkRequiredFieldsAndLogError(fieldHierarchy, config.absentAsNilableType); + } + + private boolean isKeyBelongsToNonRestType(Object value, BString key) { + String keyStr = StringUtils.getStringValue(key); + String fieldName = CsvUtils.getUpdatedHeaders(this.updatedRecordFieldNames, + keyStr, this.fields.contains(keyStr)); + currentField = fieldHierarchy.remove(fieldName); + if (currentField == null) { + // Add to the rest field + if (restType != null) { + Type restFieldType = TypeUtils.getReferredType(restType); + addRestField(restFieldType, key, value); + return false; + } + if (config.allowDataProjection) { + return false; + } + throw DiagnosticLog.error(DiagnosticErrorCode.NO_FIELD_FOR_HEADER, key); + } + fieldNames.push(currentField.getFieldName()); + return true; + } + + private void addFieldInMapType(BString key) { + fieldNames.push(key.toString()); + } + + private Object getFieldValue(Type type, Object csvMember, boolean isRecursive) { + Type fieldType = TypeUtils.getReferredType(type); + Object nilValue = config.nilValue; + if (!isRecursive && config.nilAsOptionalField && !fieldType.isNilable() + && CsvUtils.isNullValue(nilValue, csvMember) + && currentField != null && SymbolFlags.isFlagOn(currentField.getFlags(), SymbolFlags.OPTIONAL)) { + return SkipMappedValue.createSkippedValue(); + } + if (config.stringConversion && csvMember instanceof BString str) { + Object convertedValue = CsvCreator.convertToExpectedType(str, type, config); + if (!(convertedValue instanceof BError)) { + return convertedValue; + } + } else { + switch (fieldType.getTag()) { + case TypeTags.NULL_TAG: + case TypeTags.BOOLEAN_TAG: + case TypeTags.INT_TAG: + case TypeTags.FLOAT_TAG: + case TypeTags.DECIMAL_TAG: + case TypeTags.STRING_TAG: + case TypeTags.JSON_TAG: + case TypeTags.ANYDATA_TAG: + case TypeTags.CHAR_STRING_TAG: + case TypeTags.BYTE_TAG: + case TypeTags.SIGNED8_INT_TAG: + case TypeTags.SIGNED16_INT_TAG: + case TypeTags.SIGNED32_INT_TAG: + case TypeTags.UNSIGNED8_INT_TAG: + case TypeTags.UNSIGNED16_INT_TAG: + case TypeTags.UNSIGNED32_INT_TAG: + case TypeTags.FINITE_TYPE_TAG: + if (checkTypeCompatibility(fieldType, csvMember, config.stringConversion)) { + Object value = convertToBasicType(csvMember, fieldType, config); + if (!(value instanceof BError)) { + return value; + } + } + break; + case TypeTags.UNION_TAG: + for (Type memberType : ((UnionType) fieldType).getMemberTypes()) { + memberType = TypeUtils.getReferredType(memberType); + if (!isBasicType(memberType)) { + throw DiagnosticLog.error(DiagnosticErrorCode + .EXPECTED_TYPE_CAN_ONLY_CONTAIN_BASIC_TYPES, memberType); + } + Object value = getFieldValue(memberType, csvMember, true); + if (!(value instanceof BError || value instanceof UnMappedValue)) { + return value; + } + } + break; + case TypeTags.INTERSECTION_TAG: + Type effectiveType = ((IntersectionType) fieldType).getEffectiveType(); + effectiveType = TypeUtils.getReferredType(effectiveType); + if (!SymbolFlags.isFlagOn(SymbolFlags.READONLY, effectiveType.getFlags())) { + throw DiagnosticLog.error(DiagnosticErrorCode.INVALID_TYPE, type); + } + for (Type constituentType : ((IntersectionType) fieldType).getConstituentTypes()) { + constituentType = TypeUtils.getReferredType(constituentType); + if (constituentType.getTag() == TypeTags.READONLY_TAG) { + continue; + } + return CsvCreator.constructReadOnlyValue(getFieldValue(constituentType, + csvMember, true)); + } + break; + default: + throw DiagnosticLog.error(DiagnosticErrorCode.INVALID_EXPECTED_TYPE, type); + } + } + return UnMappedValue.createUnMappedValue(); + } + + private void addRestField(Type type, BString key, Object csvMember) { + Object value = getFieldValue(type, csvMember, false); + if (!(value instanceof UnMappedValue)) { + ((BMap) currentCsvNode).put(key, value); + } + } + + private void addCurrentFieldValue(Type type, Object recValue, BString key, boolean isMapType) { + Object value = getFieldValue(type, recValue, false); + if (!(value instanceof UnMappedValue || value instanceof SkipMappedValue)) { + ((BMap) currentCsvNode).put(StringUtils.fromString(fieldNames.pop()), value); + return; + } + + if (isMapType || value instanceof SkipMappedValue) { + return; + } + throw DiagnosticLog.error(DiagnosticErrorCode.INVALID_TYPE_FOR_FIELD, recValue, key); + } + + public void addValuesToArrayType(Object arrayValue, Type type, int index, + Object currentCsvNode, CsvConfig config) { + Object value = getFieldValue(type, arrayValue, false); + boolean isArrayType = type instanceof ArrayType; + if (!(value instanceof UnMappedValue)) { + if (isArrayType) { + ArrayType arrayType = (ArrayType) TypeUtils.getType(type); + if (arrayType.getState() == ArrayType.ArrayState.CLOSED && + arrayType.getSize() - 1 < index) { + return; + } + } + ((BArray) currentCsvNode).add(index, value); + return; + } + throw DiagnosticLog.error(DiagnosticErrorCode.INVALID_TYPE_FOR_ARRAY, arrayValue, index, type); + } + + private void setRootCsvNodeForNonUnionArrays(Type referredType, Type type) { + referredType = TypeUtils.getReferredType(referredType); + if (referredType.getTag() == TypeTags.ARRAY_TAG) { + ArrayType arrayType = (ArrayType) referredType; + rootCsvNode = ValueCreator.createArrayValue(arrayType); + expectedArrayElementType = TypeUtils.getReferredType((arrayType).getElementType()); + return; + } + throw DiagnosticLog.error(DiagnosticErrorCode.INVALID_TYPE, type, PredefinedTypes.TYPE_ANYDATA_ARRAY); + } + + private Type getSourceElementTypeForTupleAndArrays(BArray csv) { + List memberTypes = new ArrayList<>(); + if (csv.getType() instanceof TupleType tupleType) { + for (Type memberType: tupleType.getTupleTypes()) { + memberTypes.add(memberType); + } + return TypeCreator.createUnionType(memberTypes); + } + return csv.getElementType(); + } + } +} diff --git a/native/src/main/java/io/ballerina/stdlib/data/csvdata/csv/Native.java b/native/src/main/java/io/ballerina/stdlib/data/csvdata/csv/Native.java index 1f5d3d6..dde4144 100644 --- a/native/src/main/java/io/ballerina/stdlib/data/csvdata/csv/Native.java +++ b/native/src/main/java/io/ballerina/stdlib/data/csvdata/csv/Native.java @@ -19,11 +19,24 @@ package io.ballerina.stdlib.data.csvdata.csv; import io.ballerina.runtime.api.Environment; +import io.ballerina.runtime.api.Future; import io.ballerina.runtime.api.values.BArray; +import io.ballerina.runtime.api.values.BError; import io.ballerina.runtime.api.values.BMap; +import io.ballerina.runtime.api.values.BObject; import io.ballerina.runtime.api.values.BStream; import io.ballerina.runtime.api.values.BString; import io.ballerina.runtime.api.values.BTypedesc; +import io.ballerina.stdlib.data.csvdata.io.DataReaderTask; +import io.ballerina.stdlib.data.csvdata.io.DataReaderThreadPool; +import io.ballerina.stdlib.data.csvdata.utils.Constants; +import io.ballerina.stdlib.data.csvdata.utils.CsvConfig; +import io.ballerina.stdlib.data.csvdata.utils.DiagnosticErrorCode; +import io.ballerina.stdlib.data.csvdata.utils.DiagnosticLog; + +import java.io.ByteArrayInputStream; +import java.io.InputStreamReader; +import java.io.StringReader; /** * Csv conversion. @@ -33,46 +46,117 @@ public class Native { public static Object parseStringToRecord(BString csv, BMap options, BTypedesc type) { - return null; + try { + return CsvParser.parse(new StringReader(csv.getValue()), + type, CsvConfig.createParserToRecordOptions(options)); + } catch (BError e) { + return e; + } catch (Exception e) { + return DiagnosticLog.error(DiagnosticErrorCode.INVALID_CAST, csv, type); + } } public static Object parseBytesToRecord(BArray csv, BMap options, BTypedesc type) { - return null; + try { + byte[] bytes = csv.getBytes(); + return CsvParser.parse(new InputStreamReader(new ByteArrayInputStream(bytes)), + type, CsvConfig.createParserToRecordOptions(options)); + } catch (BError e) { + return e; + } catch (Exception e) { + return DiagnosticLog.error(DiagnosticErrorCode.INVALID_CAST, csv, type); + } } public static Object parseStreamToRecord(Environment env, BStream csv, BMap options, BTypedesc type) { - return null; + try { + final BObject iteratorObj = csv.getIteratorObj(); + final Future future = env.markAsync(); + DataReaderTask task = new DataReaderTask(env, iteratorObj, future, type, + CsvConfig.createParserToRecordOptions(options)); + DataReaderThreadPool.EXECUTOR_SERVICE.submit(task); + return null; + } catch (BError e) { + return e; + } catch (Exception e) { + return DiagnosticLog.error(DiagnosticErrorCode.INVALID_CAST, csv, type); + } } public static Object parseStringToList(BString csv, BMap options, BTypedesc type) { - return null; + try { + return CsvParser.parse(new StringReader(csv.getValue()), + type, CsvConfig.createParseOptions(options)); + } catch (BError e) { + return e; + } catch (Exception e) { + return DiagnosticLog.error(DiagnosticErrorCode.INVALID_CAST, csv, type); + } } public static Object parseBytesToList(BArray csv, BMap options, BTypedesc type) { - return null; + try { + byte[] bytes = csv.getBytes(); + return CsvParser.parse(new InputStreamReader(new ByteArrayInputStream(bytes)), + type, CsvConfig.createParseOptions(options)); + } catch (BError e) { + return e; + } catch (Exception e) { + return DiagnosticLog.error(DiagnosticErrorCode.INVALID_CAST, csv, type); + } } public static Object parseStreamToList(Environment env, BStream csv, BMap options, BTypedesc type) { - return null; + try { + final BObject iteratorObj = csv.getIteratorObj(); + final Future future = env.markAsync(); + DataReaderTask task = new DataReaderTask(env, iteratorObj, future, type, + CsvConfig.createParseOptions(options)); + DataReaderThreadPool.EXECUTOR_SERVICE.submit(task); + return null; + } catch (BError e) { + return e; + } catch (Exception e) { + return DiagnosticLog.error(DiagnosticErrorCode.INVALID_CAST, csv, type); + } } public static Object parseRecordAsRecordType(BArray csv, BMap options, BTypedesc type) { - return null; + try { + return CsvTraversal.traverse(csv, CsvConfig.createRecordAsRecordOption(options), type); + } catch (Exception e) { + return DiagnosticLog.getCsvError(e.getMessage()); + } } public static Object parseRecordAsListType(BArray csv, BArray headers, BMap options, BTypedesc type) { - return null; + try { + CsvConfig toRecordOptions = CsvConfig.createToRecordOptions(options); + toRecordOptions.headersOrder = headers; + return CsvTraversal.traverse(csv, toRecordOptions, type); + } catch (Exception e) { + return DiagnosticLog.getCsvError(e.getMessage()); + } } public static Object parseListAsRecordType(BArray csv, Object customHeaders, BMap options, BTypedesc type) { - return null; + try { + options.put(Constants.ConfigConstants.CUSTOM_HEADERS, customHeaders); + return CsvTraversal.traverse(csv, CsvConfig.createListAsRecordTypeOptions(options), type); + } catch (Exception e) { + return DiagnosticLog.getCsvError(e.getMessage()); + } } public static Object parseListAsListType(BArray csv, BMap options, BTypedesc type) { - return null; + try { + return CsvTraversal.traverse(csv, CsvConfig.createListTypeOptions(options), type); + } catch (Exception e) { + return DiagnosticLog.getCsvError(e.getMessage()); + } } } diff --git a/native/src/main/java/io/ballerina/stdlib/data/csvdata/io/BallerinaByteBlockInputStream.java b/native/src/main/java/io/ballerina/stdlib/data/csvdata/io/BallerinaByteBlockInputStream.java new file mode 100644 index 0000000..b6705a2 --- /dev/null +++ b/native/src/main/java/io/ballerina/stdlib/data/csvdata/io/BallerinaByteBlockInputStream.java @@ -0,0 +1,166 @@ +/* + * Copyright (c) 2024, WSO2 LLC. (https://www.wso2.com). + * + * 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 + * + * 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 io.ballerina.stdlib.data.csvdata.io; + +import io.ballerina.runtime.api.Environment; +import io.ballerina.runtime.api.async.Callback; +import io.ballerina.runtime.api.async.StrandMetadata; +import io.ballerina.runtime.api.types.MethodType; +import io.ballerina.runtime.api.types.Type; +import io.ballerina.runtime.api.values.BArray; +import io.ballerina.runtime.api.values.BError; +import io.ballerina.runtime.api.values.BMap; +import io.ballerina.runtime.api.values.BObject; +import io.ballerina.runtime.api.values.BString; +import io.ballerina.stdlib.data.csvdata.utils.DiagnosticLog; + +import java.io.IOException; +import java.io.InputStream; +import java.util.Arrays; +import java.util.Map; +import java.util.concurrent.Semaphore; +import java.util.concurrent.atomic.AtomicBoolean; +import java.util.function.Consumer; + +/** + * Java Input Stream based on Ballerina byte block stream. stream + * + * @since 0.1.0 + */ +public class BallerinaByteBlockInputStream extends InputStream { + + private final BObject iterator; + private final Environment env; + private final String nextMethodName; + private final Type returnType; + private final String strandName; + private final StrandMetadata metadata; + private final Map properties; + private final AtomicBoolean done = new AtomicBoolean(false); + private final MethodType closeMethod; + private final Consumer futureResultConsumer; + + private byte[] currentChunk = new byte[0]; + private int nextChunkIndex = 0; + + public BallerinaByteBlockInputStream(Environment env, BObject iterator, MethodType nextMethod, + MethodType closeMethod, Consumer futureResultConsumer) { + this.env = env; + this.iterator = iterator; + this.nextMethodName = nextMethod.getName(); + this.returnType = nextMethod.getReturnType(); + this.closeMethod = closeMethod; + this.strandName = env.getStrandName().orElse(""); + this.metadata = env.getStrandMetadata(); + this.properties = Map.of(); + this.futureResultConsumer = futureResultConsumer; + } + + @Override + public int read() { + if (done.get()) { + return -1; + } + if (hasBytesInCurrentChunk()) { + return currentChunk[nextChunkIndex++]; + } + // Need to get a new block from the stream, before reading again. + nextChunkIndex = 0; + try { + if (readNextChunk()) { + return read(); + } + } catch (InterruptedException e) { + BError error = DiagnosticLog.getCsvError("Cannot read the stream, interrupted error"); + futureResultConsumer.accept(error); + return -1; + } + return -1; + } + + @Override + public void close() throws IOException { + super.close(); + Semaphore semaphore = new Semaphore(0); + if (closeMethod != null) { + env.getRuntime().invokeMethodAsyncSequentially(iterator, closeMethod.getName(), strandName, metadata, + new Callback() { + @Override + public void notifyFailure(BError bError) { + semaphore.release(); + } + + @Override + public void notifySuccess(Object result) { + semaphore.release(); + } + }, properties, returnType); + } + try { + semaphore.acquire(); + } catch (InterruptedException e) { + throw new IOException("Error while closing the stream", e); + } + } + + private boolean hasBytesInCurrentChunk() { + return currentChunk.length != 0 && nextChunkIndex < currentChunk.length; + } + + private boolean readNextChunk() throws InterruptedException { + Semaphore semaphore = new Semaphore(0); + Callback callback = new Callback() { + + @Override + public void notifyFailure(BError bError) { + // Panic with an error + done.set(true); + futureResultConsumer.accept(bError); + currentChunk = new byte[0]; + semaphore.release(); + } + + @Override + public void notifySuccess(Object result) { + if (result == null) { + done.set(true); + currentChunk = new byte[0]; + semaphore.release(); + return; + } + if (result instanceof BMap) { + BMap valueRecord = (BMap) result; + final BString value = Arrays.stream(valueRecord.getKeys()).findFirst().get(); + final BArray arrayValue = valueRecord.getArrayValue(value); + currentChunk = arrayValue.getByteArray(); + semaphore.release(); + } else { + // Case where Completes with an error + done.set(true); + semaphore.release(); + } + } + + }; + env.getRuntime().invokeMethodAsyncSequentially(iterator, nextMethodName, strandName, metadata, callback, + properties, returnType); + semaphore.acquire(); + return !done.get(); + } +} diff --git a/native/src/main/java/io/ballerina/stdlib/data/csvdata/io/DataReaderTask.java b/native/src/main/java/io/ballerina/stdlib/data/csvdata/io/DataReaderTask.java new file mode 100644 index 0000000..38cd61c --- /dev/null +++ b/native/src/main/java/io/ballerina/stdlib/data/csvdata/io/DataReaderTask.java @@ -0,0 +1,109 @@ +/* + * Copyright (c) 2024, WSO2 LLC. (https://www.wso2.com). + * + * 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 + * + * 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 io.ballerina.stdlib.data.csvdata.io; + +import io.ballerina.runtime.api.Environment; +import io.ballerina.runtime.api.Future; +import io.ballerina.runtime.api.types.MethodType; +import io.ballerina.runtime.api.types.ObjectType; +import io.ballerina.runtime.api.utils.TypeUtils; +import io.ballerina.runtime.api.values.BObject; +import io.ballerina.runtime.api.values.BTypedesc; +import io.ballerina.stdlib.data.csvdata.csv.CsvParser; +import io.ballerina.stdlib.data.csvdata.utils.CsvConfig; +import io.ballerina.stdlib.data.csvdata.utils.DiagnosticLog; + +import java.io.InputStreamReader; +import java.util.function.Consumer; + +/** + * This class will read data from a Ballerina Stream of byte blocks, in non-blocking manner. + * + * @since 0.1.0 + */ +public class DataReaderTask implements Runnable { + + private static final String METHOD_NAME_NEXT = "next"; + private static final String METHOD_NAME_CLOSE = "close"; + + private final Environment env; + private final BObject iteratorObj; + private final Future future; + private final BTypedesc typed; + private final CsvConfig config; + + public DataReaderTask(Environment env, BObject iteratorObj, Future future, BTypedesc typed, CsvConfig config) { + this.env = env; + this.iteratorObj = iteratorObj; + this.future = future; + this.typed = typed; + this.config = config; + } + + static MethodType resolveNextMethod(BObject iterator) { + MethodType method = getMethodType(iterator, METHOD_NAME_NEXT); + if (method != null) { + return method; + } + throw new IllegalStateException("next method not found in the iterator object"); + } + + static MethodType resolveCloseMethod(BObject iterator) { + return getMethodType(iterator, METHOD_NAME_CLOSE); + } + + private static MethodType getMethodType(BObject iterator, String methodNameClose) { + ObjectType objectType = (ObjectType) TypeUtils.getReferredType(iterator.getOriginalType()); + MethodType[] methods = objectType.getMethods(); + // Assumes compile-time validation of the iterator object + for (MethodType method : methods) { + if (method.getName().equals(methodNameClose)) { + return method; + } + } + return null; + } + + @Override + public void run() { + ResultConsumer resultConsumer = new ResultConsumer<>(future); + try (var byteBlockSteam = new BallerinaByteBlockInputStream(env, iteratorObj, resolveNextMethod(iteratorObj), + resolveCloseMethod(iteratorObj), resultConsumer)) { + Object result = CsvParser.parse(new InputStreamReader(byteBlockSteam), + typed, this.config); + future.complete(result); + } catch (Exception e) { + future.complete(DiagnosticLog.getCsvError("Error occurred while reading the stream: " + e.getMessage())); + } + } + + /** + * This class will hold module related utility functions. + * + * @param The type of the result + * @param future The future to complete + * @since 0.1.0 + */ + public record ResultConsumer(Future future) implements Consumer { + + @Override + public void accept(T t) { + future.complete(t); + } + } +} diff --git a/native/src/main/java/io/ballerina/stdlib/data/csvdata/io/DataReaderThreadPool.java b/native/src/main/java/io/ballerina/stdlib/data/csvdata/io/DataReaderThreadPool.java new file mode 100644 index 0000000..55e732f --- /dev/null +++ b/native/src/main/java/io/ballerina/stdlib/data/csvdata/io/DataReaderThreadPool.java @@ -0,0 +1,51 @@ +/* + * Copyright (c) 2024, WSO2 LLC. (https://www.wso2.com). + * + * 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 + * + * 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 io.ballerina.stdlib.data.csvdata.io; + +import java.util.concurrent.ExecutorService; +import java.util.concurrent.SynchronousQueue; +import java.util.concurrent.ThreadFactory; +import java.util.concurrent.ThreadPoolExecutor; +import java.util.concurrent.TimeUnit; + +/** + * Thread pool for data reader. + * + * @since 0.1.0 + */ +public class DataReaderThreadPool { + private static final int CORE_POOL_SIZE = 0; + private static final int MAX_POOL_SIZE = 50; + private static final long KEEP_ALIVE_TIME = 60L; + private static final String THREAD_NAME = "bal-data-csv-thread"; + public static final ExecutorService EXECUTOR_SERVICE = new ThreadPoolExecutor(CORE_POOL_SIZE, + MAX_POOL_SIZE, KEEP_ALIVE_TIME, TimeUnit.SECONDS, new SynchronousQueue<>(), new DataThreadFactory()); + + /** + * Thread factory for data reader. + */ + static class DataThreadFactory implements ThreadFactory { + + @Override + public Thread newThread(Runnable runnable) { + Thread ballerinaData = new Thread(runnable); + ballerinaData.setName(THREAD_NAME); + return ballerinaData; + } + } +} diff --git a/native/src/main/java/io/ballerina/stdlib/data/csvdata/utils/Constants.java b/native/src/main/java/io/ballerina/stdlib/data/csvdata/utils/Constants.java new file mode 100644 index 0000000..ef16c39 --- /dev/null +++ b/native/src/main/java/io/ballerina/stdlib/data/csvdata/utils/Constants.java @@ -0,0 +1,42 @@ +package io.ballerina.stdlib.data.csvdata.utils; + +import io.ballerina.runtime.api.utils.StringUtils; +import io.ballerina.runtime.api.values.BString; + +public class Constants { + public static class ConfigConstants { + public static final BString DELIMITER = StringUtils.fromString("delimiter"); + public static final BString TEXT_ENCLOSURE = StringUtils.fromString("textEnclosure"); + public static final BString HEADER = StringUtils.fromString("header"); + public static final BString ESCAPE_CHAR = StringUtils.fromString("escapeChar"); + public static final BString LINE_TERMINATOR = StringUtils.fromString("lineTerminator"); + public static final BString SKIP_LINES = StringUtils.fromString("skipLines"); + public static final BString NIL_VALUE = StringUtils.fromString("nilValue"); + public static final BString COMMENT_CHAR = StringUtils.fromString("comment"); + public static final BString LOCALE = StringUtils.fromString("locale"); + public static final BString ENCODING = StringUtils.fromString("encoding"); + public static final BString NIL_AS_OPTIONAL = StringUtils.fromString("nilAsOptionalField"); + public static final BString ABSENT_AS_NILABLE = StringUtils.fromString("absentAsNilableType"); + public static final BString ALLOW_DATA_PROJECTION = StringUtils.fromString("allowDataProjection"); + public static final BString CUSTOM_HEADERS = StringUtils.fromString("customHeaders"); + public static final BString STRING_CONVERSION = StringUtils.fromString("stringConversion"); + public static final BString ENABLE_CONSTRAINT_VALIDATION = StringUtils. + fromString("enableConstraintValidation"); + } + + public static class Values { + public static final String NULL = "null"; + public static final String BALLERINA_NULL = "()"; + } + + public static class LineTerminator { + public static final char LF = '\n'; + public static final char CR = '\r'; + public static final String CRLF = "\r\n"; + } + + public static final String SKIP_LINE_RANGE_SEP = "-"; + public static final String FIELD = "$field$."; + public static final String NAME = "Name"; + public static final BString VALUE = StringUtils.fromString("value"); +} diff --git a/native/src/main/java/io/ballerina/stdlib/data/csvdata/utils/CsvConfig.java b/native/src/main/java/io/ballerina/stdlib/data/csvdata/utils/CsvConfig.java new file mode 100644 index 0000000..93d19d6 --- /dev/null +++ b/native/src/main/java/io/ballerina/stdlib/data/csvdata/utils/CsvConfig.java @@ -0,0 +1,247 @@ +package io.ballerina.stdlib.data.csvdata.utils; + +import io.ballerina.runtime.api.utils.StringUtils; +import io.ballerina.runtime.api.values.BArray; +import io.ballerina.runtime.api.values.BMap; +import io.ballerina.runtime.api.values.BString; + +import static io.ballerina.stdlib.data.csvdata.utils.Constants.ConfigConstants.ABSENT_AS_NILABLE; +import static io.ballerina.stdlib.data.csvdata.utils.Constants.ConfigConstants.ALLOW_DATA_PROJECTION; +import static io.ballerina.stdlib.data.csvdata.utils.Constants.ConfigConstants.COMMENT_CHAR; +import static io.ballerina.stdlib.data.csvdata.utils.Constants.ConfigConstants.CUSTOM_HEADERS; +import static io.ballerina.stdlib.data.csvdata.utils.Constants.ConfigConstants.DELIMITER; +import static io.ballerina.stdlib.data.csvdata.utils.Constants.ConfigConstants.ENABLE_CONSTRAINT_VALIDATION; +import static io.ballerina.stdlib.data.csvdata.utils.Constants.ConfigConstants.ENCODING; +import static io.ballerina.stdlib.data.csvdata.utils.Constants.ConfigConstants.ESCAPE_CHAR; +import static io.ballerina.stdlib.data.csvdata.utils.Constants.ConfigConstants.HEADER; +import static io.ballerina.stdlib.data.csvdata.utils.Constants.ConfigConstants.LINE_TERMINATOR; +import static io.ballerina.stdlib.data.csvdata.utils.Constants.ConfigConstants.LOCALE; +import static io.ballerina.stdlib.data.csvdata.utils.Constants.ConfigConstants.NIL_AS_OPTIONAL; +import static io.ballerina.stdlib.data.csvdata.utils.Constants.ConfigConstants.NIL_VALUE; +import static io.ballerina.stdlib.data.csvdata.utils.Constants.ConfigConstants.SKIP_LINES; +import static io.ballerina.stdlib.data.csvdata.utils.Constants.ConfigConstants.STRING_CONVERSION; +import static io.ballerina.stdlib.data.csvdata.utils.Constants.ConfigConstants.TEXT_ENCLOSURE; + +public class CsvConfig { + public char delimiter = ','; + public char textEnclosure = '\\'; + public Object header = (long) 0; + public char escapeChar = '\\'; + public Object lineTerminator = '\n'; + public Object skipLines = null; + public Object nilValue = null; + public char comment = '#'; + public String locale = "EN/US"; + public String encoding = "UTF-8"; + public boolean nilAsOptionalField = false; + public boolean absentAsNilableType = false; + public boolean allowDataProjection = true; + public Object customHeader = null; + public BArray headersOrder = null; + public boolean stringConversion = false; + public boolean enableConstraintValidation = false; + + private CsvConfig(CsvConfig config) { + this.allowDataProjection = false; + this.header = config.header; + this.delimiter = config.delimiter; + this.textEnclosure = config.textEnclosure; + this.escapeChar = config.escapeChar; + this.lineTerminator = config.lineTerminator; + this.nilValue = config.nilValue; + this.comment = config.comment; + this.locale = config.locale; + this.encoding = config.encoding; + } + + private CsvConfig(Object skipLines, boolean nilAsOptionalField, + boolean absentAsNilableType, boolean allowDataProjection) { + this.skipLines = skipLines; + this.nilAsOptionalField = nilAsOptionalField; + this.absentAsNilableType = absentAsNilableType; + this.allowDataProjection = allowDataProjection; + } + + private CsvConfig(boolean enableConstraintValidation, Object skipLines, boolean nilAsOptionalField, + boolean absentAsNilableType, boolean allowDataProjection) { + this.skipLines = skipLines; + this.nilAsOptionalField = nilAsOptionalField; + this.absentAsNilableType = absentAsNilableType; + this.allowDataProjection = allowDataProjection; + this.enableConstraintValidation = enableConstraintValidation; + } + + private CsvConfig(Object skipLines, boolean nilAsOptionalField, + boolean absentAsNilableType, boolean allowDataProjection, Object customHeader) { + this.skipLines = skipLines; + this.nilAsOptionalField = nilAsOptionalField; + this.absentAsNilableType = absentAsNilableType; + this.allowDataProjection = allowDataProjection; + this.customHeader = customHeader; + } + + private CsvConfig(Object skipLines, boolean nilAsOptionalField, + boolean absentAsNilableType, boolean allowDataProjection, boolean stringConversion) { + this.skipLines = skipLines; + this.nilAsOptionalField = nilAsOptionalField; + this.absentAsNilableType = absentAsNilableType; + this.allowDataProjection = allowDataProjection; + this.stringConversion = stringConversion; + } + + private CsvConfig(Object skipLines, boolean nilAsOptionalField, boolean absentAsNilableType, + boolean allowDataProjection, boolean stringConversion, Object customHeader, + boolean enableConstraintValidation) { + this.skipLines = skipLines; + this.nilAsOptionalField = nilAsOptionalField; + this.absentAsNilableType = absentAsNilableType; + this.allowDataProjection = allowDataProjection; + this.stringConversion = stringConversion; + this.customHeader = customHeader; + this.enableConstraintValidation = enableConstraintValidation; + } + + public static CsvConfig createListTypeOptions(BMap options) { + updateDataProjectOptions(options); + return new CsvConfig( + options.get(SKIP_LINES), + options.getBooleanValue(NIL_AS_OPTIONAL).booleanValue(), + options.getBooleanValue(ABSENT_AS_NILABLE).booleanValue(), + options.getBooleanValue(ALLOW_DATA_PROJECTION).booleanValue(), + options.getBooleanValue(STRING_CONVERSION).booleanValue() + ); + } + + public static CsvConfig createListAsRecordTypeOptions(BMap options) { + updateDataProjectOptions(options); + return new CsvConfig( + options.get(SKIP_LINES), + options.getBooleanValue(NIL_AS_OPTIONAL).booleanValue(), + options.getBooleanValue(ABSENT_AS_NILABLE).booleanValue(), + options.getBooleanValue(ALLOW_DATA_PROJECTION).booleanValue(), + options.getBooleanValue(STRING_CONVERSION).booleanValue(), + options.get(CUSTOM_HEADERS), + options.getBooleanValue(ENABLE_CONSTRAINT_VALIDATION).booleanValue() + ); + } + + private CsvConfig(char delimiter, char textEnclosure, Object header, + char escapeChar, Object lineTerminator, Object skipLines, + Object nilValue, char comment, String locale, String encoding, + boolean nilAsOptionalField, boolean absentAsNilableType, boolean allowDataProjection) { + this.delimiter = delimiter; + this.textEnclosure = textEnclosure; + this.header = header; + this.escapeChar = escapeChar; + this.lineTerminator = lineTerminator; + this.nilValue = nilValue == null ? null : nilValue; + this.comment = comment; + this.locale = locale; + this.encoding = encoding; + this.nilAsOptionalField = nilAsOptionalField; + this.absentAsNilableType = absentAsNilableType; + this.allowDataProjection = allowDataProjection; + this.skipLines = skipLines; + } + + private CsvConfig(char delimiter, char textEnclosure, Object header, char escapeChar, Object lineTerminator, + Object skipLines, Object nilValue, char comment, String locale, String encoding, + boolean nilAsOptionalField, boolean absentAsNilableType, + boolean allowDataProjection, Object customHeaders, boolean enableConstraintValidation) { + this.delimiter = delimiter; + this.textEnclosure = textEnclosure; + this.header = header; + this.escapeChar = escapeChar; + this.lineTerminator = lineTerminator; + this.nilValue = nilValue == null ? null : nilValue; + this.comment = comment; + this.locale = locale; + this.encoding = encoding; + this.nilAsOptionalField = nilAsOptionalField; + this.absentAsNilableType = absentAsNilableType; + this.allowDataProjection = allowDataProjection; + this.skipLines = skipLines; + this.customHeader = customHeaders; + this.enableConstraintValidation = enableConstraintValidation; + } + + public static CsvConfig createRecordAsRecordOption(BMap options) { + updateDataProjectOptions(options); + return new CsvConfig( + options.getBooleanValue(ENABLE_CONSTRAINT_VALIDATION), + options.get(SKIP_LINES), + options.getBooleanValue(NIL_AS_OPTIONAL), + options.getBooleanValue(ABSENT_AS_NILABLE), + options.getBooleanValue(ALLOW_DATA_PROJECTION) + ); + } + + public static CsvConfig createParseOptions(BMap options) { + updateDataProjectOptions(options); + return new CsvConfig( + StringUtils.getStringValue(options.getStringValue(DELIMITER)).charAt(0), + StringUtils.getStringValue(options.getStringValue(TEXT_ENCLOSURE)).charAt(0), + options.get(HEADER), + StringUtils.getStringValue(options.getStringValue(ESCAPE_CHAR)).charAt(0), + options.get(LINE_TERMINATOR), + options.get(SKIP_LINES), + options.get(NIL_VALUE), + StringUtils.getStringValue(options.getStringValue(COMMENT_CHAR)).charAt(0), + StringUtils.getStringValue(options.getStringValue(LOCALE)), + StringUtils.getStringValue(options.getStringValue(ENCODING)), + options.getBooleanValue(NIL_AS_OPTIONAL), + options.getBooleanValue(ABSENT_AS_NILABLE), + options.getBooleanValue(ALLOW_DATA_PROJECTION) + ); + } + + public static CsvConfig createParserToRecordOptions(BMap options) { + updateDataProjectOptions(options); + return new CsvConfig( + StringUtils.getStringValue(options.getStringValue(DELIMITER)).charAt(0), + StringUtils.getStringValue(options.getStringValue(TEXT_ENCLOSURE)).charAt(0), + options.get(HEADER), + StringUtils.getStringValue(options.getStringValue(ESCAPE_CHAR)).charAt(0), + options.get(LINE_TERMINATOR), + options.get(SKIP_LINES), + options.getStringValue(NIL_VALUE), + StringUtils.getStringValue(options.getStringValue(COMMENT_CHAR)).charAt(0), + StringUtils.getStringValue(options.getStringValue(LOCALE)), + StringUtils.getStringValue(options.getStringValue(ENCODING)), + options.getBooleanValue(NIL_AS_OPTIONAL), + options.getBooleanValue(ABSENT_AS_NILABLE), + options.getBooleanValue(ALLOW_DATA_PROJECTION), + options.get(CUSTOM_HEADERS), + options.getBooleanValue(ENABLE_CONSTRAINT_VALIDATION) + ); + } + + public static CsvConfig createToRecordOptions(BMap options) { + updateDataProjectOptions(options); + return new CsvConfig( + options.get(SKIP_LINES), + options.getBooleanValue(NIL_AS_OPTIONAL), + options.getBooleanValue(ABSENT_AS_NILABLE), + options.getBooleanValue(ALLOW_DATA_PROJECTION), + options.get(CUSTOM_HEADERS) + ); + } + + + public static CsvConfig createConfigOptionsForUnion(CsvConfig config) { + return new CsvConfig(config); + } + + private static void updateDataProjectOptions(BMap options) { + Object allowProjections = options.get(ALLOW_DATA_PROJECTION); + if (allowProjections instanceof Boolean) { + options.put(NIL_AS_OPTIONAL, false); + options.put(ABSENT_AS_NILABLE, false); + return; + } + BMap projections = (BMap) allowProjections; + options.put(ALLOW_DATA_PROJECTION, true); + options.put(NIL_AS_OPTIONAL, projections.getBooleanValue(NIL_AS_OPTIONAL)); + options.put(ABSENT_AS_NILABLE, projections.getBooleanValue(ABSENT_AS_NILABLE)); + } +} diff --git a/native/src/main/java/io/ballerina/stdlib/data/csvdata/utils/CsvUtils.java b/native/src/main/java/io/ballerina/stdlib/data/csvdata/utils/CsvUtils.java new file mode 100644 index 0000000..3f67f06 --- /dev/null +++ b/native/src/main/java/io/ballerina/stdlib/data/csvdata/utils/CsvUtils.java @@ -0,0 +1,337 @@ +package io.ballerina.stdlib.data.csvdata.utils; + +import io.ballerina.runtime.api.TypeTags; +import io.ballerina.runtime.api.flags.SymbolFlags; +import io.ballerina.runtime.api.types.ArrayType; +import io.ballerina.runtime.api.types.Field; +import io.ballerina.runtime.api.types.IntersectionType; +import io.ballerina.runtime.api.types.RecordType; +import io.ballerina.runtime.api.types.TupleType; +import io.ballerina.runtime.api.types.Type; +import io.ballerina.runtime.api.utils.StringUtils; +import io.ballerina.runtime.api.utils.ValueUtils; +import io.ballerina.runtime.api.values.BArray; +import io.ballerina.runtime.api.values.BDecimal; +import io.ballerina.runtime.api.values.BMap; +import io.ballerina.runtime.api.values.BString; + +import java.util.HashMap; +import java.util.HashSet; +import java.util.Map; +import java.util.Optional; + +import static io.ballerina.stdlib.data.csvdata.utils.Constants.SKIP_LINE_RANGE_SEP; + +public class CsvUtils { + public static boolean isCarriageTokenPresent = false; + + public static void setCarriageTokenPresent(boolean isCarriageTokenPresent) { + CsvUtils.isCarriageTokenPresent = isCarriageTokenPresent; + } + + public static void validateExpectedArraySize(int size, int currentSize) { + if (size != -1 && size > currentSize) { + throw DiagnosticLog.error(DiagnosticErrorCode.INVALID_EXPECTED_ARRAY_SIZE, currentSize); + } + } + + public static boolean isBasicType(Type type) { + switch (type.getTag()) { + case TypeTags.INT_TAG: + case TypeTags.STRING_TAG: + case TypeTags.BOOLEAN_TAG: + case TypeTags.DECIMAL_TAG: + case TypeTags.FLOAT_TAG: + case TypeTags.NULL_TAG: + case TypeTags.JSON_TAG: + case TypeTags.ANYDATA_TAG: + case TypeTags.UNION_TAG: + case TypeTags.INTERSECTION_TAG: + case TypeTags.CHAR_STRING_TAG: + case TypeTags.BYTE_TAG: + case TypeTags.SIGNED8_INT_TAG: + case TypeTags.SIGNED16_INT_TAG: + case TypeTags.SIGNED32_INT_TAG: + case TypeTags.UNSIGNED8_INT_TAG: + case TypeTags.UNSIGNED16_INT_TAG: + case TypeTags.UNSIGNED32_INT_TAG: + return true; + default: + return false; + } + } + + public static String[] createHeaders(String[] headers, CsvConfig config) { + Object customHeaders = config.customHeader; + + if (customHeaders == null) { + for (int i = 0; i < headers.length; i++) { + headers[i] = String.valueOf(i + 1); + } + } + + if (customHeaders instanceof BArray) { + BArray array = (BArray) customHeaders; + if (array.size() != headers.length) { + throw DiagnosticLog.error(DiagnosticErrorCode.INVALID_CUSTOM_HEADER_LENGTH); + } + for (int i = 0; i < headers.length; i++) { + headers[i] = array.get(i).toString(); + } + } + + return headers; + } + + public static Optional getMutableType(IntersectionType intersectionType) { + for (Type constituentType : intersectionType.getConstituentTypes()) { + if (constituentType.getTag() == TypeTags.READONLY_TAG) { + continue; + } + return Optional.of(constituentType); + } + return Optional.empty(); + } + + public static Object convertToBasicType(Object csv, Type targetType, CsvConfig config) { + if (csv == null) { + csv = config.nilValue; + } + return ValueUtils.convert(csv, targetType); + } + + public static void checkRequiredFieldsAndLogError(Map filedHierarchy, boolean absentAsNilableType) { + filedHierarchy.values().forEach(field -> { + if (absentAsNilableType && field.getFieldType().isNilable()) { + return; + } + if (SymbolFlags.isFlagOn(field.getFlags(), SymbolFlags.REQUIRED)) { + throw DiagnosticLog.error(DiagnosticErrorCode.INVALID_FIELD_IN_CSV, field.getFieldName()); + } + }); + } + + public static boolean isHeaderFieldsEmpty(Map currentField) { + for (Field field: currentField.values()) { + if (SymbolFlags.isFlagOn(field.getFlags(), SymbolFlags.REQUIRED)) { + return false; + } + } + return true; + } + + public static boolean checkTypeCompatibility(Type constraintType, Object csv, boolean stringConversion) { + int tag = constraintType.getTag(); + if ((csv instanceof BString && (stringConversion || tag == TypeTags.STRING_TAG + || tag == TypeTags.CHAR_STRING_TAG || isJsonOrAnyDataOrAny(tag))) + || (csv instanceof Long && (tag == TypeTags.INT_TAG + || tag == TypeTags.FLOAT_TAG || tag == TypeTags.DECIMAL_TAG || tag == TypeTags.BYTE_TAG + || tag == TypeTags.SIGNED8_INT_TAG || tag == TypeTags.SIGNED16_INT_TAG + || tag == TypeTags.SIGNED32_INT_TAG || tag == TypeTags.UNSIGNED8_INT_TAG + || tag == TypeTags.UNSIGNED16_INT_TAG || tag == TypeTags.UNSIGNED32_INT_TAG + || isJsonOrAnyDataOrAny(tag))) + || (csv instanceof BDecimal && ((tag == TypeTags.DECIMAL_TAG + || tag == TypeTags.FLOAT_TAG || tag == TypeTags.INT_TAG) || isJsonOrAnyDataOrAny(tag))) + || (csv instanceof Double && ((tag == TypeTags.FLOAT_TAG + || tag == TypeTags.DECIMAL_TAG || tag == TypeTags.INT_TAG) || isJsonOrAnyDataOrAny(tag))) + || (Boolean.class.isInstance(csv) && (tag == TypeTags.BOOLEAN_TAG || isJsonOrAnyDataOrAny(tag))) + || (csv == null && (tag == TypeTags.NULL_TAG || isJsonOrAnyDataOrAny(tag)))) { + return true; + } else { + return false; + } + } + + private static boolean isJsonOrAnyDataOrAny(int tag) { + return tag == TypeTags.JSON_TAG || tag == TypeTags.ANYDATA_TAG || tag == TypeTags.ANY_TAG; + } + + public static int getTheActualExpectedType(Type type) { + if (type instanceof TupleType) { + TupleType tupleType = (TupleType) type; + if (tupleType.getRestType() != null) { + return -1; + } + return tupleType.getTupleTypes().size(); + } else { + return ((ArrayType) type).getSize(); + } + } + + public static HashMap + processNameAnnotationsAndBuildCustomFieldMap(RecordType recordType, + Map fieldHierarchy) { + BMap annotations = recordType.getAnnotations(); + HashMap updatedRecordFieldNames = new HashMap<>(); + HashSet updatedFields = new HashSet<>(); + HashSet updatedValues = new HashSet<>(); + + for (BString annotationsKey : annotations.getKeys()) { + String key = annotationsKey.getValue(); + if (key.contains(Constants.FIELD)) { + BMap annotMap = ((BMap) annotations.get(annotationsKey)); + for (BString mapKey : annotMap.getKeys()) { + if (mapKey.getValue().endsWith(Constants.NAME)) { + String name = ((Map) annotMap.get(mapKey)).get(Constants.VALUE).toString(); + String originalName = key.substring(Constants.FIELD.length()); + if (updatedValues.contains(name)) { + throw DiagnosticLog.error(DiagnosticErrorCode.DUPLICATE_FIELD, name); + } + if (updatedFields.contains(originalName)) { + throw DiagnosticLog.error(DiagnosticErrorCode.DUPLICATE_FIELD, originalName); + } + updatedFields.add(originalName); + updatedValues.add(name); + updatedRecordFieldNames.put(name, originalName); + break; + } + } + } + } + for (String field : fieldHierarchy.keySet()) { + if (updatedFields.contains(field)) { + continue; + } + if (updatedValues.contains(field) || updatedRecordFieldNames.containsKey(field)) { + throw DiagnosticLog.error(DiagnosticErrorCode.DUPLICATE_FIELD, field); + } + updatedRecordFieldNames.put(field, field); + } + + return updatedRecordFieldNames; + } + + public static String getUpdatedHeaders(Map updatedRecords, String key, boolean isKeyContains) { + String fieldName = updatedRecords.get(key); + if (fieldName != null) { + return fieldName; + } + if (isKeyContains) { + throw DiagnosticLog.error(DiagnosticErrorCode.DUPLICATE_FIELD, key); + } + return key; + } + + public static long[] getSkipLinesFromStringConfigValue(String configValue) { + String[] parts = configValue.split(SKIP_LINE_RANGE_SEP); + if (parts.length != 2) { + throw DiagnosticLog.error(DiagnosticErrorCode.INVALID_RANGE_FOR_SKIPLINES); + } + try { + int start = Integer.parseInt(parts[0]); + int end = Integer.parseInt(parts[1]); + int size = end - start + 1; + if (size <= 0) { + throw DiagnosticLog.error(DiagnosticErrorCode.INVALID_RANGE_FOR_SKIPLINES); + } + long[] result = new long[size]; + for (int i = 0; i < size; i++) { + result[i] = start + i; + } + return result; + } catch (NumberFormatException e) { + throw DiagnosticLog.error(DiagnosticErrorCode.INVALID_VALUE_FOR_SKIPLINES); + } + } + + public static long[] getSkipDataRows(Object skipLines) { + long[] skipDataRows; + if (skipLines == null) { + return new long[]{}; + } + if (skipLines instanceof BArray) { + BArray skipLinesArray = (BArray) skipLines; + if (skipLinesArray.getLength() == 0) { + return new long[]{}; + } + skipDataRows = (skipLinesArray).getIntArray(); + return skipDataRows; + } + + skipDataRows = getSkipLinesFromStringConfigValue(StringUtils.getStringValue(skipLines)); + return skipDataRows; + } + + public static boolean isNullValue(Object nullValue, Object value) { + if (value == null) { + return true; + } + if (value instanceof BString) { + value = StringUtils.getStringValue(value); + } + if (value instanceof String v) { + if ((nullValue == null) && (Constants.Values.NULL.equalsIgnoreCase(v) + || Constants.Values.BALLERINA_NULL.equalsIgnoreCase(v))) { + return true; + } + if (nullValue != null && value.equals(StringUtils.getStringValue(nullValue))) { + return true; + } + return false; + } + return false; + } + + public static boolean isCharContainsInLineTerminatorUserConfig(char c, Object lineTerminatorObj) { + if (lineTerminatorObj instanceof BArray) { + Object[] lineTerminators = ((BArray) lineTerminatorObj).getValues(); + for (Object lineTerminator: lineTerminators) { + if (lineTerminator != null && c == Constants.LineTerminator.LF) { + String lineTerminatorString = lineTerminator.toString(); + if (isCarriageTokenPresent) { + if (lineTerminatorString.equals(Constants.LineTerminator.CRLF)) { + return true; + } + continue; + } + return true; + } + } + return false; + } + + String lineTerminator = StringUtils.getStringValue(StringUtils.fromString(lineTerminatorObj.toString())); + if (c == Constants.LineTerminator.LF) { + if (lineTerminator != null) { + if (lineTerminator.equals(Constants.LineTerminator.CRLF)) { + if (isCarriageTokenPresent) { + return true; + } + return false; + } + return true; + } + } + return false; + } + + public static class SortConfigurations { + protected Object columnName; + protected Object sortOrder; + + public SortConfigurations(Object columnName, Object sortOrder) { + this.columnName = columnName; + this.sortOrder = sortOrder; + } + } + + public static class UnMappedValue { + private static UnMappedValue value = null; + public static UnMappedValue createUnMappedValue() { + if (value == null) { + value = new UnMappedValue(); + } + return value; + } + } + + public static class SkipMappedValue { + private static SkipMappedValue value = null; + public static SkipMappedValue createSkippedValue() { + if (value == null) { + value = new SkipMappedValue(); + } + return value; + } + } +} diff --git a/native/src/main/java/io/ballerina/stdlib/data/csvdata/utils/DataUtils.java b/native/src/main/java/io/ballerina/stdlib/data/csvdata/utils/DataUtils.java new file mode 100644 index 0000000..06c1488 --- /dev/null +++ b/native/src/main/java/io/ballerina/stdlib/data/csvdata/utils/DataUtils.java @@ -0,0 +1,28 @@ +package io.ballerina.stdlib.data.csvdata.utils; + +import io.ballerina.runtime.api.values.BError; +import io.ballerina.runtime.api.values.BTypedesc; +import io.ballerina.stdlib.constraint.Constraints; + +public class DataUtils { + public static Object validateConstraints(Object convertedValue, BTypedesc typed, boolean requireValidation) { + if (!requireValidation) { + return convertedValue; + } + + Object result = Constraints.validate(convertedValue, typed); + if (result instanceof BError bError) { + return DiagnosticLog.getCsvError(getPrintableErrorMsg(bError)); + } + return convertedValue; + } + + private static String getPrintableErrorMsg(BError err) { + String errorMsg = err.getMessage() != null ? err.getMessage() : ""; + Object details = err.getDetails(); + if (details != null && !details.toString().equals("{}")) { + errorMsg += !errorMsg.isBlank() ? ", " : "" + details; + } + return errorMsg; + } +} diff --git a/native/src/main/java/io/ballerina/stdlib/data/csvdata/utils/DiagnosticErrorCode.java b/native/src/main/java/io/ballerina/stdlib/data/csvdata/utils/DiagnosticErrorCode.java new file mode 100644 index 0000000..20e7ac1 --- /dev/null +++ b/native/src/main/java/io/ballerina/stdlib/data/csvdata/utils/DiagnosticErrorCode.java @@ -0,0 +1,66 @@ +/* + * Copyright (c) 2024, WSO2 LLC. (https://www.wso2.com). + * + * 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 + * + * 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 io.ballerina.stdlib.data.csvdata.utils; + +/** + * Represents a diagnostic error code. + * + * @since 0.1.0 + */ +public enum DiagnosticErrorCode { + + INVALID_TYPE("BDE_0001", "invalid.type"), + UNION_TYPES_NOT_ALLOWED("BDE_0002", "union.types.not.allowed.as.expected.type"), + INVALID_ARRAY_MEMBER("BDE_0003", "invalid.array.member.in.expected.type"), + INVALID_FIELD_IN_CSV("BDE_0004", "cannot.found.field.in.csv"), + INVALID_CAST("BDE_0005", "csv.value.cannot.cast.into.expected.type"), + INVALID_EXPECTED_TYPE("BDE_0006", "invalid.expected.type"), + INVALID_TOKEN("BDE_0007", "invalid.token.while.reading.the.csv.data"), + INVALID_CSV_DATA_FORMAT("BDE_0008", "invalid.csv.data.format"), + INVALID_EXPECTED_ARRAY_SIZE("BDE_0009", "invalid.expected.array.size"), + INVALID_EXPECTED_TUPLE_SIZE("BDE_0010", "invalid.expected.tuple.size"), + INVALID_SKIP_COLUMN_QUERY("BDE_0011", "invalid.skip.column.query"), + INVALID_TYPE_FOR_FIELD("BDE_0012", "invalid.type.for.field"), + INVALID_TYPE_FOR_ARRAY("BDE_0013", "invalid.type.for.array"), + INVALID_CONVERSION_FOR_ARRAY_TO_MAP("BDE_0014", "invalid.conversion.for.array.to.map"), + INVALID_CONFIGURATIONS("BDE_0015", "invalid.configurations"), + EXPECTED_TYPE_CAN_ONLY_CONTAIN_BASIC_TYPES("BDE_0016", "expected.type.can.only.contains.basic.types"), + INVALID_FORMAT_FOR_SKIPLINES("BDE_0017", "invalid.format.for.skiplines"), + INVALID_RANGE_FOR_SKIPLINES("BDE_0018", "invalid.range.for.skiplines"), + INVALID_VALUE_FOR_SKIPLINES("BDE_0019", "invalid.value.for.skiplines"), + INVALID_CUSTOM_HEADER("BDE_0020", "invalid.custom.header"), + INVALID_CUSTOM_HEADER_LENGTH("BDE_0021", "invalid.custom.header.length"), + INVALID_HEADER_NAMES_LENGTH("BDE_0022", "invalid.header.names.length"), + HEADER_CANNOT_BE_EMPTY("BDE_0023", "header.cannot.be.empty"), + NO_FIELD_FOR_HEADER("BDE_0024", "no.field.for.header"), + DUPLICATE_FIELD("BDE_0025", "duplicate.field"), + SOURCE_CANNOT_CONVERT_INTO_EXP_TYPE("BDE_0026", "cannot.convert.into.exptype"); + + String diagnosticId; + String messageKey; + + DiagnosticErrorCode(String diagnosticId, String messageKey) { + this.diagnosticId = diagnosticId; + this.messageKey = messageKey; + } + + public String messageKey() { + return messageKey; + } +} diff --git a/native/src/main/java/io/ballerina/stdlib/data/csvdata/utils/DiagnosticLog.java b/native/src/main/java/io/ballerina/stdlib/data/csvdata/utils/DiagnosticLog.java new file mode 100644 index 0000000..1836d4a --- /dev/null +++ b/native/src/main/java/io/ballerina/stdlib/data/csvdata/utils/DiagnosticLog.java @@ -0,0 +1,58 @@ +/* + * Copyright (c) 2024, WSO2 LLC. (https://www.wso2.com). + * + * 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 + * + * 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 io.ballerina.stdlib.data.csvdata.utils; + +import io.ballerina.runtime.api.creators.ErrorCreator; +import io.ballerina.runtime.api.utils.StringUtils; +import io.ballerina.runtime.api.values.BError; + +import java.text.MessageFormat; +import java.util.Locale; +import java.util.ResourceBundle; + +/** + * Diagnostic log for data module. + * + * @since 0.1.0 + */ +public class DiagnosticLog { + private static final String ERROR_PREFIX = "error"; + private static final String CSV_CONVERSION_ERROR = "Error"; + private static final String UNSUPPORTED_OPERATION_ERROR = "Error"; + private static final ResourceBundle MESSAGES = ResourceBundle.getBundle("error", Locale.getDefault()); + + public static BError error(DiagnosticErrorCode code, Object... args) { + String msg = formatMessage(code, args); + return getCsvError(msg); + } + + private static String formatMessage(DiagnosticErrorCode code, Object[] args) { + String msgKey = MESSAGES.getString(ERROR_PREFIX + "." + code.messageKey()); + return MessageFormat.format(msgKey, args); + } + + public static BError getCsvError(String message, String errorType) { + return ErrorCreator.createError(io.ballerina.stdlib.data.csvdata.utils.ModuleUtils.getModule(), + errorType, StringUtils.fromString(message), null, null); + } + + public static BError getCsvError(String message) { + return getCsvError(message, CSV_CONVERSION_ERROR); + } +} diff --git a/native/src/main/java/module-info.java b/native/src/main/java/module-info.java index 1f625c2..dfa31e5 100644 --- a/native/src/main/java/module-info.java +++ b/native/src/main/java/module-info.java @@ -18,4 +18,10 @@ module io.ballerina.stdlib.data { requires io.ballerina.runtime; + requires io.ballerina.lang.value; + requires junit; + requires org.apache.commons.lang3; + requires io.ballerina.stdlib.constraint; + exports io.ballerina.stdlib.data.csvdata.csv; + exports io.ballerina.stdlib.data.csvdata.utils; } diff --git a/native/src/main/resources/META-INF/native-image/io.ballerina.stdlib/data/csvdata-native/resource-config.json b/native/src/main/resources/META-INF/native-image/io.ballerina.stdlib/data/csvdata-native/resource-config.json new file mode 100644 index 0000000..befe09e --- /dev/null +++ b/native/src/main/resources/META-INF/native-image/io.ballerina.stdlib/data/csvdata-native/resource-config.json @@ -0,0 +1,6 @@ +{ + "bundles":[{ + "name":"error", + "locales":[""] + }] +} diff --git a/native/src/main/resources/error.properties b/native/src/main/resources/error.properties index 84e78d6..5424a8e 100644 --- a/native/src/main/resources/error.properties +++ b/native/src/main/resources/error.properties @@ -19,3 +19,82 @@ # ------------------------- # Data module error messages # ------------------------- + +error.invalid.type=\ + invalid expected type ''{0}'', expected a subtype of (map|anydata[])[] + +error.union.types.not.allowed.as.expected.type=\ + union types are not allowed in the expected type, found ''{0}'' + +error.invalid.array.member.in.expected.type=\ + invalid type ''{0}'' in the expected array type + +error.cannot.found.field.in.csv=\ + no matching header value is found for the required field ''{0}'' + +error.csv.value.cannot.cast.into.expected.type=\ + value ''{0}'' cannot be cast into ''{1}'' + +error.invalid.expected.type=\ + expected a array type, found ''{0}'' + +error.invalid.token.while.reading.the.csv.data=\ + error while reading the csv data ''{0}'' in line: ''{1}'', column: ''{2}'' + +error.invalid.csv.data.format=\ + invalid csv data format + +error.invalid.expected.array.size=\ + invalid array size for expected array type, cannot be greater than ''{0}'' + +error.invalid.expected.tuple.size=\ + invalid array size for expected tuple type, cannot be greater than ''{0}'' + +error.invalid.skip.column.query=\ + invalid query found for skip column field, ''{0}'' + +error.invalid.type.for.field=\ + no mapping type found for value ''{0}'' in key ''{1}'' + +error.invalid.type.for.array=\ + value ''{0}'' in index ''{1}'' is not compatible with array type ''{2}'' + +error.expected.type.can.only.contains.basic.types=\ + expected type cannot contains types other than basic types, ''{0}'' not allowed + +error.invalid.conversion.for.array.to.map=\ + value ''{0}'' cannot be cast into ''{1}'', because fields in ''{1}'' or the provided \ + expected headers are not matching with the ''{0}'' + +error.invalid.configurations=\ + invalid configurations: ''{0}'' + +error.invalid.format.for.skiplines=\ + Invalid format for the skipLines field. Expected format: 'start-end' + +error.invalid.range.for.skiplines=\ + Invalid range for the skipLines field. Start value must be less than or equal to end value. + +error.invalid.value.for.skiplines=\ + Invalid input for the skipLines field. Both start and end values must be integers. + +error.invalid.custom.header=\ + Invalid header value: ''{0}'' + +error.invalid.custom.header.length=\ + Invalid length for the custom headers + +error.invalid.header.names.length=\ + Invalid length for the header names + +error.header.cannot.be.empty=\ + The provided header row is empty + +error.no.field.for.header=\ + No mapping field in the expected type for header ''{0}'' + +error.duplicate.field=\ + Duplicate field found in record fields: ''{0}'' + +error.cannot.convert.into.exptype=\ + The source value cannot convert in to the ''{0}'' diff --git a/settings.gradle b/settings.gradle index 72b6bfd..3a376ae 100644 --- a/settings.gradle +++ b/settings.gradle @@ -46,12 +46,14 @@ include(':data.csv-native') include(':data.csv-ballerina') include(':data.csv-compiler-plugin') include(':data.csv-compiler-plugin-tests') +include(':data.csv-ballerina-tests') project(':checkstyle').projectDir = file("build-config${File.separator}checkstyle") project(':data.csv-native').projectDir = file('native') project(':data.csv-ballerina').projectDir = file('ballerina') project(':data.csv-compiler-plugin').projectDir = file('compiler-plugin') project(':data.csv-compiler-plugin-tests').projectDir = file('compiler-plugin-test') +project(':data.csv-ballerina-tests').projectDir = file('ballerina-tests') gradleEnterprise { buildScan { @@ -59,3 +61,5 @@ gradleEnterprise { termsOfServiceAgree = 'yes' } } +include 'ballerina-tests' +